zig icon indicating copy to clipboard operation
zig copied to clipboard

[MachO] error: unsupported linker arg: -no_pie

Open motiejus opened this issue 1 year ago • 3 comments

Currently we cannot compile CGo programs to MacOS (at least x86_64) with default settings. Example Go file:

main.go

package main

// #include <stdio.h>
// char* hello() { return "hello, world"; }
// void phello() { printf("%s\n", hello()); }
import "C"

func main() {
        C.phello()
}

func Chello() string {
        return C.GoString(C.hello())
}

Compile to MacOS

$ CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 CC="zig cc -target x86_64-macos-none" go build  .
# example.com/x
/usr/local/go/pkg/tool/linux_amd64/link: running zig failed: exit status 1
error: unsupported linker arg: -no_pie

motiejus avatar Apr 24 '23 11:04 motiejus

Related: #15439

motiejus avatar Apr 24 '23 11:04 motiejus

I don't think we ever wanted to enable non PIE builds on macOS mainly because it is x86_64 specific. Thoughts?

kubkon avatar Jun 03 '23 22:06 kubkon

I don't think we ever wanted to enable non PIE builds on macOS mainly because it is x86_64 specific. Thoughts?

I personally don't care much about it nor truly understand the impact on this flag.

I am reporting the issue, because Go just adds it on x86_64. We need some way to make Go compile the CGo binaries for x86_64-macos.

Here is the CR in Go that added it: https://go-review.googlesource.com/c/go/+/201358

Or do we really need it? x86_64-macos is on the verge of being abandoned by Apple altogether.

motiejus avatar Jun 10 '23 05:06 motiejus

This flag is required to disambiguate position-dependent from position-independent code models generated by the compiler. The linker has no idea which model it should assume which is important to correctly apply relocations and relaxations. x86_64-macos allows both position-dependent and -independent models while aarch64-macos is strictly position-independent. Zig currently always assumes position-independent code (PIE) for macOS targets, while Go by default uses position-dependent code model for x86_64-macos (non-PIE), and position-independent for aarch64-macos (PIE).

If Apple is on the verge of discontinuing x86_64-macos and given we only support the latest 3 macOS releases, I think we have the luxury to put this feature in our good-to-have list of features that we might work on in the distant future.

kubkon avatar Jun 19 '23 07:06 kubkon

Hit "zig cc doesn't work as CC for cgo on Mac" at TigerBeetle. Would work around, as that's not critical, but having this just work would be nice!

matklad avatar Sep 27 '23 14:09 matklad

Does CGo actually require position-dependent code?

In any case, for Clang-level arguments, we currently handle -no-pie (and its many variations) by setting create_module.opts.pie = false. This ultimately goes ignored when linking on macOS. It seems to me that handling the -no_pie linker option in the same way would at least be no worse than that. And if CGo doesn't actually care about PIE, it would unblock this scenario. @kubkon thoughts?

alexrp avatar Jun 22 '24 07:06 alexrp

Does CGo actually require position-dependent code?

In any case, for Clang-level arguments, we currently handle -no-pie (and its many variations) by setting create_module.opts.pie = false. This ultimately goes ignored when linking on macOS. It seems to me that handling the -no_pie linker option in the same way would at least be no worse than that. And if CGo doesn't actually care about PIE, it would unblock this scenario. @kubkon thoughts?

There's way more than just forwarding a flag to the linker. We are actually missing all of non-pic/pie handling in the linker, so no, it's not a simple change.

kubkon avatar Jun 22 '24 08:06 kubkon

I think you misunderstood my comment? I'm acknowledging exactly that.

alexrp avatar Jun 22 '24 08:06 alexrp

What I'm saying is: We already handle the Clang-level (no-)PIE flags by setting create_module.opts.pie, but as you say, they're not respected by the Mach-O linker at the end of the day. But you can at least build with the flags without getting an error; you just won't get position-dependent output.

So I'm suggesting that we can just do the same for the -no_pie linker-level option: Accept it and do the same thing, with the understanding that actually emitting position-dependent output in the linker is a TODO.

alexrp avatar Jun 22 '24 08:06 alexrp

As an aside, @motiejus @matklad some searching suggests that you can use something like GOFLAGS="-buildmode=pie" to prevent that flag being emitted in the first place.

alexrp avatar Jun 22 '24 08:06 alexrp

The dotnet AOT toolchain uses these related lld/bfd flags: -pie, -no-pie and -static-pie (depending on higher-level msbuild flags). Perhaps those could also be handled by zig as part of this request (to avoid workarounds like these: https://github.com/MichalStrehovsky/PublishAotCross/blob/45d90a19c46ba2ce7fd6158babb045d665a678a2/src/clang.cmd#L19).

am11 avatar Aug 07 '24 10:08 am11

@am11 I've included dd93cf9 in #20384. But please note that all this does is wire it up in the frontend; it depends on the linker backend (lld vs zld) whether it's actually respected.

I'll do a follow-up PR after #20384 to add the linker flags that are being removed in that clang.cmd.

alexrp avatar Aug 07 '24 10:08 alexrp

Please note this issue is low priority for me especially since Apple ditched x86_64 and aarch64 doesn't support this flag anyhow.

kubkon avatar Aug 08 '24 05:08 kubkon