[llvm-dev] ld.lld ignoring --sysroot

1,079 views
Skip to first unread message

Ivan Medoedov via llvm-dev

unread,
May 13, 2020, 10:04:52 PM5/13/20
to llvm-dev
Hello,

I'm trying to compile a Linux hello world executable on macOS.

The first step is simple:

clang -c -target x86_64-linux-gnu -c -o hello.o hello.c

But linking results in an error:

ld.lld --sysroot=/linuxroot/ -o hello -m elf_x86_64 \
  -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
  /lib/crt1.o \
  /usr/lib/x86_64-linux-gnu/crti.o ../hello.o \
  /usr/lib/x86_64-linux-gnu/libc.so \
  /usr/lib/x86_64-linux-gnu/crtn.o

ld.lld: error: cannot open /lib/crt1.o: No such file or directory
ld.lld: error: cannot open /usr/lib/x86_64-linux-gnu/crti.o: No such file or directory

/linuxroot/ contains all the necessary files copied from a Linux machine:
/linuxroot/lib/crt1.o, /linuxroot/usr/lib/x86_64-linux-gnu/crti.o, etc

It works if I use a full path for each file (-dynamic-linker /linuxroot/lib64/ld-linux-x86-64.so.2 ...), but the resulting binary doesn't work on Linux, because it's dynamically linked to /linuxroot/... which is missing on the Linux box.

file hi
hi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /linuxroot/lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped

The only way I can make it work is to have actual /usr/lib/x86_64-linux-gnu/crti.o etc on my macOS box, which --sysroot is supposed to help avoid.

I'm sure I'm missing something simple here. I've been following the docs, but couldn't figure it out on my own.

Thanks!

Rui Ueyama via llvm-dev

unread,
May 13, 2020, 11:23:18 PM5/13/20
to Ivan Medoedov, llvm-dev
On Thu, May 14, 2020 at 11:04 AM Ivan Medoedov via llvm-dev <llvm...@lists.llvm.org> wrote:
Hello,

I'm trying to compile a Linux hello world executable on macOS.

The first step is simple:

clang -c -target x86_64-linux-gnu -c -o hello.o hello.c

But linking results in an error:

ld.lld --sysroot=/linuxroot/ -o hello -m elf_x86_64 \
  -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
  /lib/crt1.o \
  /usr/lib/x86_64-linux-gnu/crti.o ../hello.o \
  /usr/lib/x86_64-linux-gnu/libc.so \
  /usr/lib/x86_64-linux-gnu/crtn.o

ld.lld: error: cannot open /lib/crt1.o: No such file or directory
ld.lld: error: cannot open /usr/lib/x86_64-linux-gnu/crti.o: No such file or directory

--sysroot affects some library search paths, but it doesn't affect paths directly given to the linker. In the above command line, you are directly specifying object file and so file paths without -l, so the linker looks at the only given locations. This is an expected behavior.

I think, unlike some other linkers, --sysroot option isn't very useful for lld, because lld doesn't have a notion of built-in default search paths. You always have to specify library search paths by -L option to lld. So why don't you specify library directories with -L, like this?

$ ld.lld -o hello -m elf_x86-64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -L /linuxroot/usr/lib -lc /linuxroot/usr/lib/x86_64-linux-gnu/crtn.o


/linuxroot/ contains all the necessary files copied from a Linux machine:
/linuxroot/lib/crt1.o, /linuxroot/usr/lib/x86_64-linux-gnu/crti.o, etc

It works if I use a full path for each file (-dynamic-linker /linuxroot/lib64/ld-linux-x86-64.so.2 ...), but the resulting binary doesn't work on Linux, because it's dynamically linked to /linuxroot/... which is missing on the Linux box.

file hi
hi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /linuxroot/lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped

The only way I can make it work is to have actual /usr/lib/x86_64-linux-gnu/crti.o etc on my macOS box, which --sysroot is supposed to help avoid.

I'm sure I'm missing something simple here. I've been following the docs, but couldn't figure it out on my own.

Thanks!

_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Fangrui Song via llvm-dev

unread,
May 14, 2020, 2:06:39 AM5/14/20
to Ivan Medoedov, llvm-dev
On 2020-05-14, Rui Ueyama via llvm-dev wrote:
>On Thu, May 14, 2020 at 11:04 AM Ivan Medoedov via llvm-dev <
>llvm...@lists.llvm.org> wrote:
>
>> Hello,
>>
>> I'm trying to compile a Linux hello world executable on macOS.
>>
>> The first step is simple:
>>
>> clang -c -target x86_64-linux-gnu -c -o hello.o hello.c
>>
>> But linking results in an error:
>>
>> ld.lld --sysroot=/linuxroot/ -o hello -m elf_x86_64 \
>> -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
>> /lib/crt1.o \
>> /usr/lib/x86_64-linux-gnu/crti.o ../hello.o \
>> /usr/lib/x86_64-linux-gnu/libc.so \
>> /usr/lib/x86_64-linux-gnu/crtn.o
>>
>> ld.lld: error: cannot open /lib/crt1.o: No such file or directory
>> ld.lld: error: cannot open /usr/lib/x86_64-linux-gnu/crti.o: No such file
>> or directory
>>

You misunderstand GNU ld's --sysroot rule, which is applicable in these two cases:

* when a path begins with "=" or "$SYSROOT"
* https://www.sourceware.org/binutils/docs/ld/File-Commands.html
"In case a sysroot prefix is configured, and the filename starts with
the ‘/’ character, and the script being processed was located inside
the sysroot prefix, the filename will be looked for in the sysroot
prefix."

For your case, you need a linker script located under /linuxroot/, which
INPUT or GROUP an absolute path.

Ivan Medoedov via llvm-dev

unread,
May 14, 2020, 6:59:44 AM5/14/20
to Fangrui Song, llvm-dev
Thanks for the replies.

Rui, with your command I get

ld.lld: error: unknown emulation: elf_x86-64
ld.lld: error: unable to find library -lc
ld.lld: error: cannot open /linuxroot/usr/lib/x86_64-linux-gnu/crtn.o: No such file or directory


> For your case, you need a linker script located under /linuxroot/, which INPUT or GROUP an absolute path.

Do you have an example of such linker script? I have no idea how this works.

Ivan Medoedov via llvm-dev

unread,
May 14, 2020, 7:01:20 AM5/14/20
to llvm-dev
Sorry, it's just 

ld.lld: error: unknown emulation: elf_x86-64
ld.lld: error: unable to find library -lc

Path to /linuxroot/usr/lib/x86_64-linux-gnu/crtn.o is correct

Ivan Medoedov via llvm-dev

unread,
May 14, 2020, 7:49:22 PM5/14/20
to llvm-dev
I managed to make it work with

ld.lld -L /linuxroot/usr/lib/x86_64-linux-gnu/ \
  --sysroot=/linuxroot/ -v -o hello -m elf_x86_64 \
  -dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 \
  crt1.o \
  crti.o ../hello.o \
  ./lib/x86_64-linux-gnu/libc.so.6 \
  -lc \
  crtn.o

Thanks for your help
Reply all
Reply to author
Forward
0 new messages