From a09aff83430037d0e6b23437d7e317cb55e322ee Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Wed, 15 May 2013 14:30:03 +0000 Subject: [PATCH] Add support for an external cross compiler. The cross compiler is specified by passing the XCC, XCXX, and XCPP variables (corresponding to CC, CXX, and CPP) to buildworld/buildkernel. The compiler must be clang or be configured to target the appropriate architecture. To speed build times, if XCC is an absolute path or WITHOUT_CROSS_COMPILER is defined then no cross compiler will be built during the cross-tools stage. Limited documentation of this feature can currently be found at: https://wiki.freebsd.org/ExternalToolchain This functionality should be considered experimental and is subject to change without notice. Sponsored by: DARPA, AFRL Discussed with: imp, sjg --- Makefile.inc1 | 69 ++++++++++++++++++++-- share/mk/bsd.own.mk | 1 + tools/build/options/WITHOUT_CROSS_COMPILER | 3 + 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 tools/build/options/WITHOUT_CROSS_COMPILER diff --git a/Makefile.inc1 b/Makefile.inc1 index baf697692b55..cd84d1e66b25 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -273,15 +273,67 @@ WMAKEENV= ${CROSSENV} \ .if ${MK_CDDL} == "no" WMAKEENV+= NO_CTF=1 .endif -.if ${CC:T:Mgcc} == "gcc" + +.if defined(CROSS_TOOLCHAIN_PREFIX) +CROSS_COMPILER_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} +CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} +.endif +XCOMPILERS= CC CXX CPP +.for COMPILER in ${XCOMPILERS} +.if defined(CROSS_COMPILER_PREFIX) +X${COMPILER}?= ${CROSS_COMPILER_PREFIX}${${COMPILER}} +.else +X${COMPILER}?= ${${COMPILER}} +.endif +.endfor +XBINUTILS= AS AR LD NM OBJDUMP RANLIB STRINGS +.for BINUTIL in ${XBINUTILS} +.if defined(CROSS_BINUTILS_PREFIX) +X${BINUTIL}?= ${CROSS_BINUTILS_PREFIX}${${BINUTIL}} +.else +X${BINUTIL}?= ${${BINUTIL}} +.endif +.endfor +WMAKEENV+= CC="${XCC} ${XFLAGS}" CXX="${XCXX} ${XFLAGS}" \ + CPP="${XCPP} ${XFLAGS}" \ + AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \ + OBJDUMP=${XOBJDUMP} RANLIB=${XRANLIB} STRINGS=${XSTRINGS} + +.if ${XCC:T:Mgcc} == "gcc" WMAKE_COMPILER_TYPE= gcc -.elif ${CC:T:Mclang} == "clang" +.elif ${XCC:T:Mclang} == "clang" WMAKE_COMPILER_TYPE= clang .elif ${MK_CLANG_IS_CC} == "no" WMAKE_COMPILER_TYPE= gcc .else WMAKE_COMPILER_TYPE= clang .endif +IMAKE_COMPILER_TYPE= COMPILER_TYPE=${WMAKE_COMPILER_TYPE} + +.if ${XCC:M/*} +XFLAGS= --sysroot=${WORLDTMP} +.if defined(CROSS_BINUTILS_PREFIX) +# In the case of xdev-build tools, CROSS_BINUTILS_PREFIX won't be a +# directory, but the compiler will look in the right place for it's +# tools so we don't need to tell it where to look. +.if exists(${CROSS_BINUTILS_PREFIX}) +XFLAGS+= -B${CROSS_BINUTILS_PREFIX} +.endif +.else +XFLAGS+= -B${WORLDTMP}/usr/bin +.endif +.if ${TARGET_ARCH} != ${MACHINE_ARCH} && ${WMAKE_COMPILER_TYPE} == "clang" +.if (${TARGET_ARCH} == "arm" || ${TARGET_ARCH} == "armv6") && \ +${MK_ARM_EABI} != "no" +TARGET_ABI= gnueabi +.else +TARGET_ABI= unknown +.endif +TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd10.0 +XFLAGS+= -target ${TARGET_TRIPLE} +.endif +.endif + WMAKEENV+= COMPILER_TYPE=${WMAKE_COMPILER_TYPE} WMAKE= ${WMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 DESTDIR=${WORLDTMP} @@ -314,6 +366,7 @@ LIB32WMAKEFLAGS= \ LIB32FLAGS= -m32 ${LIB32CPUFLAGS} -DCOMPAT_32BIT \ + --sysroot=${WORLDTMP} \ -isystem ${LIB32TMP}/usr/include/ \ -L${LIB32TMP}/usr/lib32 \ -B${LIB32TMP}/usr/lib32 @@ -329,8 +382,8 @@ LIB32WMAKEENV+= MAKEOBJDIRPREFIX=${OBJTREE}/lib32 \ SHLIBDIR=/usr/lib32 \ COMPILER_TYPE=${WMAKE_COMPILER_TYPE} LIB32WMAKEFLAGS+= \ - CC="${CC} ${LIB32FLAGS}" \ - CXX="${CXX} ${LIB32FLAGS}" \ + CC="${XCC} ${LIB32FLAGS}" \ + CXX="${XCXX} ${LIB32FLAGS}" \ DESTDIR=${LIB32TMP} \ -DCOMPAT_32BIT \ -DLIBRARIES_ONLY \ @@ -346,7 +399,7 @@ LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} -DNO_INCS \ IMAKEENV= ${CROSSENV:N_LDSCRIPTROOT=*} IMAKE= ${IMAKEENV} ${MAKE} -f Makefile.inc1 \ - ${IMAKE_INSTALL} ${IMAKE_MTREE} + ${IMAKE_INSTALL} ${IMAKE_MTREE} ${IMAKE_COMPILER_TYPE} .if empty(.MAKEFLAGS:M-n) IMAKEENV+= PATH=${STRICTTMPPATH}:${INSTALLTMP} \ LD_LIBRARY_PATH=${INSTALLTMP} \ @@ -1279,10 +1332,13 @@ _kgzip= usr.sbin/kgzip .endif .endif -.if ${MK_BINUTILS} != "no" +.if ${XAS:M/*} == "" && ${MK_BINUTILS} != "no" _binutils= gnu/usr.bin/binutils .endif +# If an full path to an external cross compiler is given, don't build +# a cross compiler. +.if ${XCC:M/*} == "" && ${MK_CROSS_COMPILER} != "no" .if ${MK_CLANG} != "no" && (${MK_CLANG_IS_CC} != "no" || ${CC:T:Mclang} == "clang") _clang= usr.bin/clang _clang_libs= lib/clang @@ -1291,6 +1347,7 @@ _clang_libs= lib/clang .if ${MK_GCC} != "no" && (${MK_CLANG_IS_CC} == "no" || ${TARGET} == "pc98") _cc= gnu/usr.bin/cc .endif +.endif cross-tools: .for _tool in \ diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 3565425086f1..e74000aa17ff 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -259,6 +259,7 @@ __DEFAULT_YES_OPTIONS = \ CAPSICUM \ CDDL \ CPP \ + CROSS_COMPILER \ CRYPT \ CTM \ CVS \ diff --git a/tools/build/options/WITHOUT_CROSS_COMPILER b/tools/build/options/WITHOUT_CROSS_COMPILER new file mode 100644 index 000000000000..1ded25b06573 --- /dev/null +++ b/tools/build/options/WITHOUT_CROSS_COMPILER @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Set to not build a cross compiler in the cross-tools stage of +buildworld, buildkernel, etc.