Build 32bit on 64 bit Linux using an automake configure script?
I’m using a 64bit system but want a set of 32bit binaries. What options must I pass to a configure script to generate a 32bit/x86 makefile?
Plus one. I’m trying to build Git for Solaris. uname -m returns i86pc . All but one of the 10 or so dependent libraries misdetected the platform. Only OpenSSL correctly identified it as x86_64.
5 Answers 5
Passing the following argument to configure script allowed me to build the 32bit library on 64bit Linux
./configure --build=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32
It didn’t work for me when trying to build a library. It gave me the message configure: error: C++ compiler cannot create executables .
This answer is incomplete, which is why sometimes you can get the «compiler cannot create executables» error. See my answer in this same thread
Jack’s answer is incomplete.
You need compiler/libc support for 32-bit compilation. In some distros like Ubuntu, what you need to do is install packages gcc-multilib and/or g++-multilib :
sudo apt-get install gcc-multilib g++-multilib
Then you can call configure as you said, specifyiong a 32-bit host and passing 32-bit compilation flags:
./configure --host=i686-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
If you do not have multilib installed, you will get an error like configure: error: C compiler cannot create executables when passing the -m32 flag.
Some programs compile 32-bit on amd64 by default (eg. wine,) possibly in addition to 64-bit and should be able to find multilib if installed. Doesn’t seem to be the case for OP. Also, Jack was right about one thing — it should be —build , not —host . —host should be used if and only if you are building a compiler. It still works because there is plenty of people who don’t RTFM and write scripts that use —host instead of —build , and the autotools people have broken enough things already.
I still see g++-multilib in Debian Stretch. As well as that, you will need to enable 32-bit runtime libraries, as documented at wiki.debian.org/Multiarch/HOWTO. The commands at the bottom of that page dpkg —add-architecture i386; apt-get install libstdc++6:i386 libgcc1:i386 zlib1g:i386 libncurses5:i386 are a good starting point. You can install extra libraries as needed now, for example to build something that requires SSL, you can apt-get install libssl-dev:i386 .
@JonathanBaldwin ./configure —help says (for a script generated by autoconf): System types: —build=BUILD configure for building on BUILD [guessed] —host=HOST cross-compile to build programs to run on HOST [BUILD]
Debug vs Release in CMake
With CMake, it’s generally recommended to do an «out of source» build. Create your CMakeLists.txt in the root of your project. Then from the root of your project:
mkdir Release cd Release cmake -DCMAKE_BUILD_TYPE=Release .. make
And for Debug (again from the root of your project):
mkdir Debug cd Debug cmake -DCMAKE_BUILD_TYPE=Debug .. make
Release / Debug will add the appropriate flags for your compiler. There are also RelWithDebInfo and MinSizeRel build configurations.
You can modify/add to the flags by specifying a toolchain file in which you can add CMAKE__FLAGS__INIT variables, e.g.:
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall") set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wall")
As for your third question, I’m not sure what you are asking exactly. CMake should automatically detect and use the compiler appropriate for your different source files.
You can also do a cmake -i .. instead, so cmake will run interactively, asking you which type of build you want (None, Release, Debug, MinSizeRel, RelWithDebInfo).
@thiagowfx -i option results in this error message: The «cmake -i» wizard mode is no longer supported. . I’m using cmake 3.7.1
This is NOT an out of source build if you are creating a sub-directory! It is advised to create the build directory outside/above the source directory.
I have to run cmake —build . —config Release to get release build. If you omit —config Release you always get debug build, regardless of cmake -DCMAKE_BUILD_TYPE=Release .. in the previous command. (cmake 3.21)
A lot of the answers here are out of date/bad. So I’m going to attempt to answer it better. Granted I’m answering this question in 2020, so it’s expected things would change.
How do I run CMake for each target type (debug/release)?
First off Debug/Release are called configurations in cmake (nitpick).
If you are using a single configuration generator (Ninja/Unix-Makefiles) you must specify the CMAKE_BUILD_TYPE.
# Configure the build cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug # Actually build the binaries cmake --build build/ # Configure a release build cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Release # Build release binaries cmake --build build/
For multi-configuration generators it’s slightly different (Ninja Multi-Config, Visual Studio)
# Configure the build cmake -S . -B build # Build debug binaries cmake --build build --config Debug # Build release binaries cmake --build build --config Release
If you are wondering why this is necessary it’s because cmake isn’t a build system. It’s a meta-build system (IE a build system that build’s build systems). This is basically the result of handling build systems that support multiple-configurations in 1 build. If you’d like a deeper understanding I’d suggest reading a bit about cmake in Craig Scott’s book «Professional CMake: A Practical Guide
How do I specify debug and release C/C++ flags using CMake?
The modern practice is to use target’s and properties.
add_library(foobar) # Add this compile definition for debug builds, this same logic works for # target_compile_options, target_link_options, etc. target_compile_definitions(foobar PRIVATE $: FOOBAR_DEBUG=1 > )
NOTE: How I’m using generator expressions to specify the configuration! Using CMAKE_BUILD_TYPE will result in bad builds for any multi-configuration generator!
Further more sometimes you need to set things globally and not just for one target. Use add_compile_definitions, add_compile_options, etc. Those functions support generator expressions. Don’t use old style cmake unless you have to (that path is a land of nightmares)
How do I express that the main executable will be compiled with g++ and one nested library with gcc?
Your last question really doesn’t make sense.