[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4 Building with a Cross Compiler

It is possible to build a program which uses GNU Autotools on one system and to run it on a different type of system. In other words, it is possible to build programs using a cross compiler. In this section, we explain what this means, how to build programs this way, and how to write your ‘configure’ scripts to support it. Building a program on one system and running it on another is sometimes referred to as a Canadian Cross(69).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.1 Canadian Cross Example

We’ll start with an example of a Canadian Cross, to make sure that the concepts are clear. Using a GNU/Linux system, you can build a program which will run on a Solaris system. You would use a GNU/Linux cross Solaris compiler to build the program. You could not run the resulting programs on your GNU/Linux system. After all, they are Solaris programs. Instead, you would have to copy the result over to a Solaris system before you could run it.

Naturally, you could simply build the program on the Solaris system in the first place. However, perhaps the Solaris system is not available for some reason; perhaps you don’t actually have one, but you want to build the tools for somebody else to use. Or perhaps your GNU/Linux system is much faster than your Solaris system.

A Canadian Cross build is most frequently used when building programs to run on a non-Unix system, such as DOS or Windows. It may be simpler to configure and build on a Unix system than to support the GNU Autotools tools on a non-Unix system.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.2 Canadian Cross Concepts

When building a Canadian Cross, there are at least two different systems involved: the system on which the tools are being built, and the system on which the tools will run. The system on which the tools are being built is called the build system. The system on which the tools will run is called the host system. For example, if you are building a Solaris program on a GNU/Linux system, as in the previous example, the build system would be GNU/Linux, and the host system would be Solaris.

Note that we already discussed the host system above; see Host and Target. It is, of course, possible to build a cross compiler using a Canadian Cross (i.e., build a cross compiler using a cross compiler). In this case, the system for which the resulting cross compiler generates code is the target system.

An example of building a cross compiler using a Canadian Cross would be building a Windows cross MIPS ELF compiler on a GNU/Linux system. In this case the build system would be GNU/Linux, the host system would be Windows, and the target system would be MIPS ELF.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.3 Build Cross Host Tools

In order to configure a program for a Canadian Cross build, you must first build and install the set of cross tools you will use to build the program. These tools will be build cross host tools. That is, they will run on the build system, and will produce code that runs on the host system. It is easy to confuse the meaning of build and host here. Always remember that the build system is where you are doing the build, and the host system is where the resulting program will run. Therefore, you need a build cross host compiler.

In general, you must have a complete cross environment in order to do the build. This normally means a cross compiler, cross assembler, and so forth, as well as libraries and header files for the host system. Setting up a complete cross environment can be complex, and is beyond the scope of this book. You may be able to get more information from the ‘crossgcc’ mailing list and FAQ; see http://www.objsw.com/CrossGCC/.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.4 Build and Host Options

When you run ‘configure’ for a Canadian Cross, you must use both the ‘--build’ and ‘--host’ options. The ‘--build’ option is used to specify the configuration name of the build system. This can normally be the result of running the ‘config.guess’ shell script, and when using a Unix shell it is reasonable to use ‘--build=`config.guess`’. The ‘--host’ option is used to specify the configuration name of the host system.

As we explained earlier, ‘config.guess’ is used to set the default value for the ‘--host’ option (see section Using the Target Type). We can now see that since ‘config.guess’ returns the type of system on which it is run, it really identifies the build system. Since the host system is normally the same as the build system (or, in other words, people do not normally build using a cross compiler), it is reasonable to use the result of ‘config.guess’ as the default for the host system when the ‘--host’ option is not used.

It might seem that if the ‘--host’ option were used without the ‘--build’ option that the ‘configure’ script could run ‘config.guess’ to determine the build system, and presume a Canadian Cross if the result of ‘config.guess’ differed from the ‘--host’ option. However, for historical reasons, some configure scripts are routinely run using an explicit ‘--host’ option, rather than using the default from ‘config.guess’. As noted earlier, it is difficult or impossible to reliably compare configuration names (see section Using the Target Type). Therefore, by convention, if the ‘--host’ option is used, but the ‘--build’ option is not used, then the build system defaults to the host system. (This convention may be changing in the Autoconf 2.5 release. Check the release notes.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.5 Canadian Cross Tools

You must explicitly specify the cross tools which you want to use to build the program. This is done by setting environment variables before running the ‘configure’ script. You must normally set at least the environment variables ‘CC’, ‘AR’, and ‘RANLIB’ to the cross tools which you want to use to build. For some programs, you must set additional cross tools as well, such as ‘AS’, ‘LD’, or ‘NM’. You would set these environment variables to the build cross host tools which you are going to use.

For example, if you are building a Solaris program on a GNU/Linux system, and your GNU/Linux cross Solaris compiler were named ‘solaris-gcc’, then you would set the environment variable ‘CC’ to ‘solaris-gcc’.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.6 Supporting Building with a Cross Compiler

If you want to make it possible to build a program which you are developing using a cross compiler, you must take some care when writing your ‘configure.in’ and make rules. Simple cases will normally work correctly. However, it is not hard to write configure tests which will fail when building with a cross compiler, so some care is required to avoid this.

You should write your ‘configure’ scripts to support building with a cross compiler if you can, because that will permit others to build your program on a fast compilation server.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.6.1 Supporting Building with a Cross Compiler in Configure Scripts

In a ‘configure.in’ file, after calling ‘AC_PROG_CC’, you can find out whether the program is being built by a cross compiler by examining the shell variable ‘cross_compiling’. If the compiler is a cross compiler, which means that this is a Canadian Cross, ‘cross_compiling’ will be ‘yes’. In a normal configuration, ‘cross_compiling’ will be ‘no’.

You ordinarily do not need to know the type of the build system in a ‘configure’ script. However, if you do need that information, you can get it by using the macro ‘AC_CANONICAL_SYSTEM’, the same macro which is used to determine the target system. This macro will set the variables ‘build’, ‘build_alias’, ‘build_cpu’, ‘build_vendor’, and ‘build_os’, which correspond to the similar ‘target’ and ‘host’ variables, except that they describe the build system. See section Using the Target Type.

When writing tests in ‘configure.in’, you must remember that you want to test the host environment, not the build environment. Macros which use the compiler, such as like ‘AC_CHECK_FUNCS’, will test the host environment. That is because the tests will be done by running the compiler, which is actually a build cross host compiler. If the compiler can find the function, that means that the function is present in the host environment.

Tests like ‘test -f /dev/ptyp0’, on the other hand, will test the build environment. Remember that the ‘configure’ script is running on the build system, not the host system. If your ‘configure’ scripts examines files, those files will be on the build system. Whatever you determine based on those files may or may not be the case on the host system.

Most Autoconf macros will work correctly when building with a cross compiler. The main exception is ‘AC_TRY_RUN’. This macro tries to compile and run a test program. This will fail when building with a cross compiler, because the program will be compiled for the host system, which means that it will not run on the build system.

The ‘AC_TRY_RUN’ macro provides an optional argument to tell the ‘configure’ script what to do when building with a cross compiler. If that argument is not present, you will get a warning when you run ‘autoconf’:

 
warning: AC_TRY_RUN called without default to allow cross compiling

This tells you that the resulting ‘configure’ script will not work when building with a cross compiler.

In some cases while it may better to perform a test at configure time, it is also possible to perform the test at run time (see section Testing system features at application runtime). In such a case you can use the cross compiling argument to ‘AC_TRY_RUN’ to tell your program that the test could not be performed at configure time.

There are a few other autoconf macros which will not work correctly when building with a cross compiler: a partial list is ‘AC_FUNC_GETPGRP’, ‘AC_FUNC_SETPGRP’, ‘AC_FUNC_SETVBUF_REVERSED’, and ‘AC_SYS_RESTARTABLE_SYSCALLS’. The ‘AC_CHECK_SIZEOF’ macro is generally not very useful when building with a cross compiler; it permits an optional argument indicating the default size, but there is no way to know what the correct default should be.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

26.4.6.2 Supporting Building with a Cross Compiler in Makefiles

The main cross compiling issue in a ‘Makefile’ arises when you want to use a subsidiary program to generate code or data which you will then include in your real program. If you compile this subsidiary program using ‘$(CC)’ in the usual way, you will not be able to run it. This is because ‘$(CC)’ will build a program for the host system, but the program is being built on the build system. You must instead use a compiler for the build system, rather than the host system. This compiler is conventionally called ‘$(CC_FOR_BUILD)’.

A ‘configure’ script should normally permit the user to define ‘CC_FOR_BUILD’ explicitly in the environment. Your configure script should help by selecting a reasonable default value. If the ‘configure’ script is not being run with a cross compiler (i.e., the ‘cross_compiling’ shell variable is ‘no’ after calling ‘AC_PROG_CC’), then the proper default for ‘CC_FOR_BUILD’ is simply ‘$(CC)’. Otherwise, a reasonable default is simply ‘cc’.

Note that you should not include ‘config.h’ in a file you are compiling with ‘$(CC_FOR_BUILD)’. The ‘configure’ script will build ‘config.h’ with information for the host system. However, you are compiling the file using a compiler for the build system (a native compiler). Subsidiary programs are normally simple filters which do no user interaction, and it is often possible to write them in a highly portable fashion so that the absence of ‘config.h’ is not crucial.

The gccMakefile.in’ shows a complex situation in which certain files, such as ‘rtl.c’, must be compiled into both subsidiary programs run on the build system and into the final program. This approach may be of interest for advanced GNU Autotools hackers. Note that, at least in GCC 2.95, the build system compiler is rather confusingly called ‘HOST_CC’.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by Ben Elliston on July 10, 2015 using texi2html 1.82.