I just read this about C standard library:
When compiling C code, the C standard library cannot be switched per-compilation. It is necessary to build the entire compiler toolchain for the selected C library. That means either cross-compilation, or, in case of Linux, compiling in a distribution that uses the chosen C library. If I wanted to compile with musl, I'd compile in Alpine Linux, and so on.
Is this correct? My gut feeling is that, since libc is just a library, it should be possible to select a different one to compile and link against without modifying the compiler itself (if this is true, please tell me how). But I've seen system triplet such as x86_64-pc-linux-gnu
and x86_64-pc-linux-musl
, which suggests that cross-compilation is necessary.
Also, in the official GCC install guide:
In order to build GCC, the C standard library and headers must be present for all target variants for which target libraries will be built (and not only the variant of the host C++ compiler).
If libc can be swapped per-compilation, then only library and headers for the host should be necessary (for building and linking the compiler itself).
I tried compiling programs with -nostdinc -nostdlib -isystem /path/to/libc/include -L/path/to/libc/lib
. Sometimes it works, sometimes it doesn't (for reasons I've yet to understand).
My gut feeling is that, since libc is just a library, it should be possible to select a different one to compile and link against without modifying the compiler itself (if this is true, please tell me how).
It is conceivable that a C implementation could be designed such that the standard library functions and external objects are contained in a modular library, such that different implementations could be swapped in at compile and / or runtime. Note, however, that
that involves two different senses of the word "library". What is usually meant by the term "C standard library" is not a binary object such as can serve as input to a linker. Rather, it is a somewhat abstract collection of types, functions, objects, and macros to which every conforming C implementation provides a well-defined interface.
because conforming C implementations are required to include an implementation of the C standard library, there is considerable advantage to establishing deep connections between the toolchain and standard library implementation. For instance, the compiler might perform certain optimizations whose correctness depends on implementation details of library functions, or it might serve certain objectives by synthesizing calls to internal, implementation-specific functions best characterized as implementation details of the C standard library. Implementations don't have to do such things, but they can, and often do.
to any extent that an implementation provided for swappable standard libraries, there would still be limits to that. Any C standard library implementation must be compatible with the executable format, ABI, and (for hosted implementations) the underlying hardware and OS of the target machine.
on the other hand, there actually is a degree of modularity in practice with many implementations. For example, dynamically-linked binaries built against one version of Glibc will usually work correctly when transferred to systems that provide more recent versions of Glibc (all else being equal).
Overall, no, your gut is misleading you. Although it is conceivable that what you describe would be possible in some cases, you're unlikely in practice to run into an implementation that allows it, except in the limited sense already described. C toolchains ordinarily are tightly linked to specific standard library implementations.