Cross-compilation in pkgsrc (developer's guide) -*- outline -*- Taylor R. Campbell $NetBSD: HOWTO-dev-crosscompile,v 1.7 2024/04/12 19:54:43 riastradh Exp $ These are some notes on how to make your package cross-compilable. There is no single recipe for it -- each package is different, and even if it follows, say, the GNU build system conventions, it may have its quirks, and the author of the software you're packaging may not have ever thought of cross-compilation. * Native and target platform When building a package, MACHINE_ARCH, OPSYS, &c., describe the platform for which the package is being built. If USE_CROSS_COMPILE=no, this is the native platform; otherwise, if USE_CROSS_COMPILE=yes, it is the target platform. The additional variables NATIVE_MACHINE_ARCH, NATIVE_OPSYS, &c., always describe the native platform. When building a native package for cross-compilation, such as a compiler for the target, the variables TARGET_MACHINE_ARCH, TARGET_OPSYS, &c., describe the target platform. If the build product varies with the choice of target, then TARGET_MACHINE_ARCH or TARGET_OPSYS or whatever affects it should be embedded into the PKGNAME somewhere so that the different build products are distinguished by having different package names. XXX Missing: XXX - TARGET_MACHINE_GNU_PLATFORM XXX - TARGET_MACHINE_GNU_ARCH XXX - probably other variables defined in terms of the CROSSVARS * Specifying the toolchain The following build systems should automagically handle cross-compilation by passing through the architecture and OS information: - GNU_CONFIGURE=yes - .include "../../devel/meson/build.mk" (sets - .include "../../devel/cmake/build.mk" (and legacy USE_CMAKE=yes) Additional tweaks are sometimes needed (but not always), conditional on ${USE_CROSS_COMPILE:tl} == "yes" (after including bsd.prefs.mk): - (pkg-config) ALL_ENV+= PKG_CONFIG_SYSROOT_DIR=${CROSS_DESTDIR:Q} - (pkg-config) ALL_ENV+= PKG_CONFIG_FDO_SYSROOT_RULES=1 - (cmake) CMAKE_ARGS+= -DCMAKE_SYSROOT:STRING=${CROSS_DESTDIR:Q} * Tool dependencies If the process of building your package requires running programs, loading libraries, using data, &c., from a native package, the native package is a tool dependency, not (necessarily) a build dependency or a normal dependency. For example, if building your package entails transforming some XML with XSLT, you might add: TOOL_DEPENDS+= libxslt>=1.1.0:../../textproc/libxslt If you need to refer to the full pathname of a file in a package installed with TOOL_DEPENDS, it will generally be relative to TOOLBASE rather than LOCALBASE. For example: XSLTPROC= ${TOOLBASE}/bin/xsltproc post-build: cd ${WRKSRC}/xmlstuff && ${XSLTPROC} ... * Native C and C++ compilers Some software wants build tools written in C and C++ and then execute them natively at build-time. Your package probably does this if when you try to cross-compile it, it fails with: sh: Cannot execute ELF binary ./foobar Sometimes configure scripts or makefiles accept a variable named CC_FOR_BUILD or similar to build these tools. In that case, you can pass in the pkgsrc make variables NATIVE_CC and friends: .include "../../mk/bsd.prefs.mk" .if ${USE_CROSS_COMPILE:U:tl} == "yes" CONFIGURE_ENV+= CC_FOR_BUILD=${NATIVE_CC:Q} CONFIGURE_ENV+= CXX_FOR_BUILD=${NATIVE_CXX:Q} CONFIGURE_ENV+= LD_FOR_BUILD=${NATIVE_LD:Q} .endif If the software doesn't use CC_FOR_BUILD, it may still be easy to find the makefile rules that invoke $(CC) or $(LD) to build native tools and patch them to replace that by $(CC_FOR_BUILD) and $(LD_FOR_BUILD). XXX The mechanism here is currently pretty kludgey; there is little principle to these NATIVE_CC/CXX/LD variables and they should be better rationalized. If you want a native Fortran compiler, for instance, you'll have to hack it yourself. * Configure-time run-tests There's a lot of autoconf-configured software out there that uses run-tests to learn about the environment, which doesn't work so well in cross-builds. Your package probably uses this if it when you try to cross-compile it, it fails with: configure: error: cannot run test programs while cross-compiling or configure: error: cannot check for file existence when cross-compiling Some of these can be patched to be replaced by compile-tests. Otherwise, for a particular known target environment, you can pre-answer the tests for autoconf: .include "../../bsd.prefs.mk" .if ${USE_CROSS_COMPILE:tl} == "yes" # Configure wants to check for /dev/random but can't. We know NetBSD # always has a /dev/random, so inform autoconf of the fact. CONFIGURE_ENV.NetBSD+= ac_cv_file__dev_random=yes .endif