Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.






(C++) How to cross-compile a Qt Creator project from Ubuntu to a windows executable: example 11: any application, use of GCC


This is example 10, and perhaps a viable solutions of answering the Qt FAQ How to cross-compile a Qt Creator project from Ubuntu to a windows executable?, which follows [1].














Project information


Operating system: Ubuntu 10.04 LTS Lucid Lynx

IDE: Qt Creator 2.0.0

Project type: GUI application

Compiler: G++ 4.4.1

Libraries used:






Qt project file


# Project created by QtCreator 2010-09-25T09:43:28
QT       += core
QT       -= gui
LIBS += -L/usr/local/lib -lboost_filesystem
TARGET = CppQtCrosscompileToWindowsExample5
CONFIG   += console
CONFIG   -= app_bundle
SOURCES += main.cpp








///cross-compiling a console application with
///a library (that is: boost_filesystem).
#include <iostream>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
//From http://www.richelbilderbeek.nl/CppGetFilesInFolder.htm
const std::vector<std::string> GetFilesInFolder(const std::string& folder)
  std::vector<std::string> v;

  const boost::filesystem::path my_folder
    = boost::filesystem::system_complete(

  if (!boost::filesystem::is_directory(my_folder)) return v;

  const boost::filesystem::directory_iterator j;
  for ( boost::filesystem::directory_iterator i(my_folder);
        i != j;
    if ( boost::filesystem::is_regular_file( i->status() ) )
      const std::string filename = i->path().filename();
      //const std::string full_filename = folder + "/" + filename;
  return v;
//From http://www.richelbilderbeek.nl/CppGetPath.htm
const std::string GetPath(const std::string& filename)
  return boost::filesystem::path(filename).parent_path().string();
int main(int, char* argv[])
  const std::vector<std::string> v = GetFilesInFolder(GetPath(argv[0]));
  std::cout << "Number of files: " << v.size() << '\n';








For this example, I use a console project that calls the Boost libraries. If you only need the STL, example 1: console application, no libaries shows an easy and successfull approach.


Additional qmake arguments can be supplied in the 'Projects -> Build Settings -> Build Steps -> qmake -> Additional arguments' edit.













[1] http://www.airs.com/ian/configure/configure_5.html#SEC28


Cross Compilation Tools

The GNU configure and build system can be used to build cross compilation tools. A cross compilation tool is a tool which runs on one system and produces code which runs on another system.
Cross Compilation Concepts

A compiler which produces programs which run on a different system is a cross compilation compiler, or simply a cross compiler. Similarly, we speak of cross assemblers, cross linkers, etc.

In the normal case, a compiler produces code which runs on the same system as the one on which the compiler runs. When it is necessary to distinguish this case from the cross compilation case, such a compiler is called a native compiler. Similarly, we speak of native assemblers, etc.

Although the debugger is not strictly speaking a compilation tool, it is nevertheless meaningful to speak of a cross debugger: a debugger which is used to debug code which runs on another system. Everything that is said below about configuring cross compilation tools applies to the debugger as well.
Host and Target

When building cross compilation tools, there are two different systems involved: the system on which the tools will run, and the system for which the tools generate code.

The system on which the tools will run is called the host system.

The system for which the tools generate code is called the target system.

For example, suppose you have a compiler which runs on a GNU/Linux system and generates ELF programs for a MIPS embedded system. In this case the GNU/Linux system is the host, and the MIPS ELF system is the target. Such a compiler could be called a GNU/Linux cross MIPS ELF compiler, or, equivalently, a `i386-linux-gnu' cross `mips-elf' compiler.

Naturally, most programs are not cross compilation tools. For those programs, it does not make sense to speak of a target. It only makes sense to speak of a target for tools like `gcc' or the `binutils' which actually produce running code. For example, it does not make sense to speak of the target of a tool like `bison' or `make'.

Most cross compilation tools can also serve as native tools. For a native compilation tool, it is still meaningful to speak of a target. For a native tool, the target is the same as the host. For example, for a GNU/Linux native compiler, the host is GNU/Linux, and the target is also GNU/Linux.
Using the Host Type

In almost all cases the host system is the system on which you run the `configure' script, and on which you build the tools (for the case when they differ, see section Canadian Cross).

If your configure script needs to know the configuration name of the host system, and the package is not a cross compilation tool and therefore does not have a target, put `AC_CANONICAL_HOST' in `configure.in'. This macro will arrange to define a few shell variables when the `configure' script is run.

    The canonical configuration name of the host. This will normally be determined by running the `config.guess' shell script, although the user is permitted to override this by using an explicit `--host' option.
    In the unusual case that the user used an explicit `--host' option, this will be the argument to `--host'. In the normal case, this will be the same as the `host' variable.
    The first three parts of the canonical configuration name.

The shell variables may be used by putting shell code in `configure.in'. For an example, see section Using Configuration Names.
Specifying the Target

By default, the `configure' script will assume that the target is the same as the host. This is the more common case; for example, it leads to a native compiler rather than a cross compiler.

If you want to build a cross compilation tool, you must specify the target explicitly by using the `--target' option when you run `configure'. The argument to `--target' is the configuration name of the system for which you wish to generate code. See section Configuration Names.

For example, to build tools which generate code for a MIPS ELF embedded system, you would use `--target mips-elf'.
Using the Target Type

When writing `configure.in' for a cross compilation tool, you will need to use information about the target. To do this, put `AC_CANONICAL_SYSTEM' in `configure.in'.

`AC_CANONICAL_SYSTEM' will look for a `--target' option and canonicalize it using the `config.sub' shell script. It will also run `AC_CANONICAL_HOST' (see section Using the Host Type).

The target type will be recorded in the following shell variables. Note that the host versions of these variables will also be defined by `AC_CANONICAL_HOST'.

    The canonical configuration name of the target.
    The argument to the `--target' option. If the user did not specify a `--target' option, this will be the same as `host_alias'.
    The first three parts of the canonical target configuration name.

Note that if `host' and `target' are the same string, you can assume a native configuration. If they are different, you can assume a cross configuration.

It is arguably possible for `host' and `target' to represent the same system, but for the strings to not be identical. For example, if `config.guess' returns `sparc-sun-sunos4.1.4', and somebody configures with `--target sparc-sun-sunos4.1', then the slight differences between the two versions of SunOS may be unimportant for your tool. However, in the general case it can be quite difficult to determine whether the differences between two configuration names are significant or not. Therefore, by convention, if the user specifies a `--target' option without specifying a `--host' option, it is assumed that the user wants to configure a cross compilation tool.

The variables `target' and `target_alias' should be handled differently.

In general, whenever the user may actually see a string, `target_alias' should be used. This includes anything which may appear in the file system, such as a directory name or part of a tool name. It also includes any tool output, unless it is clearly labelled as the canonical target configuration name. This permits the user to use the `--target' option to specify how the tool will appear to the outside world.

On the other hand, when checking for characteristics of the target system, `target' should be used. This is because a wide variety of `--target' options may map into the same canonical configuration name. You should not attempt to duplicate the canonicalization done by `config.sub' in your own code.

By convention, cross tools are installed with a prefix of the argument used with the `--target' option, also known as `target_alias' (see section Using the Target Type). If the user does not use the `--target' option, and thus is building a native tool, no prefix is used.

For example, if gcc is configured with `--target mips-elf', then the installed binary will be named `mips-elf-gcc'. If gcc is configured without a `--target' option, then the installed binary will be named `gcc'.

The autoconf macro `AC_ARG_PROGRAM' will handle this for you. If you are using automake, no more need be done; the programs will automatically be installed with the correct prefixes. Otherwise, see the autoconf documentation for `AC_ARG_PROGRAM'.
Cross Tools in the Cygnus Tree

The Cygnus tree is used for various packages including gdb, the GNU binutils, and egcs. It is also, of course, used for Cygnus releases.

In the Cygnus tree, the top level `configure' script uses the old Cygnus configure system, not autoconf. The top level `Makefile.in' is written to build packages based on what is in the source tree, and supports building a large number of tools in a single `configure'/`make' step.

The Cygnus tree may be configured with a `--target' option. The `--target' option applies recursively to every subdirectory, and permits building an entire set of cross tools at once.
Host and Target Libraries

The Cygnus tree distinguishes host libraries from target libraries.

Host libraries are built with the compiler used to build the programs which run on the host, which is called the host compiler. This includes libraries such as `bfd' and `tcl'. These libraries are built with the host compiler, and are linked into programs like the binutils or gcc which run on the host.

Target libraries are built with the target compiler. If gcc is present in the source tree, then the target compiler is the gcc that is built using the host compiler. Target libraries are libraries such as `newlib' and `libstdc++'. These libraries are not linked into the host programs, but are instead made available for use with programs built with the target compiler.

For the rest of this section, assume that gcc is present in the source tree, so that it will be used to build the target libraries.

There is a complication here. The configure process needs to know which compiler you are going to use to build a tool; otherwise, the feature tests will not work correctly. The Cygnus tree handles this by not configuring the target libraries until the target compiler is built. In order to permit everything to build using a single `configure'/`make', the configuration of the target libraries is actually triggered during the make step.

When the target libraries are configured, the `--target' option is not used. Instead, the `--host' option is used with the argument of the `--target' option for the overall configuration. If no `--target' option was used for the overall configuration, the `--host' option will be passed with the output of the `config.guess' shell script. Any `--build' option is passed down unchanged.

This translation of configuration options is done because since the target libraries are compiled with the target compiler, they are being built in order to run on the target of the overall configuration. By the definition of host, this means that their host system is the same as the target system of the overall configuration.

The same process is used for both a native configuration and a cross configuration. Even when using a native configuration, the target libraries will be configured and built using the newly built compiler. This is particularly important for the C++ libraries, since there is no reason to assume that the C++ compiler used to build the host tools (if there even is one) uses the same ABI as the g++ compiler which will be used to build the target libraries.

There is one difference between a native configuration and a cross configuration. In a native configuration, the target libraries are normally configured and built as siblings of the host tools. In a cross configuration, the target libraries are normally built in a subdirectory whose name is the argument to `--target'. This is mainly for historical reasons.

To summarize, running `configure' in the Cygnus tree configures all the host libraries and tools, but does not configure any of the target libraries. Running `make' then does the following steps:

    * Build the host libraries.
    * Build the host programs, including gcc. Note that we call gcc both a host program (since it runs on the host) and a target compiler (since it generates code for the target).
    * Using the newly built target compiler, configure the target libraries.
    * Build the target libraries.

The steps need not be done in precisely this order, since they are actually controlled by `Makefile' targets.
Target Library Configure Scripts

There are a few things you must know in order to write a configure script for a target library. This is just a quick sketch, and beginners shouldn't worry if they don't follow everything here.

The target libraries are configured and built using a newly built target compiler. There may not be any startup files or libraries for this target compiler. In fact, those files will probably be built as part of some target library, which naturally means that they will not exist when your target library is configured.

This means that the configure script for a target library may not use any test which requires doing a link. This unfortunately includes many useful autoconf macros, such as `AC_CHECK_FUNCS'. autoconf macros which do a compile but not a link, such as `AC_CHECK_HEADERS', may be used.

This is a severe restriction, but normally not a fatal one, as target libraries can often assume the presence of other target libraries, and thus know which functions will be available.

As of this writing, the autoconf macro `AC_PROG_CC' does a link to make sure that the compiler works. This may fail in a target library, so target libraries must use a different set of macros to locate the compiler. See the `configure.in' file in a directory like `libiberty' or `libgloss' for an example.

As noted in the previous section, target libraries are sometimes built in directories which are siblings to the host tools, and are sometimes built in a subdirectory. The `--with-target-subdir' configure option will be passed when the library is configured. Its value will be an empty string if the target library is a sibling. Its value will be the name of the subdirectory if the target library is in a subdirectory.

If the overall build is not a native build (i.e., the overall configure used the `--target' option), then the library will be configured with the `--with-cross-host' option. The value of this option will be the host system of the overall build. Recall that the host system of the library will be the target of the overall build. If the overall build is a native build, the `--with-cross-host' option will not be used.

A library which can be built both standalone and as a target library may want to install itself into different directories depending upon the case. When built standalone, or when built native, the library should be installed in `$(libdir)'. When built as a target library which is not native, the library should be installed in `$(tooldir)/lib'. The `--with-cross-host' option may be used to distinguish these cases.

This same test of `--with-cross-host' may be used to see whether it is OK to use link tests in the configure script. If the `--with-cross-host' option is not used, then the library is being built either standalone or native, and a link should work.
Make Targets in Cygnus Tree

The top level `Makefile' in the Cygnus tree defines targets for every known subdirectory.

For every subdirectory dir which holds a host library or program, the `Makefile' target `all-dir' will build that library or program.

There are dependencies among host tools. For example, building gcc requires first building gas, because the gcc build process invokes the target assembler. These dependencies are reflected in the top level `Makefile'.

For every subdirectory dir which holds a target library, the `Makefile' target `configure-target-dir' will configure that library. The `Makefile' target `all-target-dir' will build that library.

Every `configure-target-dir' target depends upon `all-gcc', since gcc, the target compiler, is required to configure the tool. Every `all-target-dir' target depends upon the corresponding `configure-target-dir' target.

There are several other targets which may be of interest for each directory: `install-dir', `clean-dir', and `check-dir'. There are also corresponding `target' versions of these for the target libraries , such as `install-target-dir'.
Target libiberty

The `libiberty' subdirectory is currently a special case, in that it is the only directory which is built both using the host compiler and using the target compiler.

This is because the files in `libiberty' are used when building the host tools, and they are also incorporated into the `libstdc++' target library as support code.

This duality does not pose any particular difficulties. It means that there are targets for both `all-libiberty' and `all-target-libiberty'.

In a native configuration, when target libraries are not built in a subdirectory, the same objects are normally used as both the host build and the target build. This is normally OK, since libiberty contains only C code, and in a native configuration the results of the host compiler and the target compiler are normally interoperable.

Irix 6 is again an exception here, since the SGI native compiler defaults to using the `O32' ABI, and gcc defaults to using the `N32' ABI. On Irix 6, the target libraries are built in a subdirectory even for a native configuration, avoiding this problem.

There are currently no other libraries built for both the host and the target, but there is no conceptual problem with adding more.






Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.


Valid XHTML 1.0 Strict