ziglang / zig

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

Can't link on PPC64LE #20087

Open rany2 opened 5 months ago

rany2 commented 5 months ago

Zig Version

0.13.0-dev.267+793f820b3

Steps to Reproduce and Observed Behavior

Below is a demonstration of linking failing with the error from linker being call to save_start.posixCallMainAndExit lacks nop, can't restore toc. It doesn't not occur when using the GNU linker. I've also tested with LLVM 18.1.6 and it has the same problem.

Either way, I'm not sure if it's a LLVM or Zig issue but seeing that this seems to occur only with Zig I thought it would be better to report here first.

$ cat hello-world.zig 
const std = @import("std");
pub fn main() !void {
    std.debug.print("Hello, World!\n", .{});
}
$ ./zig build-exe --verbose-link hello-world.zig
LLD Link... ld.lld --error-limit=0 --entry _start -z stack-size=16777216 --image-base=16777216 -znow -m elf64lppc -static -o hello-world hello-world.o /home/rany/.cache/zig/o/b641c6ef537a8bd07eb50bc8e06bb5b4/libc.a --as-needed /home/rany/.cache/zig/o/b4e98cb876e0e0eee45053dd5ba4f2d7/libcompiler_rt.a
error: ld.lld: hello-world.o:(function _start: .text+0x18): call to save_start.posixCallMainAndExit lacks nop, can't restore toc
$ /opt/cfarm/binutils-2.42/bin/ld --entry _start -z stack-size=16777216 -znow -m elf64lppc -static -o hello-world hello-world.o /home/rany/.cache/zig/o/b641c6ef537a8bd07eb50bc8e06bb5b4/libc.a --as-needed /home/rany/.cache/zig/o/b4e98cb876e0e0eee45053dd5ba4f2d7/libcompiler_rt.a 
$ ./hello-world
Hello, World!

Expected Behavior

Seems similar to #18100

This is the machine info:

$ uname -a 
Linux cfarm120 5.14.0-284.11.1.el9_2.ppc64le #1 SMP Tue May 9 09:51:51 UTC 2023 ppc64le ppc64le ppc64le GNU/Linux

If you suggest, I could build zig myself but right now I've just used the prebuilt one: https://ziglang.org/builds/zig-linux-powerpc64le-0.13.0-dev.267+793f820b3.tar.xz. I tried the prebuilt version 0.11.0 and 0.12.0 and they both have the same issue.

rany2 commented 5 months ago

Explicitly specifying the -mcpu fixes the problem, it turns out the problem is that -mcpu defaults to pwr10 which is the toolchain default.

$ ./zig build-exe -mcpu=pwr10 hello-world.zig
error: ld.lld: hello-world.o:(function _start: .text+0x18): call to save_start.posixCallMainAndExit lacks nop, can't restore toc
$ ./zig build-exe -mcpu=ppc64le hello-world.zig
$ ./hello-world
Hello, World!
MementoRC commented 4 months ago

I am having a very hard time building on a PPC64le: Linux travis-job-conda-forge-zig-feedstock-623034056 5.4.0-52-generic #57-Ubuntu SMP Thu Oct 15 10:53:30 UTC 2020 ppc64le ppc64le ppc64le GNU/Linux The build simply fails without info when trying to execute the 0.13.0 zig binary distro

is this related, it fails with $zig build -Dcpu=ppc64

rany2 commented 4 months ago

@MementoRC Your machine is PPC64le, so it should be -mcpu=ppc64le. See https://github.com/ziglang/zig/issues/20087#issuecomment-2133867069. There is also a similar issue with PPC64 with a similar solution: https://github.com/ziglang/zig/issues/18100#issuecomment-2133894184

Note that this only works when you're calling build-exe or similar. When you use the newer build.zig (zig build) this workaround will not work because it is first compiles that using the default zig parameters and you cannot configure that. The only solution is to patch zig to explicitly add the correct -mcpu option in the linking step.

Edit: sorry, I see what you're trying to do now. zig build does not work because build.zig gets compiled as an executable first by Zig using the defaults and then gets executed by Zig. The -Dcpu=... you specified is only for building the prohect not the build.zig executable itself. As said above in the note, you cannot configure it.

MementoRC commented 4 months ago

@rany2 Thanks for the quick reply. I did try both. Does the ppc64le bin dist work for you? The following sehll:

    echo "Building zig from source"
    echo "ZIG: ${zig}"
    echo "     ${config_h}"
    ls -l "${zig}"
    uname -a
    $zig build.exe -mcpu=ppc64le
    $zig build -Dcpu=ppc64
    $zig build -Dcpu=ppc64

    mkdir -p "${install_dir}"
    "${zig}" build \
      --prefix "${install_dir}" \
      --search-prefix "${PREFIX}" \
      -Doptimize=ReleaseSafe \
      -Dconfig_h="${config_h}" \
      "${EXTRA_ZIG_ARGS[@]}" \
      -Dversion-string="${PKG_VERSION}"

gives:

Building zig from source
Building zig from source
ZIG: $SRC_DIR/zig-bootstrap/zig
     $SRC_DIR/build-release/config.h
-rwxr-xr-x 1 conda conda 174375504 Jun 16 03:44 $SRC_DIR/zig-bootstrap/zig
Linux travis-job-conda-forge-zig-feedstock-623035486 5.4.0-52-generic #57-Ubuntu SMP Thu Oct 15 10:53:30 UTC 2020 ppc64le ppc64le ppc64le GNU/Linux
The command "if [[ ${PLATFORM} =~ .*linux.* ]]; then CONDA_FORGE_DOCKER_RUN_ARGS="--network=host --security-opt=seccomp=unconfined" ./.scripts/run_docker_build.sh; fi" exited with 1.

on a ppc64le image running on Travis

MementoRC commented 4 months ago

I tried to cross-compile with CMake but get a

install
└─ install zig
   └─ zig build-exe zig ReleaseSafe powerpc64le-linux-gnu 1 errors
error: ld.lld: cannot open /usr/lib64/libpthread_nonshared.a: No such file or directory

that I can't fathom the origin

MementoRC commented 4 months ago

When I try to cross-compile with a x86_64 bootstrap zig it also fails. It gets a wrong prototype definition for sigaction compared to the sysroot v2.28 signal.h installed

It seems quite difficult to build (been trying for more than a month) - I am trying to populate the conda recipe for zig with all the supported arch and typically, conda prefers to built from source and within its own environment I have similar difficulties with windows

rany2 commented 4 months ago

I'm not sure what you're trying to do. Are you attempting to build Zig from source with your patches to include -mcpu=...?

MementoRC commented 4 months ago

I am just trying to build ZIG from source for a powerpc64le (when I only have a local x86_64) using either a cross-compilation or a Travis runner of the ppc64le image. Any way it builds is fine by me, I just want to build it. For this I have gone through these 3 options and all fail

The cross-compilation with CMake fails because the qemu-ppc64le-static simply cannot run the wasm exe that should build zig1, but now I see that even the binary distro does not run on the Travis runner

MementoRC commented 4 months ago

I'm not sure what you're trying to do. Are you attempting to build Zig from source with your patches to include -mcpu=...?

the excerpt I show is to try to understand what is going on the Travis runner to make the zig distribution just stop without any errors - x-compiling the same recipe for aarch64 worked well

The best for me would be to cross-compile from x86_64, this way I can debug locally rather than submit tons of commit to see what happens

rany2 commented 4 months ago

I don't know, sorry.

MementoRC commented 4 months ago

Thanks, been quite frustrated with it (and windows), so it helped a lot to discuss it a bit. I'll probably open a separate issue since this solution does not seem to solve it