cosmopolitan icon indicating copy to clipboard operation
cosmopolitan copied to clipboard

Apple's linker can't build portable binaries

Open tromp opened this issue 3 years ago • 7 comments

Trying the example on macOS Catalina 10.15.7:

$ gcc -g -O -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone -o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds -include cosmopolitan.h crt.o ape.o cosmopolitan.a ld: unknown option: -T collect2: error: ld returned 1 exit status $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/10.2.0_3/libexec/gcc/x86_64-apple-darwin19/10.2.0/lto-wrapper Target: x86_64-apple-darwin19 Configured with: ../configure --build=x86_64-apple-darwin19 --prefix=/usr/local/Cellar/gcc/10.2.0_3 --libdir=/usr/local/Cellar/gcc/10.2.0_3/lib/gcc/10 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-10 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 10.2.0_3' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk SED=/usr/bin/sed Thread model: posix Supported LTO compression algorithms: zlib gcc version 10.2.0 (Homebrew GCC 10.2.0_3) $ ld -v @(#)PROGRAM:ld PROJECT:ld64-609.8 BUILD 15:07:46 Dec 18 2020 configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em LTO support using: LLVM version 12.0.0, (clang-1200.0.32.29) (static support for 27, runtime is 27) TAPI support using: Apple TAPI version 12.0.0 (tapi-1200.0.23.5)

tromp avatar Feb 28 '21 11:02 tromp

It's not possible to build Actually Portable Executables if you're using a toolchain that's configured to use Apple's proprietary ld command, because Apple designed it to only produce binaries that run on Apple. You need to install an x86_64-pc-linux-gnu toolchain on your machine. The problem is I don't know if anyone's ever built a GCC+BinUtils toolchain for MacOS before. I've tried building GCC from source on Mac a couple times but failed.

I did however manage to get GCC to successfully compile on Windows: https://justine.lol/cosmopolitan/windows-compiling.html If anyone can help us do the same thing for Mac please reach out!

Until then I would recommend building your binaries on Linux. Cosmopolitan has universal deployment down pat. Universal development is a work in progress.

jart avatar Feb 28 '21 12:02 jart

I use nix to get cross-compile toolchains, and this also works on macOS. This is how I get a temporary one with nix-shell, which automatically sets CC, CXX, LD etc within the shell for you:

$ cat - > shell.nix
let pkgs = import <nixpkgs> {
  crossSystem = {
    config = "x86_64-pc-linux-gnu";
  };
};
in
  pkgs.callPackage (
    {mkShell, pkg-config, zlib}:
    mkShell {
      nativeBuildInputs = [ pkg-config ]; # cosmopolitan build dependencies here (there aren't any?)
      buildInputs = [ zlib ]; # cosmopolitan runtime dependencies here (there aren't any? qemu?)
    }
  ) {}
^D

$ nix-shell

(From: https://nixos.wiki/wiki/Cross_Compiling#How_to_obtain_a_shell_with_a_cross_compiler )

I plan to try a macOS-only cosmopolitan build with the above and see how far I get, but for acquiring a cross gcc toolchain for any platform (for any project), it might be useful already.

paulreimer avatar Feb 28 '21 18:02 paulreimer

It's not possible to build Actually Portable Executables if you're using a toolchain that's configured to use Apple's proprietary ld command, because Apple designed it to only produce binaries that run on Apple. You need to install an x86_64-pc-linux-gnu toolchain on your machine. The problem is I don't know if anyone's ever built a GCC+BinUtils toolchain for MacOS before. I've tried building GCC from source on Mac a couple times but failed.

I did however manage to get GCC to successfully compile on Windows: https://justine.lol/cosmopolitan/windows-compiling.html If anyone can help us do the same thing for Mac please reach out!

Until then I would recommend building your binaries on Linux. Cosmopolitan has universal deployment down pat. Universal development is a work in progress.

But couldn't the x86_64-pc-linux-gnu toolchain be built using cosmopolitan and then it would be just as portable as any other program compiled with cosmopolitan, which of course includes macOS and Windows. How about bundling such a portable x86_64-pc-linux-gnu toolchain with cosmopolitan?

feeley avatar Feb 28 '21 21:02 feeley

Yes it could, but it's likely blocked by #27 and also the fact that GCC is notoriously difficult to compile from source in general. I'm sure someone will come along eventually who's good at doing that. I've personally found it much more fun to develop a new compiler / assembler / linker in a greenfield. See //third_party/chibicc. That compiler will never be an adequate replacement for GCC. But it's something that's tiny fast and fun in the meantime.

jart avatar Mar 01 '21 03:03 jart

blocked by #27

gcc 4.7.4 is written in pure C, only 4.8 and newer require a C++ toolchain.

rofl0r avatar Mar 05 '21 22:03 rofl0r

I gave the x86_64-elf GNU compiler collection from homebrew a whirl and it worked 🤠 #163

@jart, I can build APE binaries on MacOS using the prebuilt / amalg pkg no problem now, but I can't seem to get any of the cosmopolitan make commands to work, not even for the hello.com build. I tried all kinds of hackery, like tweaking most of the mk config to brute replacing the third-party gcc binaries with the ones from brew. My real goal is to build redbean on MacOS, but how do I separate that task from the concerns of compiling from source, any insights / pointers?

d4tocchini avatar May 07 '21 13:05 d4tocchini

@d4tocchini

I can't seem to get any of the cosmopolitan make commands to work

If you get

Bad system call: 12

I executed make o//tool/build/mkdeps.com o//third_party/make/make.com on linux and copied (typically with scp but nc could also work): o//tool/build/mkdeps.com ./build/bootstrap/mkdeps.com and o//third_party/make/make.com ./build/bootstrap/make.com

build/bootstrap/make.com failed with

./build/bootstrap/make.com
`make MODE= -j8 o/ape/config.h.ok` exited with 127:
o/third_party/gcc/bin/x86_64-linux-musl-gcc

so I installed x86_64-elf-gcc as you suggested it pulled me x86_64-elf-gcc 12.1.0 and x86_64-elf-binutils 2.38

Since unbundle.com works only on linux: https://github.com/jart/cosmopolitan/blob/066ed2b2b229dce4d1f49be86179bb8efa9b9724/tool/build/unbundle.c#L75

I overwrote those lines: https://github.com/jart/cosmopolitan/blob/066ed2b2b229dce4d1f49be86179bb8efa9b9724/build/definitions.mk#L88-L99

with :'<,'>s/o\/third_party\/gcc\/bin\/x86_64-linux-musl-/x86_64-elf-/ in vim

since some warning are triggered I removed https://github.com/jart/cosmopolitan/blob/066ed2b2b229dce4d1f49be86179bb8efa9b9724/build/definitions.mk#L138

and now it fail:

libc/nexgen32e/cescapec.S: Assembler messages:
libc/nexgen32e/cescapec.S:115: Error: number of operands mismatch for `mov'

https://github.com/jart/cosmopolitan/blob/066ed2b2b229dce4d1f49be86179bb8efa9b9724/libc/nexgen32e/cescapec.S#L115 it seem to be the /2 that cause parsing failure since *2 works.

Could it be binutils regression ?

It is intended: https://sourceware.org/bugzilla/show_bug.cgi?id=4572 --divide need to be added and then libc compile fine

Thus 57 targets need to be fixed.

Et7f3 avatar Jul 28 '22 09:07 Et7f3