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
- 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.
- 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).
- 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
Understanding Gsl::Narrow Implementation
Workaround for Error C2536: Cannot Specify Explicit Initializer for Arrays in Visual Studio 2013
Why Do Sin(45) and Cos(45) Give Different Results
Undefined Reference to Template Members
How to Treat a Specific Warning as an Error
G++ Linker: Force Static Linking If Static Library Exists
Why Isn't Memcpy Guaranteed to Be Safe for Non-Pod Types
Passing Non-Pod Type to Variadic Function Is Undefined Behavior
When Does a Std::Vector Reallocate Its Memory Array
Generate All Sequences of Bits Within Hamming Distance T
Std::Cin Doesn't Throw an Exception on Bad Input
How to Overload Operator==() for a Pointer to the Class