Date: Tue, 17 Aug 2010 15:21:52 +0200 From: Dimitry Andric <dimitry@andric.com> To: Bob Bishop <rb@gid.co.uk> Cc: current@freebsd.org Subject: Re: Building world with clang Message-ID: <4C6A8CF0.8000002@andric.com> In-Reply-To: <19F5467B-6432-4531-BF04-62D8EB4F3093@gid.co.uk> References: <4C6A7357.8000606@andric.com> <19F5467B-6432-4531-BF04-62D8EB4F3093@gid.co.uk>
next in thread | previous in thread | raw e-mail | index | archive | help
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. :)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C6A8CF0.8000002>