|
|
Cross compiling is supported by CMake starting with version 2.6.0.
|
|
|
|
|
|
Cross compiling means that the software is built for a different system
|
|
|
than the one which does the build. This means
|
|
|
|
|
|
- CMake cannot autodetect the target system
|
|
|
- Usually the executables don't run on the build host
|
|
|
- The build process has to use a different set of include files and
|
|
|
libraries for building, i.e. not the native ones
|
|
|
|
|
|
## Setting up the system and toolchain
|
|
|
|
|
|
When cross compiling, CMake cannot guess the target system, so you have
|
|
|
to preset some CMake variables, e.g. using a [toolchain
|
|
|
file](CMake_Cross_Compiling#The_toolchain_file "wikilink"). The
|
|
|
following variables have to be preset:
|
|
|
|
|
|
- CMAKE_SYSTEM_NAME : this one is mandatory, it is the name of the
|
|
|
target system, i.e. the same as CMAKE_SYSTEM_NAME would have if
|
|
|
CMake would run on the target system. Typical examples are "Linux"
|
|
|
and "Windows". This variable is used for constructing the file names
|
|
|
of the platform files like Linux.cmake or Windows-gcc.cmake. If your
|
|
|
target is an embedded system without OS set CMAKE_SYSTEM_NAME to
|
|
|
"Generic". If CMAKE_SYSTEM_NAME is preset, the CMake variable
|
|
|
CMAKE_CROSSCOMPILING is automatically set to TRUE, so this can be
|
|
|
used for testing in the CMake files.
|
|
|
CMAKE_SYSTEM_VERSION : optional, version of your target system,
|
|
|
not used very much.
|
|
|
CMAKE_SYSTEM_PROCESSOR : optional, processor (or hardware) of the
|
|
|
target system. This variable is not used very much except for one
|
|
|
purpose, it is used to load a
|
|
|
CMAKE_SYSTEM_NAME-compiler-CMAKE_SYSTEM_PROCESSOR.cmake file,
|
|
|
which can be used to modify settings like compiler flags etc. for
|
|
|
the target. You probably only have to set this one if you are using
|
|
|
a cross compiler where every target hardware needs special build
|
|
|
settings.
|
|
|
|
|
|
Since CMake cannot guess the target system, it also cannot guess which
|
|
|
compiler it should use, so you have to preset this too:
|
|
|
|
|
|
- CMAKE_C_COMPILER : the C compiler executable, may be the full path
|
|
|
or just the filename. If it is specified with full path, then this
|
|
|
path will be prefered when searching the C++ compiler and the other
|
|
|
tools (binutils, linker, etc.). If this compiler is a gcc-cross
|
|
|
compiler with a prefixed name (e.g. "arm-elf-gcc") CMake will detect
|
|
|
this and automatically find the corresponding C++ compiler (i.e.
|
|
|
"arm-elf-c++"). The compiler can also be preset via the CC
|
|
|
environment variables.
|
|
|
CMAKE_CXX_COMPILER : the C++ compiler executable, may be the full
|
|
|
path or just the filename. It is handled the same way as
|
|
|
CMAKE_C_COMPILER. If the toolchain is a GNU toolchain, you only
|
|
|
need to set one of both.
|
|
|
|
|
|
Once the system and the compiler are determined by CMake, it loads the
|
|
|
corresponding files in the following order:
|
|
|
|
|
|
- Platform/${CMAKE_SYSTEM_NAME}.cmake (optional, but issues a stern
|
|
|
warning)
|
|
|
- Platform/${CMAKE_SYSTEM_NAME}-<compiler>.cmake
|
|
|
(optional)
|
|
|
- Platform/${CMAKE_SYSTEM_NAME}-<compiler>-${CMAKE_SYSTEM_PROCESSOR}.cmake
|
|
|
(optional)
|
|
|
|
|
|
<compiler> is either the basename of the compiler executable, e.g. "gcc"
|
|
|
(this is also used if gcc has a different name) or "cl", or by a
|
|
|
compiler id, which is detected by compiling a test source file.
|
|
|
|
|
|
For testing the host system, there is a corresponding set of variables,
|
|
|
which is set automatically by CMake:
|
|
|
|
|
|
- CMAKE_HOST_SYSTEM_NAME
|
|
|
- CMAKE_HOST_SYSTEM_VERSION
|
|
|
- CMAKE_HOST_SYSTEM_PROCESSOR
|
|
|
- CMAKE_HOST_SYSTEM
|
|
|
|
|
|
Without cross compiling the variables for the host system and the target
|
|
|
system are identical. In most cases you will want to test for the target
|
|
|
system, then the same way as without cross compiling use the
|
|
|
CMAKE_SYSTEM_xxx variables, this will work both for cross compiling
|
|
|
and for native building.
|
|
|
|
|
|
With these variables correctly set, CMake will now use the cross
|
|
|
compiling toolchain for building and in the CMakeLists.txt you can still
|
|
|
use the CMAKE_SYSTEM_XXX variables for testing for which system you
|
|
|
are building. This is already enough to use CMake for cross compiling
|
|
|
simple (buildsystem-wise) projects.
|
|
|
|
|
|
## Searching and finding external software
|
|
|
|
|
|
Most non-trivial projects will depend on external libraries or tools.
|
|
|
CMake offers the FIND_PROGRAM(), FIND_LIBRARY(), FIND_FILE(),
|
|
|
FIND_PATH() and FIND_PACKAGE() commands for this purpose. They search
|
|
|
the file system in common places for files and return the results.
|
|
|
FIND_PACKAGE() is a bit different in that it actually doesn't search
|
|
|
itself, but "only" executes FindXXX.cmake modules, which usually call
|
|
|
the FIND_PROGRAM(), FIND_LIBRARY(), FIND_FILE() and FIND_PATH()
|
|
|
commands then.
|
|
|
|
|
|
When cross compiling e.g. for a target with an ARM processor getting
|
|
|
/usr/lib/libjpeg.so as the result of a FIND_PACKAGE(JPEG) wouldn't be
|
|
|
much of a help, since this would be the JPEG library for the host
|
|
|
system, e.g. an x86 Linux box. So you need to tell CMake to search in
|
|
|
other locations. This can be done by setting the following variables:
|
|
|
|
|
|
- CMAKE_FIND_ROOT_PATH : this is a list of directories, each of the
|
|
|
directories listed there will be prepended to each of the search
|
|
|
directories of every FIND_XXX() command. So e.g. if your target
|
|
|
environment is installed under /opt/eldk/ppc_74xx, set
|
|
|
CMAKE_FIND_ROOT_PATH to this directory. Then e.g.
|
|
|
FIND_LIBRARY(BZ2_LIB bz2) will search in /opt/eldk/ppc_74xx/lib,
|
|
|
/opt/eldk/ppc_74xx/usr/lib, /lib, /usr/lib and so give
|
|
|
/opt/eldk/ppc_74xx/usr/lib/libbz2.so as result. By default
|
|
|
CMAKE_FIND_ROOT_PATH is empty. If set, at first the directories
|
|
|
prefixed with the directories given in CMAKE_FIND_ROOT_PATH will
|
|
|
be searched and after that the unprefixed versions of the search
|
|
|
directories will be searched. This behaviour can be modified
|
|
|
individually for every FIND_XXX() call with the
|
|
|
NO_CMAKE_FIND_ROOT_PATH, ONLY_CMAKE_FIND_ROOT_PATH and
|
|
|
CMAKE_FIND_ROOT_PATH_BOTH options or the default for all
|
|
|
FIND_XXX() commands can be adjusted with the
|
|
|
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM,
|
|
|
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY and
|
|
|
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE variables. If you don't want
|
|
|
to use only libraries that come with the toolchain but also build
|
|
|
and use additional libraries for your target platform, you should
|
|
|
create an install directory for these packages, e.g.
|
|
|
$HOME/eldk-ppc_74xx-inst/ and add this to CMAKE_FIND_ROOT_PATH,
|
|
|
so the FIND_XXX() commands will search there too. If you then build
|
|
|
packages for your target platform, they should be installed into
|
|
|
this directory.
|
|
|
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM: This sets the default
|
|
|
behaviour for the FIND_PROGRAM() command. It can be set to NEVER,
|
|
|
ONLY or BOTH (default). If set to NEVER, CMAKE_FIND_ROOT_PATH
|
|
|
will not be used for FIND_PROGRAM() calls (except where it is
|
|
|
enabled explicitely). If set to ONLY, only the search directories
|
|
|
with the prefixes coming from CMAKE_FIND_ROOT_PATH will be used
|
|
|
in FIND_PROGRAM(). The default is BOTH, which means that at first
|
|
|
the prefixed directories and after that the unprefixed directories
|
|
|
will be searched. In most cases FIND_PROGRAM() is used to search
|
|
|
for an executable which will then be executed e.g. using
|
|
|
EXECUTE_PROCESS() or ADD_CUSTOM_COMMAND(). So in most cases an
|
|
|
executable from the build host is required, so usually set
|
|
|
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM to NEVER.
|
|
|
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY: This is the same as above,
|
|
|
but for the FIND_LIBRARY() command. In most cases this is used to
|
|
|
find a library which will then be used for linking, so a library for
|
|
|
the target is required. So in the common case, set it to ONLY.
|
|
|
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE: This is the same as above
|
|
|
and used for both FIND_PATH() and FIND_FILE(). In many cases this
|
|
|
is used for finding include directories, so the target environment
|
|
|
should be searched. So in the common case, set it to ONLY. You may
|
|
|
have to adjust this behaviour for some of the FIND_PATH() or
|
|
|
FIND_FILE() calls using the NO_CMAKE_FIND_ROOT_PATH,
|
|
|
ONLY_CMAKE_FIND_ROOT_PATH and CMAKE_FIND_ROOT_PATH_BOTH
|
|
|
options.
|
|
|
|
|
|
## The toolchain file
|
|
|
|
|
|
Defining all the variables mentioned above using `-DCMAKE_SYSTEM_NAME`
|
|
|
etc. would be quite tedious and error prone. To make things easier,
|
|
|
there is another cmake variable you can set:
|
|
|
|
|
|
- CMAKE_TOOLCHAIN_FILE : absolute or relative path to a cmake script
|
|
|
which sets up all the toolchain related variables mentioned above
|
|
|
|
|
|
For instance for crosscompiling from Linux to Embedded Linux on PowerPC
|
|
|
this file could look like this:
|
|
|
|
|
|
# this one is important
|
|
|
SET(CMAKE_SYSTEM_NAME Linux)
|
|
|
#this one not so much
|
|
|
SET(CMAKE_SYSTEM_VERSION 1)
|
|
|
|
|
|
# specify the cross compiler
|
|
|
SET(CMAKE_C_COMPILER /opt/eldk-2007-01-19/usr/bin/ppc_74xx-gcc)
|
|
|
SET(CMAKE_CXX_COMPILER /opt/eldk-2007-01-19/usr/bin/ppc_74xx-g++)
|
|
|
|
|
|
# where is the target environment
|
|
|
SET(CMAKE_FIND_ROOT_PATH /opt/eldk-2007-01-19/ppc_74xx /home/alex/eldk-ppc74xx-inst)
|
|
|
|
|
|
# search for programs in the build host directories
|
|
|
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
|
# for libraries and headers in the target directories
|
|
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
|
|
|
|
If this file is named Toolchain-eldk-ppc74xx.cmake and is located in
|
|
|
your home directory and you are building in the subdirectory build then
|
|
|
you can do:
|
|
|
|
|
|
~/src$ cd build
|
|
|
~/src/build$ cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-eldk-ppc74xx.cmake ..
|
|
|
...
|
|
|
|
|
|
You don't have to write a toolchain file for every piece of software you
|
|
|
want to build, the toolchain files are per target platform, i.e. if you
|
|
|
are building several software packages all for the same target platform,
|
|
|
you have to write only one toolchain file and you can use this for all
|
|
|
packages.
|
|
|
|
|
|
If your compiler is not able to build a simple program by default
|
|
|
without special flags or files (e.g. linker scripts or memory layout
|
|
|
files), the toolchain file as shown above doesn't work. Then you have to
|
|
|
*force* the compiler:
|
|
|
|
|
|
INCLUDE(CMakeForceCompiler)
|
|
|
|
|
|
# this one is important
|
|
|
SET(CMAKE_SYSTEM_NAME eCos)
|
|
|
|
|
|
# specify the cross compiler
|
|
|
CMAKE_FORCE_C_COMPILER(arm-elf-gcc GNU)
|
|
|
CMAKE_FORCE_CXX_COMPILER(arm-elf-g++ GNU)
|
|
|
|
|
|
# where is the target environment
|
|
|
SET(CMAKE_FIND_ROOT_PATH /home/alex/src/ecos/install )
|
|
|
|
|
|
# search for programs in the build host directories
|
|
|
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
|
# for libraries and headers in the target directories
|
|
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
|
|
|
|
This is done using the CMAKE_FORCE_XXX_COMPILER() macros. The second
|
|
|
argument is the compiler id, which is used by CMake to recognize the
|
|
|
compiler.
|
|
|
|
|
|
A toolchain for crosscompiling for Win32 using mingw32 might look like
|
|
|
this:
|
|
|
|
|
|
# the name of the target operating system
|
|
|
SET(CMAKE_SYSTEM_NAME Windows)
|
|
|
|
|
|
# which compilers to use for C and C++
|
|
|
SET(CMAKE_C_COMPILER i486-mingw32-gcc)
|
|
|
SET(CMAKE_CXX_COMPILER i486-mingw32-g++)
|
|
|
SET(CMAKE_RC_COMPILER i486-mingw32-windres)
|
|
|
|
|
|
# here is the target environment located
|
|
|
SET(CMAKE_FIND_ROOT_PATH /usr/i486-mingw32)
|
|
|
|
|
|
# adjust the default behaviour of the FIND_XXX() commands:
|
|
|
# search headers and libraries in the target environment, search
|
|
|
# programs in the host environment
|
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
|
|
|
|
## System introspection
|
|
|
|
|
|
Many non-trivial software projects have a set of system introspection
|
|
|
tests for finding out properties of the (target) system. In CMake there
|
|
|
are macros provided for this purpose like e.g. CHECK_INCLUDE_FILES()
|
|
|
or CHECK_C_SOURCE_RUNS(). Most of these tests will internally use
|
|
|
either the TRY_COMPILE() or the TRY_RUN() CMake commands. The
|
|
|
TRY_COMPILE() commands work as expected also when cross compiling, they
|
|
|
will try to compile the piece of code with the cross compiling
|
|
|
toolchain, which will give the expected result. All tests using
|
|
|
TRY_RUN() internally cannot work, since the created executables cannot
|
|
|
run on the build host system. At first TRY_RUN() tries to compile the
|
|
|
software, which will work the same way when cross compiling. If this
|
|
|
succeeded, it will check the variable CMAKE_CROSSCOMPILING whether the
|
|
|
resulting executable is runnable or not. If not, it will create two
|
|
|
cache variables, which then have to be set by the user or via the CMake
|
|
|
cache. Let's say the command looks like this:
|
|
|
|
|
|
TRY_RUN(SHARED_LIBRARY_PATH_TYPE SHARED_LIBRARY_PATH_INFO_COMPILED
|
|
|
${PROJECT_BINARY_DIR}/CMakeTmp
|
|
|
${PROJECT_SOURCE_DIR}/CMake/SharedLibraryPathInfo.cxx
|
|
|
OUTPUT_VARIABLE OUTPUT
|
|
|
ARGS "LDPATH")
|
|
|
|
|
|
The variable SHARED_LIBRARY_PATH_INFO_COMPILED will be set to the
|
|
|
result of the build (i.e. TRUE or FALSE). CMake will create a cache
|
|
|
variable SHARED_LIBRARY_PATH_TYPE and preset it to
|
|
|
PLEASE_FILL_OUT-FAILED_TO_RUN. This one has to be set to the exit
|
|
|
code of the executable if it would have been executed on the target. It
|
|
|
will also create a cache variable
|
|
|
SHARED_LIBRARY_PATH_TYPE__TRYRUN_OUTPUT and preset it to
|
|
|
PLEASE_FILL_OUT-NOTFOUND. This one has to be set to the output the
|
|
|
executable prints to stdout and stderr if it is executed on the target.
|
|
|
This variable is only created if the TRY_RUN() command was used with
|
|
|
the RUN_OUTPUT_VARIABLE or the OUTPUT_VARIABLE argument. You have to
|
|
|
fill in appropriate values for these variables. To help you with this
|
|
|
CMake tries its best to give you useful information.
|
|
|
|
|
|
To do so CMake creates a file ${CMAKE_BINARY_DIR}/TryRunResults.cmake.
|
|
|
There you will find all variables which CMake could not determine, from
|
|
|
which CMake file they were called, the source file, the arguments for
|
|
|
the executable and the path to the executable. CMake will also copy the
|
|
|
executables in the build directory, they have the names
|
|
|
cmTryCompileExec-<name of the variable>, e.g.
|
|
|
cmTryCompileExec-SHARED_LIBRARY_PATH_TYPE. You can then try to run
|
|
|
this executable manually on the actual target platform and check the
|
|
|
results.
|
|
|
|
|
|
Once you have these results, they have to get in the CMake cache. You
|
|
|
can either use ccmake/CMakeSetup/"make edit_cache" and edit the
|
|
|
variables directly in the cache. Then you won't be able to reuse your
|
|
|
changes in another build directory or if you remove CMakeCache.txt. The
|
|
|
second option is to use the TryRunResults.cmake file. Copy it to a safe
|
|
|
location (i.e. where it is not deleted if you delete the build dir) and
|
|
|
give it a useful name, e.g. MyProjectTryRunResults-eldk-ppc.cmake. Then
|
|
|
edit it so that the SET() commands set the required values. You can the
|
|
|
use this file to preload the CMake cache by using the -C option of
|
|
|
cmake:
|
|
|
|
|
|
src/build/ $ cmake -C ~/MyProjectTryRunResults-eldk-ppc.cmake .
|
|
|
|
|
|
You don't have to use the other CMake options again, they are now
|
|
|
already in the cache. This way you can use
|
|
|
MyProjectTryRunResults-eldk-ppc.cmake in multiple build trees and it
|
|
|
could also be distributed with your project so it gets easier for other
|
|
|
users who want to compile it.
|
|
|
|
|
|
[This script](https://gist.github.com/thewtex/5931775) may be helpful to
|
|
|
automatically populate the TRY_RUN results with those placed in a
|
|
|
CMakeCache.txt that were created on the target.
|
|
|
|
|
|
## Using executables in the build created during the build
|
|
|
|
|
|
In some cases during a build executables are created which are then used
|
|
|
in ADD_CUSTOM_COMMAND() or ADD_CUSTOM_TARGET() during the same build
|
|
|
process.
|
|
|
|
|
|
When cross compiling this won't work without modifications because the
|
|
|
executables cannot run on the build host. Starting with CMake 2.6 it is
|
|
|
possible to "import" executable targets into a CMake project. When cross
|
|
|
compiling this has to be used to import executables built in a native
|
|
|
build into the cross-build. This can be done like this:
|
|
|
|
|
|
# when crosscompiling import the executable targets from a file
|
|
|
IF(CMAKE_CROSSCOMPILING)
|
|
|
SET(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Point it to the export file from a native build")
|
|
|
INCLUDE(${IMPORT_EXECUTABLES})
|
|
|
ENDIF(CMAKE_CROSSCOMPILING)
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
# only build the generator if not crosscompiling
|
|
|
IF(NOT CMAKE_CROSSCOMPILING)
|
|
|
ADD_EXECUTABLE(mygenerator mygen.cpp)
|
|
|
TARGET_LINK_LIBRARIES(mygenerator ${SOME_LIBS})
|
|
|
ENDIF(NOT CMAKE_CROSSCOMPILING)
|
|
|
|
|
|
# then use the target name as COMMAND, CMake >= 2.6 knows how to handle this
|
|
|
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.c
|
|
|
COMMAND mygenerator foo.dat -o ${CMAKE_CURRENT_BINARY_DIR}/generated.c
|
|
|
DEPENDS foo.dat )
|
|
|
|
|
|
|
|
|
...
|
|
|
# export the generator target to a file, so it can be imported (see above) by another build
|
|
|
# the IF() is not necessary, but makes the intention clearer
|
|
|
IF(NOT CMAKE_CROSSCOMPILING)
|
|
|
EXPORT(TARGETS mygenerator FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake )
|
|
|
ENDIF(NOT CMAKE_CROSSCOMPILING)
|
|
|
|
|
|
So during the native build the target "mygenerator" will be built and
|
|
|
used in ADD_CUSTOM_COMMAND(). As command only the target name is used.
|
|
|
CMake \>= 2.6.0 recognizes this and creates the dependencies and will
|
|
|
use the path to the created executable when executing the command. At
|
|
|
the end the EXPORT() function (since CMake 2.6.0) is called, which
|
|
|
"exports" the listed targets to the file
|
|
|
${CMAKE_BINARY_DIR}/ImportExecutables.cmake, which will look like
|
|
|
this:
|
|
|
|
|
|
ADD_EXECUTABLE(mygenerator IMPORT)
|
|
|
SET_TARGET_PROPERTIES(mygenerator PROPERTIES
|
|
|
LOCATION /home/alex/build-native/bin/mygenerator )
|
|
|
|
|
|
This file is then included when cross compiling, it either has to be
|
|
|
specified using -D or via the cmake GUI. Then later on the command for
|
|
|
actually building mygenerator is excluded. In ADD_CUSTOM_COMMAND()
|
|
|
mygenerator will be recognized as an imported target and it will be used
|
|
|
when executing the command.
|
|
|
|
|
|
If the executable mygenerator also has to be built when cross compiling,
|
|
|
then some more logic needs to be added, e.g. like this:
|
|
|
|
|
|
# when crosscompiling import the executable targets from a file
|
|
|
IF(CMAKE_CROSSCOMPILING)
|
|
|
SET(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Point it to the export file from a native build")
|
|
|
INCLUDE(${IMPORT_EXECUTABLES})
|
|
|
ENDIF(CMAKE_CROSSCOMPILING)
|
|
|
|
|
|
...
|
|
|
|
|
|
# always build the executable
|
|
|
ADD_EXECUTABLE(mygenerator mygen.cpp)
|
|
|
TARGET_LINK_LIBRARIES(mygenerator ${SOME_LIBS})
|
|
|
|
|
|
# but use different names for the command
|
|
|
IF(CMAKE_CROSSCOMPILING)
|
|
|
SET(mygenerator_EXE native-mygenerator)
|
|
|
ELSE(CMAKE_CROSSCOMPILING)
|
|
|
SET(mygenerator_EXE mygenerator)
|
|
|
ENDIF(CMAKE_CROSSCOMPILING)
|
|
|
|
|
|
# then use the target name as COMMAND, CMake >= 2.6 knows how to handle this
|
|
|
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.c
|
|
|
COMMAND ${mygenerator_EXE} foo.dat -o ${CMAKE_CURRENT_BINARY_DIR}/generated.c
|
|
|
DEPENDS foo.dat )
|
|
|
|
|
|
|
|
|
...
|
|
|
# export the generator target to a file, so it can be imported (see above) by another build
|
|
|
# the IF() is not necessary, but makes the intention clearer
|
|
|
# use the NAMESPACE option of EXPORT() to get a different target name for mygenerator when exporting
|
|
|
IF(NOT CMAKE_CROSSCOMPILING)
|
|
|
EXPORT(TARGETS mygenerator FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake NAMESPACE native- )
|
|
|
ENDIF(NOT CMAKE_CROSSCOMPILING)
|
|
|
|
|
|
## Cross compilation for Windows CE
|
|
|
|
|
|
Building for Windows CE requires Visual Studio 2005 or 2008 (No Express
|
|
|
Edition\!) with at least one installed SDK. If you don't have a specific
|
|
|
installation file for your target device it is possible to use the
|
|
|
Windows CE 5.0 Standard SDK from
|
|
|
<http://www.microsoft.com/downloads/details.aspx?familyid=fa1a3d66-3f61-4ddc-9510-ae450e2318c3>.
|
|
|
|
|
|
CMake supports Windows CE out of the box since version 2.8.10 when used
|
|
|
with the `NMake Makefiles` generator. To use it you first need the
|
|
|
corresponding environment variables set, for which the CMake command
|
|
|
`env_vs8_wince` has been added in the following version. Using 2.8.10 is
|
|
|
possible too, if the environment is set manually. To get there start a
|
|
|
command prompt and type the following commands:
|
|
|
|
|
|
"%VS80COMNTOOLS%vsvars32.bat"
|
|
|
cmake -E env_vs8_wince "STANDARDSDK_500 (ARMV4I)" > env.bat
|
|
|
env.bat
|
|
|
|
|
|
Then the Makefiles can be generated and built with the following
|
|
|
commands:
|
|
|
|
|
|
cmake -G "NMake Makefiles" -DCMAKE_SYSTEM_NAME=WindowsCE -DCMAKE_SYSTEM_PROCESSOR=ARMV4I \path\to\source
|
|
|
cmake --build .
|
|
|
|
|
|
Starting with CMake 2.8.11 it is also possible to create Visual Studio
|
|
|
solution for Windows CE targets. Depending on the installed SDKs CMake
|
|
|
will accept additional generators. The following command will create
|
|
|
Visual Studio 2005 files for the WinCE standard
|
|
|
SDK:
|
|
|
|
|
|
cmake -G "Visual Studio 8 2005 STANDARDSDK_500 (ARMV4I)" \path\to\source
|
|
|
|
|
|
To use VS2008 instead of VS2005 simple replace "VS80COMNTOOLS" with
|
|
|
"VS90COMNTOOLS", "vs8" with "vs9" and "8 2005" with "9
|
|
|
2008".
|
|
|
|
|
|
## Information how to set up various cross compiling toolchains
|
|
|
|
|
|
- [1](https://sites.google.com/site/michaelsafyan/software-engineering/haunted-by-an-ancient-post-about-iphone-cross-compilation-and-cmake-based-builds),
|
|
|
detailed instructions for using CMake for the iPhone (external,
|
|
|
thirdparty website).
|
|
|
- [eldk](CmakeEldk "wikilink"), embedded Linux cross compiling
|
|
|
toolchain from Denx
|
|
|
- [mingw](CmakeMingw "wikilink") - gcc for cross compiling from Linux
|
|
|
to Windows
|
|
|
- [SDCC](CmakeSdcc "wikilink") - the small devices C compiler
|
|
|
- [eCos](CmakeEcos "wikilink") - the embedded Configurable operating
|
|
|
system
|
|
|
- [ADSP](CmakeAdsp "wikilink") - the Analog Devices toolchain for
|
|
|
their DSPs
|
|
|
- [IBM BlueGene/L](CmakeBlueGene "wikilink")
|
|
|
- [Cray XT3 / Catamount](CmakeCrayXt3 "wikilink")
|
|
|
- [Crosstool NG](http://ymorin.is-a-geek.org/projects/crosstool) - may
|
|
|
be used to easily build various cross compiler toolchain. The
|
|
|
produced toolchain seems to work well with CMake cross-compiling.
|
|
|
- [MXE](http://mxe.cc/) - Builds compiler and libraries for cross
|
|
|
compiling from Linux to Windows. Comes with CMake toolchain
|
|
|
file\!
|
|
|
|
|
|
## How to cross compile specific projects
|
|
|
|
|
|
- [ITK](ITK/Cross_Compiling "wikilink")
|
|
|
- [ParaView3](http://paraview.org/ParaView3/index.php/Cross_compiling_ParaView3_and_VTK)
|
|
|
- [Python](BuildingPythonWithCMake "wikilink")
|
|
|
|
|
|
## FAQ/Potential Problems
|
|
|
|
|
|
- On mixed 32/64 bit Linux installations cross compilation cannot be
|
|
|
used to build for 32/64 bit only.
|
|
|
|
|
|
<!-- end list -->
|
|
|
|
|
|
- FindXXX.cmake modules, which rely on executing a binary tool like
|
|
|
pkg-config may have problems, since the pkg-config of the target
|
|
|
platform cannot be executed on the host. Tools like pkg-config
|
|
|
should be used only optional in FindXXX.cmake files.
|
|
|
|
|
|
<!-- end list -->
|
|
|
|
|
|
- What about Scratchbox ? CMake should work without problems in
|
|
|
scratchbox, then it will just work in native mode.
|
|
|
|
|
|
<!-- end list -->
|
|
|
|
|
|
- Can it build software for PS3 ? If you build software for PS3, you
|
|
|
build software for two architectures, for the PowerPC and for the
|
|
|
cells. This is done using two different toolchains. Currently CMake
|
|
|
doesn't support using multiple toolchains in one buildtree or
|
|
|
building for multiple target architectures in one build tree. So
|
|
|
building for PS3 doesn't work out-of-the-box. It should work using
|
|
|
ADD_CUSTOM_COMMAND() or by using two buildtrees.
|
|
|
|
|
|
----
|
|
|
This page was initially populated by conversion from its [original location](https://public.kitware.com/Wiki/CMake_Cross_Compiling) in another wiki. |