Thread overview
Cross-compile macOS to Ubuntu
Dec 20, 2018
Paolo Invernizzi
Dec 20, 2018
kinke
Dec 26, 2018
Paolo Invernizzi
Dec 26, 2018
kinke
Dec 30, 2018
Paolo Invernizzi
Dec 31, 2018
kinke
Dec 20, 2018
Your Name
Dec 22, 2018
Jacob Carlborg
Dec 26, 2018
Timoses
December 20, 2018
Hi all,

I'm pretty new to cross compiling, and I'm trying to cross-compile from a macOS to a Ubuntu machine.

I'm using, ldc-1.13.0 on macOS 12, files and libraries copied from a vanilla docker Ubuntu 18.04 with ldc-1.13.0.

With the relevant files in the directory `ubuntu`, and doing:
---
ln ubuntu/lib/x86_64-linux-gnu/librt-2.27.so ubuntu/lib/x86_64-linux-gnu/librt.so
ln ubuntu/lib/x86_64-linux-gnu/libdl-2.27.so ubuntu/lib/x86_64-linux-gnu/libdl.so
ln ubuntu/lib/x86_64-linux-gnu/libpthread-2.27.so ubuntu/lib/x86_64-linux-gnu/libpthread.so
ln ubuntu/lib/x86_64-linux-gnu/libm-2.27.so ubuntu/lib/x86_64-linux-gnu/libm.so

ldc2 -mtriple=x86_64-unknown-linux-gnu -link-internally -L-L./ubuntu/ldc-1.13.0/lib -L-L./ubuntu/lib/x86_64-linux-gnu -L-error-limit=0 hello.d
---

I'm almost there, I'm missing the C runtime:
---
ldc2 -mtriple=x86_64-unknown-linux-gnu -link-internally -L-L./ubuntu/ldc-1.13.0/lib -L-L./ubuntu/lib/x86_64-linux-gnu -L-error-limit=0 hello.d
lld: error: undefined symbol: fwrite
>>> referenced by hello.d
>>>               hello.o:(_D3std5stdio__T13trustedFwriteTaZQsFNbNiNePOS4core4stdcQBx8_IO_FILExAaZm)
<snip>
---

Internally, lld is invoked as:
---
lld hello.o -o hello -L./ubuntu/ldc-1.13.0/lib -L./ubuntu/lib/x86_64-linux-gnu -error-limit=0 -L/Users/pinver/dlang/ldc-1.13.0/bin/../lib -lphobos2-ldc -ldruntime-ldc --gc-sections -lrt -ldl -lpthread -lm
---

I've tried linking against the vanilla `libc.so` but without success... so:

- someone can point me to correct missing `.so` and `.o` to link, and their location?

Thank you,
Paolo


December 20, 2018
On Thursday, 20 December 2018 at 17:37:23 UTC, Paolo Invernizzi wrote:
> I've tried linking against the vanilla `libc.so` but without success... so:
>
> - someone can point me to correct missing `.so` and `.o` to link, and their location?

That mess wrt. distro-specific default libs/object files/other switches being injected by gcc into the linker command line is the reason we recommend using a cross-gcc toolchain for Linux/BSD targets. Anyway, you can invoke `gcc dummy.c -v` in Ubuntu to check the default linker args added by gcc, and work your way from there. E.g., see the first paragraph in https://github.com/ldc-developers/ldc/pull/2203#issuecomment-339167131. In my case on Ubuntu 18.04, the ugly linker cmdline is:

/usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccqp6nEf.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. <DUMMY.o> -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
December 20, 2018
On Thursday, 20 December 2018 at 17:37:23 UTC, Paolo Invernizzi wrote:
> Hi all,
>
> I'm pretty new to cross compiling, and I'm trying to cross-compile from a macOS to a Ubuntu machine.
>
> [...]

I was trying to get cross compiling set up too, but I ended up just using docker to run a ubuntu image, and compile in that.
December 22, 2018
On 2018-12-20 18:37, Paolo Invernizzi wrote:
> Hi all,
>
> I'm pretty new to cross compiling, and I'm trying to cross-compile from
> a macOS to a Ubuntu machine.

For targeting Linux, I would recommend to compile inside a Docker container instead of trying to cross-compile.

-- 
/Jacob Carlborg
December 26, 2018
On Thursday, 20 December 2018 at 21:47:40 UTC, kinke wrote:
> On Thursday, 20 December 2018 at 17:37:23 UTC, Paolo Invernizzi wrote:
>> I've tried linking against the vanilla `libc.so` but without success... so:
>>
>> - someone can point me to correct missing `.so` and `.o` to link, and their location?
>
> That mess wrt. distro-specific default libs/object files/other switches being injected by gcc into the linker command line is the reason we recommend using a cross-gcc toolchain for Linux/BSD targets. Anyway, you can invoke `gcc dummy.c -v` in Ubuntu to check the default linker args added by gcc, and work your way from there. E.g., see the first paragraph in https://github.com/ldc-developers/ldc/pull/2203#issuecomment-339167131. In my case on Ubuntu 18.04, the ugly linker cmdline is:
>
> /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccqp6nEf.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. <DUMMY.o> -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o

