ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
35.13k stars 2.56k forks source link

[MachO] error: unsupported linker arg: -no_pie #15438

Open motiejus opened 1 year ago

motiejus commented 1 year ago

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 commented 1 year ago

Related: #15439

kubkon commented 1 year ago

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

motiejus commented 1 year ago

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.

kubkon commented 1 year ago

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.

matklad commented 1 year ago

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!

alexrp commented 5 months ago

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?

kubkon commented 5 months ago

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.

alexrp commented 5 months ago

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

alexrp commented 5 months ago

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 commented 5 months ago

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.

am11 commented 3 months ago

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).

alexrp commented 3 months ago

@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.

kubkon commented 3 months ago

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