Summary of changes: sys/boot/common/ufsread.c sys/boot/i386/boot2/Makefile Make sure the boot2 stage is compiled with gcc, as clang has no problems compiling it, but it just gets too big at the moment, even with -Os. This is not applicable to gptboot, though. Also, use a memcpy call instead of a structure assignment in ufsread.c, so the custom memcpy functions defined in boot2.c and gptboot.c are used instead of the compiler built-in. Makefile.inc1 gnu/usr.bin/cc/c++/Makefile gnu/usr.bin/cc/cc/Makefile share/man/man5/src.conf.5 share/mk/bsd.own.mk share/mk/bsd.sys.mk tools/build/options/WITH_CLANG_BOOTSTRAP tools/build/options/WITH_CLANG_IS_CC usr.bin/clang/clang/Makefile Add WITH_CLANG_BOOTSTRAP and WITH_CLANG_IS_CC build options. This still does not set CC and CXX automatically, though. To do so, put the following in /etc/src.conf (the .if stuff is required): # Compile with clang .if !defined(CC) || ${CC} == "cc" CC=clang .endif .if !defined(CXX) || ${CXX} == "c++" CXX=clang++ .endif contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp lib/clang/clang.build.mk Use TOOLS_PREFIX for building clang during the cross-tools stage, to make sure the bootstrap clang does not reference anything outside the $WORLDTMP directory. crypto/openssl/crypto/rc5/rc5.h secure/lib/libcrypto/Makefile.inc If you attempt to compile libcrypto which is currently in head with clang, it will die with the following errors, at least on amd64: /usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/md4/md4_dgst.c:117:2: error: unsupported inline asm: input with type 'unsigned long' matching output with type 'unsigned int' R0(A,B,C,D,X( 0), 3,0); HOST_c2l(data,l); X( 2)=l; ^~~~~~~~~~~~~~~~~~~~~~ This has two causes: those R0() operations are done on an unsigned MD32_REG_T, which is a long by default (even on amd64), and they eventually call a ROTATE macro to rotate-left a 32-bit value: # define ROTATE(a,n) ({ register unsigned int ret; \ asm ( \ "roll %1,%0" \ : "=r"(ret) \ : "I"(n), "0"(a) \ : "cc"); \ ret; \ }) In this case, clang complains that the 'a' argument to the inline assembly is an unsigned long, while the asm instructions refer to unsigned int. If you ask me, clang is right to complain, and gcc should not compile this without at least a hint that it will silently convert the 'a' argument to unsigned int. The clang developers have also made clear they will not support such "arguments of different widths", see http://llvm.org/bugs/show_bug.cgi?id=3373 for more info about that. Now, there are two comments in crypto/openssl/crypto/md32_common.h, where the MD32_REG_T macro is defined; the first says: "In case you wonder why A-D are declared as long and not as MD5_LONG. Doing so results in slight performance boost on LP64 architectures. The catch is we don't really care if 32 MSBs of a 64-bit register get polluted with eventual overflows as we *save* only 32 LSBs in *either* case. Now declaring 'em long excuses the compiler from keeping 32 MSBs zeroed resulting in 13% performance improvement under SPARC Solaris7/64 and 5% under AlphaLinux. Well, to be honest it should say that this *prevents* performance degradation." However, the next comment reverses this opinion again for gcc on amd64: "Apparently there're LP64 compilers that generate better code if A-D are declared int. Most notably GCC-x86_64 generates better code." So, the most logical fix seems to define MD32_REG_T as int instead, which can be done via secure/lib/libcrypto/Makefile.inc. The same reasoning applies to the definition of RC5_32_INT as 'unsigned long' in crypto/openssl/crypto/rc5/rc5.h; in case of amd64, just use 'unsigned int' instead. Though MD32_REG_T is only used internally, RC5_32_INT is unfortunately member of the RC5_32_KEY struct in crypto/openssl/crypto/rc5/rc5.h, so these changes would change the ABI. This should not be too much of a problem for -current, I assume. As an additional note on this, it looks like FreeBSD has been using non-standard settings compared to upstream OpenSSL, as the original Configure script has this line for BSD on x86_64: "BSD-x86_64", "gcc:-DL_ENDIAN -DTERMIOS -O3 -DMD32_REG_T=int -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)" E.g. upstream is already using int for MD32_REG_T. RC5_32_INT is still unconditionally an unsigned long, though, even in OpenSSL 1.0.0. sys/boot/i386/loader/Makefile Change -lstand to ${LIBSTAND}. On amd64, libstand.a is compiled for i386, but is still installed under ${WORLDTMP}/usr/lib instead of ${WORLDTMP}/usr/lib32. Even if it would be installed there, ld on amd64 is set up incorrectly with a ${TOOLS_PREFIX}/usr/lib/i386 default path, so it wouldn't link. The reason it does link under gcc is that gcc passes -L${WORLDTMP}/usr/lib twice, even for -m32 builds, which is also incorrect, but accidentally works in this case. contrib/libstdc++/include/ext/bitmap_allocator.h contrib/libstdc++/include/ext/ropeimpl.h contrib/libstdc++/src/locale-inst.cc Make clang compile libstdc++: - Several private typedefs must be made public to be accessed - In some cases template keywords must be inserted to treat classes as dependent template names - Remove two 'inline' keywords where they do not make sense gnu/lib/libobjc/Makefile Make sure libobjc is compiled with gcc, as clang currently cannot compile it, and the Makefile does some '--print-prog-name' magic to retrieve the objc runtime info, which clang does not support. gnu/lib/libgcc/Makefile Add -fheinous-gnu-extensions to CFLAGS, if bootstrapping with clang, otherwise it will complain about the "heinous" inline asm and die. lib/libc/i386/gen/Makefile.inc lib/libc/i386/gen/ldexp.S Provide an assembly implementation of ldexp() for i386, to work around LLVM PR 879 without compiling all of libc with gcc instead. sys/conf/kern.mk sys/conf/kern.pre.mk sys/conf/kmod.mk sys/modules/Makefile Make sure clang does not complain about gcc-specific options, and point out that it does not support profiling at the moment. Also, disable compilation of the ce(4) module, since it uses unsupported inline assembly, but seems to be heavily obfuscated source code, so almost impossible to fix properly.