Thank you kinke,

Coping the relevant files and building with the command line below [1] produce an executable, but fails on Linux  [2], oh well...

BTW, I read some threads [3], and like Atila I'm not able to use lld also on Ubuntu with LDC 1.13...

No problems, I can stick with Docker builds right now, anyway, suggestions are welcome!

Cheers,

--- Paolo


[1] ldc2 -mtriple=x86_64-unknown-linux-gnu -link-internally -L--eh-frame-hdr -L-m -Lelf_x86_64 -L--hash-style=gnu -L-pie -L-z -Lnow -L-z -Lrelro -L./ubuntu/usr/lib/x86_64-linux-gnu/Scrt1.o -L./ubuntu/usr/lib/x86_64-linux-gnu/crti.o -L./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L-L./ubuntu/ldc-1.13.0/lib -L-L./ubuntu/lib/x86_64-linux-gnu -L./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a -L./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so.1 -L./ubuntu/lib/x86_64-linux-gnu/libc.so.6 -L./ubuntu/usr/lib/x86_64-linux-gnu/libc_nonshared.a -L./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o -L-dynamic-linker -L/lib64/ld-linux-x86-64.so.2 -v hello.d

[2]
root@84eb0783a80b:/prj# ./hello
Trace/breakpoint trap
root@84eb0783a80b:/prj# gdb ./hello
<snip>
(gdb) r
Starting program: /prj/hello
warning: Error disabling address space randomization: Operation not permitted
warning: Could not trace the inferior process.
Error:
warning: ptrace: Operation not permitted
During startup program exited with code 127.

[3] https://forum.dlang.org/thread/bxzlendtgbfxodtmpzdf@forum.dlang.org



December 26, 2018
On Saturday, 22 December 2018 at 19:06:53 UTC, Jacob Carlborg wrote:
> On 2018-12-20 18:37, Paolo Invernizzi wrote:
>> Hi all,
>>
>> I'm pretty new to cross compiling, and I'm trying to cross-compile from
>> a macOS to a Ubuntu machine.
>
> For targeting Linux, I would recommend to compile inside a Docker container instead of trying to cross-compile.

I just recently used https://github.com/andrewbenton/alpine-ldc for a project. Works fine.
When compiling in Vibe-core it complains about a missing library "-lanl" (libanl).. Still haven't figured that one out.
December 26, 2018
On Wednesday, 26 December 2018 at 18:06:47 UTC, Paolo Invernizzi wrote:
> Coping the relevant files and building with the command line below [1] produce an executable, but fails on Linux  [2], oh well...

I guess this has sth. to do with the linker command-line args *order*. Note that gcc puts the startup object files first, then the actually compiled user code object files, and then the crtend object files. This order is probably not reproducible with a normal compile-and-link LDC command line.
Before blaming LLD, it may be worth feeding it the exact same command line as ld/collect2 and check that result.

Btw, if you see those no-warn-on-search-mismatch errors, just edit your etc/ldc2.conf config file, it should be self-explanatory.
December 30, 2018
On Wednesday, 26 December 2018 at 23:55:14 UTC, kinke wrote:
> On Wednesday, 26 December 2018 at 18:06:47 UTC, Paolo Invernizzi wrote:
>> Coping the relevant files and building with the command line below [1] produce an executable, but fails on Linux  [2], oh well...
>
> I guess this has sth. to do with the linker command-line args *order*. Note that gcc puts the startup object files first, then the actually compiled user code object files, and then the crtend object files. This order is probably not reproducible with a normal compile-and-link LDC command line.
> Before blaming LLD, it may be worth feeding it the exact same command line as ld/collect2 and check that result.
>
> Btw, if you see those no-warn-on-search-mismatch errors, just edit your etc/ldc2.conf config file, it should be self-explanatory.

Indeed it was the order, now I'm able to correctly cross compile for Ubuntu 18.04, but I need to use directly LLD.

There's a plan to add more flexibility in specifying the linker command line for `-link-internally`?

Anyway, below I'm reporting the full pass I've used, If worth I can add them to the wiki, if someone is interested.

-- Paolo

