It is possible to use the GNU configure and build system to build a program which will run on a system which is different from the system on which the tools are built. In other words, it is possible to build programs using a cross compiler.
This is referred to as a Canadian Cross.
Here is an example of a Canadian Cross.
While running on a GNU/Linux, 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.
Of course, you could not run the resulting program on your GNU/Linux system. You would have to copy it over to a Solaris system before you would run it.
Of course, you could also simply build the programs on the Solaris system in the first place. However, perhaps the Solaris system is not available for some reason; perhaps you actually don't 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 configuration machinery on a non-Unix system.
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 section, the build system would be GNU/Linux, and the host system would be Solaris.
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 called the target system. (For a more complete discussion of host and target systems, see section Host and Target).
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.
The name Canadian Cross comes from the case when the build, host, and target systems are all different. At the time that these issues were all being hashed out, Canada had three national political parties.
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 include files for the host system.
When you run `configure', 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 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 Host 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 (i.e., 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.
If you are not using the Cygnus tree, 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 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'.
This section describes configuring and building a Canadian Cross when using the Cygnus tree.
When configuring a Canadian Cross in the Cygnus tree, all the appropriate environment variables are automatically set to `host-tool', where host is the value used for the `--host' option, and tool is the name of the tool (e.g., `gcc', `as', etc.). These tools must be on your `PATH'.
Adding a prefix of host will give the usual name for the build cross host tools. To see this, consider that when these cross tools were built, they were configured to run on the build system and to produce code for the host system. That is, they were configured with a `--target' option that is the same as the system which we are now calling the host. Recall that the default name for installed cross tools uses the target system as a prefix (see section Using the Target Type). Since that is the system which we are now calling the host, host is the right prefix to use.
For example, if you configure with `--build=i386-linux-gnu' and `--host=solaris', then the Cygnus tree will automatically default to using the compiler `solaris-gcc'. You must have previously built and installed this compiler, probably by doing a build with no `--host' option and with a `--target' option of `solaris'.
There are additional considerations if you want to build a cross compiler, rather than a native compiler, in the Cygnus tree using a Canadian Cross.
When you build a cross compiler using the Cygnus tree, then the target libraries will normally be built with the newly built target compiler (see section Host and Target Libraries). However, this will not work when building with a Canadian Cross. This is because the newly built target compiler will be a program which runs on the host system, and therefore will not be able to run on the build system.
Therefore, when building a cross compiler with the Cygnus tree, you must first install a set of build cross target tools. These tools will be used when building the target libraries.
Note that this is not a requirement of a Canadian Cross in general. For example, it would be possible to build just the host cross target tools on the build system, to copy the tools to the host system, and to build the target libraries on the host system. The requirement for build cross target tools is imposed by the Cygnus tree, which expects to be able to build both host programs and target libraries in a single `configure'/`make' step. Because it builds these in a single step, it expects to be able to build the target libraries on the build system, which means that it must use a build cross target toolchain.
For example, suppose you want to build a Windows cross MIPS ELF compiler on a GNU/Linux system. You must have previously installed both a GNU/Linux cross Windows compiler and a GNU/Linux cross MIPS ELF compiler.
In order to build the Windows (configuration name `i386-cygwin32') cross MIPS ELF (configure name `mips-elf') compiler, you might execute the following commands (long command lines are broken across lines with a trailing backslash as a continuation character).
mkdir linux-x-cygwin32 cd linux-x-cygwin32 srcdir/configure --target i386-cygwin32 --prefix=installdir \ --exec-prefix=installdir/H-i386-linux make make install cd .. mkdir linux-x-mips-elf cd linux-x-mips-elf srcdir/configure --target mips-elf --prefix=installdir \ --exec-prefix=installdir/H-i386-linux make make install cd .. mkdir cygwin32-x-mips-elf cd cygwin32-x-mips-elf srcdir/configure --build=i386-linux-gnu --host=i386-cygwin32 \ --target=mips-elf --prefix=wininstalldir \ --exec-prefix=wininstalldir/H-i386-cygwin32 make make install
You would then copy the contents of wininstalldir over to the Windows machine, and run the resulting programs.
If you want to make it possible to build a program you are developing using a Canadian Cross, you must take some care when writing your configure and make rules. Simple cases will normally work correctly. However, it is not hard to write configure and make tests which will fail in a Canadian Cross.
In a `configure.in' file, after calling `AC_PROG_CC', you can find out whether this is a Canadian Cross configure by examining the shell variable `cross_compiling'. In a Canadian Cross, which means that the compiler is a cross compiler, `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 that 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.
When writing tests in `configure.in', you must remember that you want to test the host environment, not the build environment.
Macros like `AC_CHECK_FUNCS' which use the compiler 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 for a Canadian Cross. The main exception is `AC_TRY_RUN'. This macro tries to compile and run a test program. This will fail in a Canadian Cross, 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 in a Canadian Cross. 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 with a Canadian Cross.
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. 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 with a Canadian Cross: 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 with a Canadian Cross; it permits an optional argument indicating the default size, but there is no way to know what the correct default should be.
The main Canadian Cross 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. In the Cygnus tree, this make variable `$(CC_FOR_BUILD)' will hold a compiler for the build system.
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 normally possible to write them in a highly portable fashion so that the absence of `config.h' is not crucial.
The gcc `Makefile.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 build system hackers. Note that the build system compiler is rather confusingly called `HOST_CC'.
Go to the first, previous, next, last section, table of contents.