This is an archive of the discontinued LLVM Phabricator instance.

[Driver] Add a experimental option to link to LLVM libc.
Needs ReviewPublic

Authored by sivachandra on Mar 1 2021, 2:15 PM.

Details

Reviewers
phosek
MaskRay
Summary

The experimental option is named -experimental-link-llvmlibc. Specifying
it will put -lllvmlibc before each system libc library component on the
link command line. This way, even if the user specifies -lm, functions
from LLVM libc will be picked instead of functions from the system libc
math library. Also, sanitizer and other options add -lm at few other
places. By putting -lllvmlibc right before each of them, we ensure that
functions available in LLVM libc are picked up by the linker.

Diff Detail

Event Timeline

sivachandra created this revision.Mar 1 2021, 2:15 PM
sivachandra requested review of this revision.Mar 1 2021, 2:15 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 1 2021, 2:15 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
phosek added inline comments.
clang/lib/Driver/ToolChains/Gnu.cpp
680

This wouldn't handle the case where you use -nolibc path/to/libc.a in which case you'd have to manually pass in the libllvmllibc.a, but I'm not sure if that's a case we care about.

684

You can move this after the condition and omit the else branch.

Address comment.

sivachandra added inline comments.Mar 4 2021, 5:12 PM
clang/lib/Driver/ToolChains/Gnu.cpp
680

Yeah, its hard to cater to all combinations. In this case though, assuming libllvmlibc.a is available in path, one can add -lllvmlibc in the right place.

684

[Shame cube] Fixed.

sivachandra added inline comments.Mar 4 2021, 5:14 PM
clang/lib/Driver/ToolChains/Gnu.cpp
680

Another point to note is that -nolibc does not prevent -lm from getting added for C++ compilations.

If the end goal is to provide a complete libc, and currently the usage is expected to shadow system libc (this has to be very careful, as I don't know how shadowing some important components like pthread shall work), perhaps the name should convey this point?

clang/test/Driver/linux-ld.c
235–255

Empty // actually makes browsing difficult and we generally don't do this for other tests. You can omit them.

In addition to the bikeshed below, I'm not a huge fan of this in general. I think we should assume that the libc we link is complete and thus it would just be named "libc.<ext>" and in a sysroot somewhere. Another option is perhaps looking at the rtlib option, but I'd want to see a bit of a writeup there so we can see what we'd be doing.

Thoughts? Other options?

Thanks!

-eric

clang/include/clang/Driver/Options.td
3626

Bikeshedding: Not a huge fan of this name. I'd rather a more general option if we feel the need to select libc from an option rather than a sysroot.

In addition to the bikeshed below, I'm not a huge fan of this in general. I think we should assume that the libc we link is complete and thus it would just be named "libc.<ext>" and in a sysroot somewhere. Another option is perhaps looking at the rtlib option, but I'd want to see a bit of a writeup there so we can see what we'd be doing.

By not giving it a libc.<ext> name, we are actually implying that, "it is not the full libc that you expect." It is expected that it will be used along with another full libc. When LLVM libc is complete enough, then yes we should be giving it the conventional name of libc.<ext> and the experimental option can be thrown out.

If the end goal is to provide a complete libc, and currently the usage is expected to shadow system libc (this has to be very careful, as I don't know how shadowing some important components like pthread shall work), perhaps the name should convey this point?

Yes. So, we have not done it yet, but the plan is to be able to build LLVM in two different modes:

  1. The default mode: This mode only builds and packages the ABI independent and ABI agnostic parts of LLVM libc. The binaries produced from this mode are to be used with the -experimental-llvm-libc. The plan is also to make default mode work under LLVM_RUNTIMES_BUILD.
  2. The full libc mode: In this mode, LLVM libc will be built as if it is a full libc. A special CMake option needs to be set to build in this mode. The binaries produced in this mode will include everything, including ABI sensitive pieces. They will be tested on bots but will not be practically useful for many months as we are still building out the libc.
clang/include/clang/Driver/Options.td
3626

The idea is not to provide an option to "choose" a libc. The idea is that this option will help one use what LLVM libc provides while getting the rest from the system libc. I would think that the option to "choose" a libc is not related to this as LLVM libc is not complete.

In addition to the bikeshed below, I'm not a huge fan of this in general. I think we should assume that the libc we link is complete and thus it would just be named "libc.<ext>" and in a sysroot somewhere. Another option is perhaps looking at the rtlib option, but I'd want to see a bit of a writeup there so we can see what we'd be doing.

I missed responding to the "writeup" part earlier. But, I am not sure what I should be writing about. I feel that there is some confusion that this option can be used to switch between libcs. As I said in the earlier reply, the idea is not to provide a way to switch between libcs. Rather, the goal is to provide a way to use LLVM libc along with the system libc with the effect that LLVM libc symbols will be preferred by the linker over the system libc symbols.

Remove empty '//' in lit test file.

sivachandra marked an inline comment as done.Mar 4 2021, 9:02 PM
phosek added a comment.Mar 4 2021, 9:54 PM

Have you considered using an input linker script? We could generate libc.so that could look something like:

INPUT(libllvmlibc.a /lib/libc.so)

We would need to pass --sysroot to the linker for this to work. The driver could remain completely agnostic of whether you're using LLVM libc or not.

Have you considered using an input linker script? We could generate libc.so that could look something like:

INPUT(libllvmlibc.a /lib/libc.so)

We would need to pass --sysroot to the linker for this to work. The driver could remain completely agnostic of whether you're using LLVM libc or not.

Yes, that was also considered. Those downstream users who have the flexibility to do it that way should be able to do it that way. However, not all downstream users or normal clang users will have that liberty [1]. Another point to note is that we will have to do this with all libc components like libc.so, libm.so etc.

[1] I think all of this can be done. For example, we can set all this up when building a distribution. However, I am not sure this is worth it when we know this is a transient phase. Soon, when LLVM libc is complete enough, a more appropriate option would be the one which allows choosing a libc as Eric pointed out.