```
brew install llvm
curl -fsS https://dlang.org/install.sh | bash -s ldc && source ~/dlang/ldc-1.13.0/activate

/usr/local/opt/llvm/bin/ld.lld --version : LLD 7.0.1 (compatible with GNU linkers)
ldc2 --version                           : LDC - the LLVM D compiler (1.13.0)

mkdir -p ubuntu/lib/x86_64-linux-gnu
mkdir -p ubuntu/usr/lib/gcc/x86_64-linux-gnu/7
mkdir -p ubuntu/usr/lib/x86_64-linux-gnu
mkdir -p ubuntu/ldc-1.13.0/lib

docker run --rm -it -v $PWD/ubuntu:/ubuntu ubuntu:18.04

apt-get update && apt-get install -y curl xz-utils build-essential lld
curl -fsS https://dlang.org/install.sh | bash -s ldc
cp /lib/x86_64-linux-gnu/libc.so.6                  /ubuntu/lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2       /ubuntu/lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libpthread.so.0            /ubuntu/lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libmvec.so.1               /ubuntu/lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libm.so.6                  /ubuntu/lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/librt-2.27.so              /ubuntu/lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libdl-2.27.so              /ubuntu/lib/x86_64-linux-gnu
cp /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o      /ubuntu/usr/lib/gcc/x86_64-linux-gnu/7
cp /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o        /ubuntu/usr/lib/gcc/x86_64-linux-gnu/7
cp /usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a         /ubuntu/usr/lib/gcc/x86_64-linux-gnu/7
cp /usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so.1    /ubuntu/usr/lib/gcc/x86_64-linux-gnu/7
cp /usr/lib/x86_64-linux-gnu/Scrt1.o                /ubuntu/usr/lib/x86_64-linux-gnu
cp /usr/lib/x86_64-linux-gnu/crti.o                 /ubuntu/usr/lib/x86_64-linux-gnu
cp /usr/lib/x86_64-linux-gnu/crtn.o                 /ubuntu/usr/lib/x86_64-linux-gnu
cp /usr/lib/x86_64-linux-gnu/libc_nonshared.a       /ubuntu/usr/lib/x86_64-linux-gnu
cp /usr/lib/x86_64-linux-gnu/libmvec_nonshared.a    /ubuntu/usr/lib/x86_64-linux-gnu
cp /usr/lib/x86_64-linux-gnu/libpthread_nonshared.a /ubuntu/usr/lib/x86_64-linux-gnu
cp ~/dlang/ldc-1.13.0/lib/libphobos2-ldc.a          /ubuntu/ldc-1.13.0/lib/
cp ~/dlang/ldc-1.13.0/lib/libdruntime-ldc.a         /ubuntu/ldc-1.13.0/lib/
exit

ldc2 -c hello.d
/usr/local/opt/llvm/bin/ld.lld \
  -o hello \
  \
  --sysroot=/ \
  --build-id \
  --eh-frame-hdr \
  -m elf_x86_64 \
  --hash-style=gnu \
  -pie \
  -z now \
  -z relro \
  \
  --lto-O2 \
  --gc-sections \
  \
  -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
  \
  -L./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7 \
  -L./ubuntu/usr/lib/x86_64-linux-gnu \
  -L./ubuntu/usr/lib \
  -L./ubuntu/lib/x86_64-linux-gnu  \
  -L./ubuntu/lib \
  \
  ./ubuntu/usr/lib/x86_64-linux-gnu/Scrt1.o \
  ./ubuntu/usr/lib/x86_64-linux-gnu/crti.o \
  ./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o \
  \
  hello.o \
  \
  ./ubuntu/ldc-1.13.0/lib/libphobos2-ldc.a  ./ubuntu/ldc-1.13.0/lib/libdruntime-ldc.a \
  \
  ./ubuntu/lib/x86_64-linux-gnu/librt-2.27.so \
  ./ubuntu/lib/x86_64-linux-gnu/libdl-2.27.so \
  ./ubuntu/lib/x86_64-linux-gnu/libpthread.so.0 ./ubuntu/usr/lib/x86_64-linux-gnu/libpthread_nonshared.a \
  ./ubuntu/lib/x86_64-linux-gnu/libm.so.6 ./ubuntu/usr/lib/x86_64-linux-gnu/libmvec_nonshared.a ./ubuntu/lib/x86_64-linux-gnu/libmvec.so.1 \
  \
  ./ubuntu/lib/x86_64-linux-gnu/libc.so.6 ./ubuntu/usr/lib/x86_64-linux-gnu/libc_nonshared.a ./ubuntu/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 \
  ./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a \
  ./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so.1 \
  \
  ./ubuntu/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o \
  ./ubuntu/usr/lib/x86_64-linux-gnu/crtn.o
```


December 31, 2018
On Sunday, 30 December 2018 at 17:19:00 UTC, Paolo Invernizzi wrote:
> There's a plan to add more flexibility in specifying the linker command line for `-link-internally`?

Thanks for experimenting and confirming.
The etc/ldc2.conf file may provide enough flexibility already. There are switches injected before the explicit cmdline args, and switches (`post-switches`) appended after the explicit ones.
If the problematic order only involves object files, you could try adding the startup object files to `switches` (directly, i.e., `Scrt1.o`, not as linker arg `-LScrt1.o`), and `crtendS.o` etc. to `post-switches`.
IIRC, there's a special case where we move the single compiled object file in front of all other object files; you may have to use `-singleobj=false` to work around that.