Building world with clang
Dimitry Andric
dimitry at andric.com
Tue Aug 17 13:21:45 UTC 2010
On 2010-08-17 13:49, Bob Bishop wrote:
>> However, a disadvantage is that the built-in search paths of the
>> bootstrap compiler are not entirely disabled by using the -isysroot, -B
>> and -L flags,
>
> This could be viewed as a bug ...
It is probably a bit more complicated than that. Let me expand a bit
on those compiler flags (and note that clang tries to mimic gcc's
interpretation of them, but is not always perfect).
The -isysroot option
====================
The -isysroot option is supposed to 'reset' the root for include files
to the specified path, according to the gcc documentation. If I compile
an empty .c file with "gcc -v -S", the default include paths are
printed:
/usr/include/gcc/4.2
/usr/include
If you now add "-isysroot ${WORLDTMP}" (the default value of WORLDTMP is
/usr/obj/usr/src/tmp), the resulting include paths become:
/usr/include/gcc/4.2
${WORLDTMP}/usr/include
So unfortunately, gcc seems to only prepend the isysroot path to one of
the directories.
Clang's default include paths are:
/usr/include/clang/2.8
/usr/include
With the same -isysroot option added, they become:
${WORLDTMP}/usr/include/clang/2.8
${WORLDTMP}/usr/include
E.g. clang does the right thing here.
The -B option
=============
The -B option is supposed to "...[specify] where to find the
executables, libraries, include files, and data files of the compiler
itself". This option is a bit strange, since it is used for finding
both executables (cc1, as, ld), objects (crt*.o) and libraries.
If you run "gcc -print-search-dirs", it gives its defaults:
programs: =/usr/bin/:/usr/bin/:/usr/libexec/:/usr/libexec/:/usr/libexec/
libraries: =/usr/lib/:/usr/lib/
When you add -B${WORLDTMP}/usr/libexec/ (where the cross-tools
built cc1 and cc1plus are), it gives:
programs: =${WORLDTMP}/usr/libexec/:${WORLDTMP}/usr/libexec/:/usr/bin/:/usr/bin/:/usr/libexec/:/usr/libexec/:/usr/libexec/
libraries: =${WORLDTMP}/usr/libexec/:${WORLDTMP}/usr/libexec/:/usr/lib/:/usr/lib/
Thus, the -B path is prepended (why it does it twice, I do not know;
probably a bug), but the defaults are *not* removed, so there is still a
risk of picking up an incorrect executable.
Note the path is also prepended to the libraries path, which is rather
useless; there are never any .o or .a files in a libexec directory. To
fix that path up, you would need to add yet *another* -B option, and you
probably also need yet another -B option to make it find the correct as
and ld. The final command line would then become:
gcc -B${WORLDTMP}/usr/bin/ -B${WORLDTMP}/usr/libexec/ -B${WORLDTMP}/usr/lib/
giving the following search dirs:
programs: =${WORLDTMP}/usr/bin/:${WORLDTMP}/usr/bin/:${WORLDTMP}/usr/libexec/:${WORLDTMP}/usr/libexec/:${WORLDTMP}/usr/lib/:${WORLDTMP}/usr/lib/:/usr/bin/:/usr/bin/:/usr/libexec/:/usr/libexec/:/usr/libexec/
libraries: =${WORLDTMP}/usr/bin/:${WORLDTMP}/usr/bin/:${WORLDTMP}/usr/libexec/:${WORLDTMP}/usr/libexec/:${WORLDTMP}/usr/lib/:${WORLDTMP}/usr/lib/:/usr/lib/:/usr/lib/
Clang also implements the -B option, but it is not additive yet, so
there is no way to specify both the ${WORLDTMP}/usr/bin directory (for
finding its second stage, as and ld), and ${WORLDTMP}/usr/lib (for
finding startup objects and libraries).
This is also the reason clang-bootstrap-isysroot.diff needs to create
symlinks from ${WORLDTMP}/usr/bin/as and ld to ${WORLDTMP}/usr/lib, as
only the latter directory is specified with -B, and it otherwise would
not be able to find the correct as and ld.
The -L option
=============
The -L option just adds the specified directory to the library search
path. It puts them before the built-in paths, but it does not disable
those either. Moreover, the -L paths are *not* used to find the CRT
startup objects:
$ gcc -L${WORLDTMP}/usr/lib -v test.c
[...]
/usr/bin/as -o /tmp/ccZcUXwc.o /tmp/ccYTRRrk.s
/usr/bin/ld --eh-frame-hdr -V -dynamic-linker /libexec/ld-elf.so.1 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L${WORLDTMP}/usr/lib -L/usr/lib -L/usr/lib /tmp/ccZcUXwc.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
The behaviour of clang is the same for this option, so it does not
improve the situation: it is still possible for libraries outside of
${WORLDTMP} to be found.
>> An advantage of method 2) is that you can be 100% sure all built-in
>> search paths of the bootstrap compiler point to directories under
>> ${WORLDTMP}. Of course, a disadvantage is that you have to make some
>> modifications to the compiler source itself.
>
> ... so, which fix to the compiler do you want to make?
My personal preference is method 2), e.g. modify the compiler's
built-in paths, but it is more reasonable to present both methods, and
ask for opinions. Someone may even know another good method. :)
More information about the freebsd-current
mailing list