The Proper Way of Forcing a 32-Bit Compile Using Cmake

CMake create and link 32bit and 64bit versions of library

The -m32 flag is not "inherited" for linking purposes:

target_compile_options ( <lib> PUBLIC -m32 )
target_link_libraries ( <target> PRIVATE <lib> ) // Does not link with `-m32`.

Note that the above causes <target> to be compiled with -m32, since target_link_libraries "inherits" PUBLIC compilation option from <lib>. However, the flag is not passed to the linker.

Moreover, there is no target_link_options command, and so, one cannot insert the line target_link_options ( <link> PUBLIC -m32 ) to solve the problem.

Instead, per this answer (modified slightly), the correct approach is

target_compile_options ( <lib> PUBLIC -m32 )
set_target_properties ( <target> PROPERTIES LINK_FLAGS -m32 )
target_link_libraries ( <target> PRIVATE <lib> )

Option to force either 32-bit or 64-bit build with cmake

TL;DR

Use toolchain

In depth

  1. an option (-DUSE32bit=true)

This is not scalable I guess. So what if you want to build N projects? You have to add N options.


  1. build types (-DCMAKE_BUILD_TYPE=release32)

This may work well. But in my opinion you're mixing unrelated stuff. Also I'm sure you have to adapt find_package behaviour by setting some *_ROOT CMake variables. It's not possible to do it with CMAKE_BUILD_TYPE (at least, again, in a scalable fashion).


  1. a tool chain (-DCMAKE_TOOLCHAIN_FILE=64bit.toolchain)

The best variant. If you want to build two projects - just use same toolchain:

cmake -Hproj-1 -B_builds/proj-1 -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain
cmake -Hproj-2 -B_builds/proj-2 -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain

If you want to build your 3rd party ExternalProject_Add with 64 bit architecture - just pass toolchain to CMAKE_ARGS:

ExternalProject_Add(
...
CMAKE_ARGS ... -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain
...
)

Want to adapt find_package - just add any CMake variables to toolchain file.

Proper way to support native and forced 32bit builds

Use a toolchain file: Here is one provided by @malak

# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)

# which compilers to use for C and C++
set(CMAKE_C_COMPILER gcc)
set(CMAKE_C_FLAGS -m32)
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_FLAGS -m32)

# here is the target environment located
set(CMAKE_FIND_ROOT_PATH /usr/i486-linux-gnu )

# 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)

Then usage is simply:

$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake /path/to/source

Also, here is some information straight from wiki.

http://www.cmake.org/Wiki/CmakeMingw

I am not familiar with Nmake, but this article seems to have some similar information: http://nmake.alcatel-lucent.com/faq/32and64bit.html

How to compile a 32-bit binary on a 64-bit linux machine with gcc/cmake

export CFLAGS=-m32

cmake built a 32 bit project in my 64 bit windows

When you invoke CMake, specify Win64 in the generator option. e.g.:

cmake . -G"Visual Studio 11 Win64"


Related Topics



Leave a reply



Submit