[CMake] Cross Compiling

Phil Smith phil at voltage.com
Mon Jan 4 13:46:13 EST 2010


We're happily cross-compiling for System z (z/OS on IBM mainframe) using the Dignus cross-compiler under Windows. This is extra fun because it's a two-stage compiler (C/C++ to assembler, assembler to object). It's all working fine; the hard parts were:

- creating the .cmake files needed (they aren't complicated, but weren't obvious, and we have to remember to re-add them for each new install or upgrade of CMake and to copy the toolchain file to each build directory)
- creating the script that gets invoked to do the compiles (it does both stages)
- getting the right version of make (Cygwin)
- getting the environment variables right

We created a bunch of tooling that lets us use a single command to do the CMake, CMake+make, or just the make, as well as to package the files for transfer to z/OS (you *really* don't want to know how painful that part is, trust me).

My dad always said "an example is worth 1000 pages of doc", so while I doubt this will be very useful to you, here are our files. Alexander was instrumental in getting us going with this -- so anything he says that contradicts me is probably correct!

Our toolchain file (in the build directory):

# This is a CMake Toolchain file, required for cross-compiling using
# the Dignus cross-compilers on Windows, compiling for z/OS.
# Tell CMAKE the target system name
SET(CMAKE_SYSTEM_NAME "IBM_ZOS")
# Specify the cross-compilers
SET(CMAKE_C_COMPILER   "rexx.exe" "cc.rex dcc.exe")
SET(CMAKE_CXX_COMPILER "rexx.exe" "cc.rex dcxx.exe")
SET(CMAKE_C_CREATE_STATIC_LIBRARY "DAR -rv <TARGET> <OBJECTS>")
SET(CMAKE_CXX_LINK_EXECUTABLE "plink.exe \"-S$ENV{DIGNUS_PROGRAM}/objs_norent/&M\" <OBJECTS> -o <TARGET>")
SET(CMAKE_C_LINK_EXECUTABLE   "plink.exe \"-S$ENV{DIGNUS_PROGRAM}/objs_norent/&M\" <OBJECTS> -o <TARGET>")
----------------
Our CMakeASM_DIGNUSInformation.cmake (in CMake 2.8\share\cmake-2.8\Modules or equivalent):

set(ASM_DIALECT _DIGNUS)
include(CMakeASMInformation)
set(ASM_DIALECT)
SET(CMAKE_ASM_DIGNUS_SOURCE_FILE_EXTENSIONS assemble;asm)
SET(CMAKE_ASM_DIGNUS_OUTPUT_EXTENSION ".o" )
SET(CMAKE_ASM_DIGNUS_COMPILE_OBJECT "<CMAKE_ASM_DIGNUS_COMPILER> -o <OBJECT> <SOURCE>")
----------------
Our CMakeTestASM_DIGNUSCompiler.cmake (in CMake 2.8\share\cmake-2.8\Modules or equivalent)::

set(ASM_DIALECT _DIGNUS)
include(CMakeTestASMCompiler)
set(ASM_DIALECT)	
----------------
Our CMakeDetermineASM_DIGNUSCompiler.cmake (in CMake 2.8\share\cmake-2.8\Modules or equivalent)::

SET(ASM_DIALECT _DIGNUS)
SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT "asmit.bat")
INCLUDE(CMakeDetermineASMCompiler)
SET(ASM_DIALECT)
----------------
Our IBM_ZOS.cmake (in the Platform\ directory under the above):

INCLUDE(Platform/UnixPaths)
----------------

HTH. Or at least doesn't hurt.

...phsiii
-----Original Message-----
From: cmake-bounces at cmake.org [mailto:cmake-bounces at cmake.org] On Behalf Of Alexander Neundorf
Sent: Monday, January 04, 2010 1:16 PM
To: cmake at cmake.org
Subject: Re: [CMake] Cross Compiling

Hi,

On Monday 04 January 2010, Daniel Stonier wrote:
> The more I use cmake, the more I find it difficult to bend in to shape to
> cross compile. The original design doesn't seem to be designed for anything
> more than windows-linux or linux-windows cross compiles.

No. It is tested for 
* x86 Linux to ARM/MIPS/PPC Linux
* x86 Linux to x86 Windows
* x86 Windows to x86 Linux 
(not sure I tested also x86 Windows to ARM/MIPS/PPC Linux)
* x86 Linux to 16bit uC without OS
* x86 Linux to ARM/PPC eCos
* x86 Linux to PPC CNK

> Some things I'm having to currently work around by creating my own
> cross-compiling set of modules. My host is an amd64 linux and my target is
> an arm linux.
>
> - You can't set CMAKE_SYSTEM_NAME to anything useful other than Linux,
> which of course doesn't trigger the cross-compile variable CROSS_COMPILING
> because the host is the same.

See my other mail. You need to preset CMAKE_SYSTEM_NAME.

> - There is no distinction between install prefixes for the target and the
> host. Sometimes I'd like to put various build tools on the host system at
> the same time as libs and binaries on the target root.

In CMake one build tree uses one toolchain. So in one build tree you can only 
create executable which run either for the target, of for the host, not both 
in one go.
So if you need first to create host build tools, and later on use them for the 
actual cross compile, you need two build trees. I would recommend to "export" 
the executable and "import" them again in the cross build.

If this is not your problem, but really just the install location, you can set 
the install location of every install() command separately, this is 
completely independent from the cross compiling support.

> - Debian packaging in cpack will only ever put things in /usr, regardless
> of cross-compiles or different CMAKE_INSTALL_PREFIX. Refer again to above
> comment.

What is the connection between Debian and cpack and the cross compiling ?
Can you please explain ?

> Having some useful autotools install style variables (--prefix and
> --exec-prefix), someway of utilising of proper gnu tuples (e.g.
> arm-unknown-linux-gnueabi) would make things alot easier.

Can you please elaborate on this ?


More information about the CMake mailing list