Date: Tue, 17 Aug 2010 13:32:39 +0200 From: Dimitry Andric <dimitry@andric.com> To: current@freebsd.org Subject: Building world with clang Message-ID: <4C6A7357.8000606@andric.com>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------090709090403060100020802 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi, Since clang has gone into the tree, there has been an effort to get head in a state where world can optionally be built with it. A number of changes required for this have already been committed, mainly thanks to Ed Schouten, Roman Divacky and Rui Paulo. Most of these changes were adapted from the clangbsd project branch. There are several other changes in the queue, pending review and/or further enhancement, but I would like to solicit your comments about one particular set: the changes required to let buildworld use clang as the compiler. Probably the most logical way to specify that you want world built with clang, is to put CC=clang and CXX=clang++ in /etc/src.conf. Any necessary modifications to Makefile.inc1 or bsd.*.mk can then be put between conditionals like: .if ${CC:T:Mclang} == "clang" [...stuff specific to clang...] .endif so nothing will change for non-clang builds. Now, for building clang as the bootstrap compiler, there are basically two methods to make it use the correct headers, C startup objects, and libraries from the object tree (${WORLDTMP}): 1) The "isysroot" method: build a regular version of clang, and make sure WMAKEENV contains something like: CC="${CC} -isysroot ${WORLDTMP} -B${WORLDTMP}/usr/lib/ \ -L${WORLDTMP}/usr/lib/" 2) The "tools-prefix" method: build a special version of clang, that has its default search paths for headers, startup objects and libraries modified, to look for everything under ${WORLDTMP}. Method 1) is used in the clangbsd project branch. Method 2) is similar to what is used for building the in-tree gcc as the bootstrap compiler. During the cross-tools stage, TOOLS_PREFIX is defined to point at ${WORLDTMP}, and the bootstrap gcc's built-in search paths get prefixed with it. An advantage of method 1) is that it does not require any modifications to the compiler, and basically just a few extra command line arguments. The same method could probably even be made to work for gcc. 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, so there is still a chance that headers, objects or libraries outside of ${WORLDTMP} will be picked up during the world stage. 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. I would like to hear your opinions about which method is preferred, or if there may be another good way to solve the bootstrap compiler issue. I have also attached two patches to this mail, which can be applied to head, to show the exact set of changes required for each method. --------------090709090403060100020802 Content-Type: text/plain; name="clang-bootstrap-isysroot.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="clang-bootstrap-isysroot.diff" The "isysroot" method for building world with clang. First of all, Makefile.inc1 is modified to build the clang libraries and binaries during the cross-tools stage, iff CC=clang. We basically adjust WMAKEENV, which applies to the world stage, and LIB32FLAGS, which optionally applies to 32-bit world stage, to add -isysroot, -B and -L options, so the compiler looks under ${WORLDTMP} for its headers, startup objects and libraries. We also need to create symlinks from ${WORLDTMP}/usr/bin/as and ld to ${WORLDTMP}/usr/lib, since the -B option in clang is not additive, and is used both for finding CRT startup objects and for finding the assembler and linker. diff --git a/Makefile.inc1 b/Makefile.inc1 index d2581c5..c31eba9 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -257,6 +257,10 @@ WMAKEENV= ${CROSSENV} \ VERSION="${VERSION}" \ INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${TMPPATH} +.if ${CC:T:Mclang} == "clang" +WMAKEENV+= CC="${CC} -isysroot ${WORLDTMP} -B${WORLDTMP}/usr/lib/ -L${WORLDTMP}/usr/lib/" \ + CXX="${CXX} -isysroot ${WORLDTMP} -B${WORLDTMP}/usr/lib/ -L${WORLDTMP}/usr/lib/" +.endif .if ${MK_CDDL} == "no" WMAKEENV+= NO_CTF=1 .endif @@ -289,8 +293,11 @@ LIB32WMAKEENV= MACHINE=powerpc MACHINE_ARCH=powerpc \ .endif -LIB32FLAGS= -m32 ${LIB32CPUFLAGS} -DCOMPAT_32BIT \ - -isystem ${LIB32TMP}/usr/include/ \ +LIB32FLAGS= -m32 ${LIB32CPUFLAGS} -DCOMPAT_32BIT +.if ${CC:T:Mclang} == "clang" +LIB32FLAGS+= -isysroot ${LIB32TMP}/ +.endif +LIB32FLAGS+= -isystem ${LIB32TMP}/usr/include/ \ -L${LIB32TMP}/usr/lib32 \ -B${LIB32TMP}/usr/lib32 @@ -440,6 +447,11 @@ everything: @echo "--------------------------------------------------------------" @echo ">>> stage 4.4: building everything" @echo "--------------------------------------------------------------" +.if ${CC:T:Mclang} == "clang" + # mergemaster goes through this but those files do not exist + [ ! -e ${WORLDTMP}/usr/bin/as ] || ln -sf ${WORLDTMP}/usr/bin/as ${WORLDTMP}/usr/lib/as + [ ! -e ${WORLDTMP}/usr/bin/ld ] || ln -sf ${WORLDTMP}/usr/bin/ld ${WORLDTMP}/usr/lib/ld +.endif ${_+_}cd ${.CURDIR}; ${WMAKE} par-all .if defined(LIB32TMP) build32: @@ -453,6 +465,12 @@ build32: mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${LIB32TMP}/usr/include >/dev/null mkdir -p ${WORLDTMP} +.if ${CC:T:Mclang} == "clang" + # relink /usr/bin/{as,ld} to the lib32 tmp so the -B can pick up + # the /usr/bin/ld and /usr/bin/as + ln -sf ${WORLDTMP}/usr/bin/as ${LIB32TMP}/usr/lib32/as + ln -sf ${WORLDTMP}/usr/bin/ld ${LIB32TMP}/usr/lib32/ld +.endif ln -sf ${.CURDIR}/sys ${WORLDTMP} .if ${MK_KERBEROS} != "no" .for _t in obj depend all @@ -1078,8 +1096,15 @@ _kgzip= usr.sbin/kgzip .endif .endif +.if ${CC:T:Mclang} == "clang" +_clang= usr.bin/clang +_clang_libs= lib/clang +.endif + cross-tools: .for _tool in \ + ${_clang_libs} \ + ${_clang} \ gnu/usr.bin/binutils \ gnu/usr.bin/cc \ usr.bin/xlint/lint1 usr.bin/xlint/lint2 usr.bin/xlint/xlint \ --------------090709090403060100020802 Content-Type: text/plain; name="clang-bootstrap-tools-prefix.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="clang-bootstrap-tools-prefix.diff" The "tools-prefix" method for building world with clang. First of all, Makefile.inc1 is modified to build the clang libraries and binaries during the cross-tools stage, iff CC=clang. The lib/clang/clang.build.mk file, which contains common build settings for all llvm and clang sources, is modified to add a CLANG_PREFIX macro to CFLAGS, iff TOOLS_PREFIX is defined. In the clang sources, the files that define the built-in search paths for headers, startup objects and libraries, are modified to use the (optional) CLANG_PREFIX macro as prefix for all those paths. diff --git a/Makefile.inc1 b/Makefile.inc1 index d2581c5..6e58396 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1078,8 +1078,15 @@ _kgzip= usr.sbin/kgzip .endif .endif +.if ${CC:T:Mclang} == "clang" +_clang= usr.bin/clang +_clang_libs= lib/clang +.endif + cross-tools: .for _tool in \ + ${_clang_libs} \ + ${_clang} \ gnu/usr.bin/binutils \ gnu/usr.bin/cc \ usr.bin/xlint/lint1 usr.bin/xlint/lint2 usr.bin/xlint/xlint \ diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp index a78d153..3506590 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp @@ -26,6 +26,10 @@ #include <cstdlib> // ::getenv +#ifndef CLANG_PREFIX +#define CLANG_PREFIX +#endif + using namespace clang::driver; using namespace clang::driver::toolchains; @@ -869,11 +873,9 @@ FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32) getProgramPaths().push_back(getDriver().Dir + "/../libexec"); getProgramPaths().push_back("/usr/libexec"); if (Lib32) { - getFilePaths().push_back(getDriver().Dir + "/../lib32"); - getFilePaths().push_back("/usr/lib32"); + getFilePaths().push_back(CLANG_PREFIX "/usr/lib32"); } else { - getFilePaths().push_back(getDriver().Dir + "/../lib"); - getFilePaths().push_back("/usr/lib"); + getFilePaths().push_back(CLANG_PREFIX "/usr/lib"); } } diff --git a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp index fcfee71..9187148 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp @@ -30,6 +30,9 @@ #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> #endif +#ifndef CLANG_PREFIX +#define CLANG_PREFIX +#endif using namespace clang; using namespace clang::frontend; @@ -408,9 +411,10 @@ static bool getWindowsSDKDir(std::string &path) { void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { -#if 0 /* Remove unneeded include paths. */ // FIXME: temporary hack: hard-coded paths. - AddPath("/usr/local/include", System, true, false, false); +#ifndef __FreeBSD__ + AddPath(CLANG_PREFIX "/usr/local/include", System, true, false, false); +#endif // Builtin includes use #include_next directives and should be positioned // just prior C include dirs. @@ -421,7 +425,6 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, P.appendComponent("include"); AddPath(P.str(), System, false, false, false, /*IgnoreSysRoot=*/ true); } -#endif // Add dirs specified via 'configure --with-c-include-dirs'. llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS); @@ -518,13 +521,15 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, case llvm::Triple::MinGW32: AddPath("c:/mingw/include", System, true, false, false); break; + case llvm::Triple::FreeBSD: + AddPath(CLANG_PREFIX "/usr/include/clang/" CLANG_VERSION_STRING, + System, false, false, false); + break; default: break; } - AddPath("/usr/include/clang/" CLANG_VERSION_STRING, - System, false, false, false); - AddPath("/usr/include", System, false, false, false); + AddPath(CLANG_PREFIX "/usr/include", System, false, false, false); } void InitHeaderSearch:: @@ -726,8 +731,10 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) { case llvm::Triple::FreeBSD: // FreeBSD 8.0 // FreeBSD 7.3 - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple); - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2/backward", "", "", "", triple); + AddGnuCPlusPlusIncludePaths(CLANG_PREFIX "/usr/include/c++/4.2", + "", "", "", triple); + AddGnuCPlusPlusIncludePaths(CLANG_PREFIX "/usr/include/c++/4.2/backward", + "", "", "", triple); break; case llvm::Triple::Minix: AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", diff --git a/lib/clang/clang.build.mk b/lib/clang/clang.build.mk index 6351eda..86384db 100644 --- a/lib/clang/clang.build.mk +++ b/lib/clang/clang.build.mk @@ -28,6 +28,10 @@ LLVM_REQUIRES_RTTI= CFLAGS+=-fno-rtti .endif +.ifdef TOOLS_PREFIX +CFLAGS+=-DCLANG_PREFIX=\"${TOOLS_PREFIX}\" +.endif + .PATH: ${LLVM_SRCS}/${SRCDIR} TBLGEN=tblgen ${CFLAGS:M-I*} --------------090709090403060100020802--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C6A7357.8000606>