How to crosscompile qt applications with CMake - c++

The situation is:
There is a compiled qt application for different platforms: Linux, Windows, Android (soon and Mac) on the Linux host. I need to build an application for all platforms on a Linux host.
I used qmake and everything was very simple there, it was enough to call qmake and pass -spec to it. Qmake wrote the necessary paths to variables on its own, and everything worked fine.
Now I am switching to CMake and I am having difficulty invoking CMake. How can I build the application for a specific platform?
Does CMake have a possibility similar to "spec" in qmake?
Or I need to manually set all the variables (I could not implement such a method)?

The CMake-equivalent of the qmake -spec option is essentially the -G (for "generator") command line option. This will tell CMake which generator to use. The CMake generator is responsible for generating the native buildsystem files (e.g. Unix Makefiles, Visual Studio project files, etc.) so it is a platform-dependent setting. For example,
cmake -G "Unix Makefiles" ..
Unlike qmake, where you specify a path to the platform/compiler information, you can tell CMake out-right which generator to choose from the list of supported generators. The CMake documentation conveniently breaks down the list of supported generators into command line and IDE groups. If you don't explicitly pick a generator, CMake will use a default generator based on the current platform.
CMake also provides additional options (that can be used along with -G) to further specify which toolset (-T) or platform (-A) to use with the generated buildsystem. The toolset and platform specifications can tell the buildsystem which specific compiler or SDK to choose. For example, we can tell CMake to prepare a build environment for an application with a Win32 platform (architecture) with Visual Studio 2019 using this:
cmake -G "Visual Studio 16 2019" -A Win32 ..
or we can change the architecture to 64-bit by specify this instead:
cmake -G "Visual Studio 16 2019" -A x64 ..
I encourage you to read through the linked documentation to understand more about how you can control CMake's buildsystem and compiler selection settings.

Related

CMake Error at CMakeLists.txt:323 (message): cl.exe (32-bit) and Visual Studio Generator (64-bit) do not match

It is my first time using cmake.
So I am writing in the developer command prompt for vs 2022
C:\Users\KBSI\OpenMS\JK_contrib>cmake -DBUILD_TYPE=ALL -DNUMBER_OF_JOBS=4 -G "Visual Studio 17 2022" -A x64 "C:\Users\KBSI\OpenMS\contrib"
The result is below
CMake Error at CMakeLists.txt:323 (message):
cl.exe (32-bit) and Visual Studio Generator (64-bit) do not match. Please
fix your PATH environment to find the proper cl.exe or use an appropriate
generator by adding -A Win32/x64 to your CMake call.
-- Configuring incomplete, errors occurred!
See also "C:/Users/KBSI/OpenMS/JK_contrib/CMakeFiles/CMakeOutput.log".
So I am adding .....X64/cl.exe to path environment also.
but it didn't work.
please help me.
The project you're trying to build puts some restrictions on the environment you run the cmake configuration from along with mentioning the reason for this:
From OpenMS/contrib/CMakeLists.txt
...
## check that the console environment has a cl.exe architecture which is identical to the VS Generator
## If cl.exe builds 32-bit libs and VS Generator is Win64, we'd end up with mixed 32bit/64bit libraries, depending on how each lib is build (Cmake, bjam, nmake)
execute_process(COMMAND "cl.exe" OUTPUT_VARIABLE cl_out ERROR_VARIABLE cl_out)
##message(STATUS "Cl.exe said: ${cl_out}")
if (cl_out MATCHES ".*x64.*")
message(STATUS "Cl.exe produces: 64-bit")
set(CL_ADDRESSMODEL 64)
elseif (cl_out MATCHES ".*x86.*")
message(STATUS "Cl.exe produces: 32-bit")
set(CL_ADDRESSMODEL 32)
else()
message(FATAL_ERROR "Could not determine if cl.exe builds x86 or x64 apps. Make sure cl.exe is available in your environment!")
endif()
if (NOT (CL_ADDRESSMODEL EQUAL CONTRIB_ADDRESSMODEL))
message(FATAL_ERROR "cl.exe (${CL_ADDRESSMODEL}-bit) and Visual Studio Generator (${CONTRIB_ADDRESSMODEL}-bit) do not match. Please fix your PATH environment to find the proper cl.exe or use an appropriate generator by adding -A Win32/x64 to your CMake call.")
endif()
...
CONTRIB_ADDRESSMODEL is set depending on the compiler properties as detected CMake (CMAKE_SIZEOF_VOID_P).
Note that here cl.exe is executed from the current process to detect the architecture of the program used. This program may be different to the compiler cmake chooses to use.
This requires you to make sure that both the compile chosen by cmake and cl.exe available in the command prompt both target x64 to set up the cmake project targeting x64. You'll need to run the correct ...\vcvarsall.bat x64 (or equivalent) before doing the cmake configuration.
Alternatively you need edit the PATH environment variable manually to list the directory containing the cl.exe targeting x64 before any other directories containing cl.exes that target different architectures.
Note: I haven't taken a look closer look at why exactly this CMake logic was added, but it sounds like a terrible choice. Sure there are scenarios where you want to prevent building with an unexpected compiler, but there are CMake generators hardcoding the absolute paths to programs like the compiler and working with those is hindered by putting such a restriction in place...

CMake generator in Visual Studio Code Windows 10 [duplicate]

I read the documentation.
It says:
A CMake Generator is responsible for writing the input files for a native build system.
What exactly does that mean?
If I have a set of C++ files in my project, are these the input files?
If I'm using Linux, what is my native build system by default? Make?
Why do the input files have to be written by the generator if they already exist?
What's a generator?
To understand what a generator is, we need to first look at what is a build system. CMake doesn't compile or link any source files. It used a generator to create configuration files for a build system. The build system uses those files to compile and link source code files.
So what's a build system?
A build system is a broad term that groups together a set of tools used to generally compile and link source code, but it can also include auxiliary tools used during a build process.
For example, in a multi-stage build system, one executable might be built to be used in the build process of another build.
Depending on the tool chain used on a system, CMake will generate multiple files and folders to allow the building of the source files referenced in the CMakeLists.txt and supporting .cmake files.
Sometimes multiple build systems may be installed on a computer, like for Windows you could have a Visual Studio and MinGW build system. CMake allows you to specify which if these build systems to generate configuration files for.
CMake includes a number of Command-Line, IDE, and Extra generators.
Command-Line Build Tool Generators
These generators are for command-line build tools, like Make and Ninja. The chosen tool chain must be configured prior to generating the build system with CMake.
The following are supported(**):
Makefile Generators
Borland Makefiles
MSYS Makefiles
MinGW Makefiles
NMake Makefiles
NMake Makefiles JOM
Unix Makefiles
Watcom WMake
Ninja Generators
Ninja
Ninja Multi-Config
IDE Build Tool Generators
These generators are for Integrated Development Environments that include their own compiler. Examples are Visual Studio and Xcode which include a compiler natively.
The following are supported(**):
Visual Studio 6
Visual Studio 7
Visual Studio 7 .NET 2003
Visual Studio 8 2005
Visual Studio 9 2008
Visual Studio 10 2010
Visual Studio 11 2012
Visual Studio 12 2013
Visual Studio 14 2015
Visual Studio 15 2017
Visual Studio 16 2019
Visual Studio 17 2022
Green Hills MULTI
Xcode
Extra Generators
These are generators that create a configuration to work with an alternative IDE tool and must be included with either an IDE or Command-Line generator.
The following are supported(**):
CodeBlocks
CodeLite
Eclipse CDT4
KDevelop3 (Unsupported after v3.10.3)
Kate
Sublime Text 2
If I have a set of C++ files in my project, are these the input files?
Yes, they are some of the input files. For a make build system you also have a MakeFile. For Visual Studio you have a solution file (.sln). With both systems there are additional files needed that CMake knows how to create given a proper CMakeLists.txt file.
If I'm using Linux, what is my native build system by default? Make?
Generally, yes, but other build systems could be setup like Ninja.
Why do the input files have to be written by the generator if they already exist?
Some source files may already exist, but CMake has the ability to generate header and source files. Also as mentioned above, there are configuration files that must be generated that depend on the source files supplied in the CMakeLists.txt file.
** According to the documentation for CMake Version 3.9 & 3.15 & 3.25
Maybe a picture is worth a thousand words.
A CMake Generator is responsible for writing the input files for a
native build system.
means that CMake prepares build scripts for a native build system when no generator is specified. In Linux the default build system is Make and its input file are makefiles, which are then interpreted and a build is executed accordingly. Before the first execution of CMake build scripts do not exist.
C++ source files (or any other source files) are not input files to a build system. Build system scripts specify how to handle source file in order to produce binary executables.
As far as I know, the standard native build system in Unix is GNU Make (gmake) known as "make".
The Google guys/gals also released a different tool called Ninja.

VS 2017 builds x64 project with cross compiler

I have a huge project in c++ for which i use cmake to generate the the .proj files.
Using CMake version 3.12.2 which supports generation of VS2017 proj files.
So for windows 64 bit compilation i use the following generator
CMAKE_GENERATOR="Visual Studio 15 2017 Win64"
This creates a .proj file at build time and is used to compile.
But from build logs what i found is that the visual studio compiler cl.exe is taken from cross compilation location
C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.15.26726/bin/Hostx86/x64/cl.exe
/Hostx86/x64/cl.exe is being used.
But i want it to be built strictly using x64 compiler. From /Hostx64/x64/cl.exe
I have read from other questions where people have mentioned to add few tags to the .proj file to force vs to use x64 compiler.
But how do i do that withe cmake file ?
I did not find any reference with this regards except the cmake generator mentioend above.
Could anyone please help me how to use cmake to strictly make VS use x64 compilor?
Note: I want it to be built with x64 compiler because i am linking to the boost library which is also compiled with
address-model=64 architecture=x86
And while the main project is compiled i am getting platform related errors.
fatal error LNK1112: module machine type 'x86' conflicts with target machine type 'x64'
That's why i wanted to compile the main project with x64 compiler.
And also, whats the difference between Hostx86/x64/cl.exe and Hostsx64/x64/cl.exe ?
This is a usual "problem". By default CMake will pick up the 32bits compiler, which is usually fine, except for projects like LLVM.
Use -T host=x64 (see https://cmake.org/cmake/help/v3.11/generator/Visual%20Studio%2015%202017.html) to use the native 64bits compiler.
Note that the last entry in the path is the target platform, not the host platform, so both the 32bits and the 64bits compilers will produce 64bits code.
I've had the same problem as described in the OP.
I think the explicit (and in my opinion recommended) way to set the build system, compiler, architecture, toolset and Windows SDK on a Microsoft Windows operating system is to use the following CMake command line arguments:
-G "Visual Studio 15 2017"
-A x64
-T v141,host=x64,version=14.12.25827
-DCMAKE_CXX_COMPILER:FILEPATH=cl
-DCMAKE_C_COMPILER:FILEPATH=cl
-DCMAKE_SYSTEM_VERSION:STRING=10.0.16299.0
This sets the compiler executable as follows on my system:
%PROGRAMFILES(X86)%\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.12.25827\bin\Hostx64\x64\cl.exe
The -A x64 argument sets the italic part in the file path above and the ,host=x64 part of the -T argument sets the bold part.
It's also a good idea to explicitly set the toolset, both the major version (v141) and the minor version ,version=14.12.25827.
According to the official CMake documentation the "Visual Studio 15 2017 Win64" generator is there only for compatibility with CMake versions prior to 3.1. I suggest to not use the "[...] Win64" generators any longer in general.
Sources:
https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2015%202017.html
https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR_TOOLSET.html

Compile CMake based project with minGW

I want to use SignalR in a Windows project that is compiled with MinGW (MSYS2). As far as I know I cannot link against a library (dll) compiled with another compiler (i.e. VC++).
Hence, I need to compile SignalR with MinGW.
Here the repository:
https://github.com/aspnet/SignalR-Client-Cpp
The project is based on CMake rather than a standard Makefile.
This is what I did:
downloaded CMake: https://cmake.org/files/v3.8/cmake-3.8.0-win32-x86.zip
extracted to a folder (i.e. C:/dev)
exported the cmake/bin folder to the PATH var (in /etc/profile)
checked if it works :) with cmake --version
cloned the Cpp Rest SDK (https://github.com/Microsoft/cpprestsdk.git)
Trying to compile the Cpp Rest SDK as described here:
https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Linux
leads to this output:
$ cmake .. -DCMAKE_BUILD_TYPE=Release
-- Building for: Visual Studio 15 2017
-- The C compiler identification is MSVC 19.10.25019.0
-- The CXX compiler identification is MSVC 19.10.25019.0
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/bin/HostX86/x86/cl.exe
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/bin/HostX86/x86/cl.exe
-- works
I'm afraid it's still using the MSVC compiler so the output binaries won't be compatible with my application.
How should I compile those libraries?
CMake does not build anything itself. Rather it generates the configuration files for make, MSBuild, Ninja, etc. Each platform has its default generator. For Windows, that is Visual Studio/NMake.
You can select a generator manually with CMake’s -G option. Some generator names contain spaces. Make sure to put quotes around those.
I am not familiar with the mingw tool chain but in cygwin it includes its own build of cmake for which you would use to generate the build system for your library. You are using the pre-compiled Windows binary which is going to detect Visual Studio.
If mingw doesnt include a prebuilt cmake I would download the source and compile it within mingw and then use that cmake binary to generate the build system of SignalR.
Download from: http://www.cmake.org/download/
And build it by:
./bootstrap
make
make install

How to cmake, make and compile C++14 on Windows

I'm trying to compile, on Windows 10, a C++ project that is using C++14 features such as std::make_unique<> and things like that.
I'd like to be able to compile easily in command line, using CMake and make and then be able to run my program from any command line or just by clicking it's executable.
Compiling using Cygwin, even if it's indeed working (I used this tutorial), is not an option since the resulting executable won't be usable outside of the Cygwin environment due to missing DLLs.
I've read about MinGW-w64, but it seems like the latest available version for Windows corresponds to GCC 4.8.3.
Same goes for the MinGW installer mingw-get-setup.exe available here, wich only allows me to install the 4.8.1-4 version.
So I'd like to have a procedure on how to compile a C++14 project using CMake, and that will allow me to launch the executable in the default Windows environment.
Thanks.
Update : Chris Drew commented that I could use the latest Visual Studio version to build my project using the Visual C++ compiler instead of GCC. I detailed the workflow in my answer, but I'm still looking for a "GNU-style" way to compile it.
"GNU-style" : Use the link provided in Tive's comment to install a working GCC 5.1 environment and use the normal cmake . -G"Unix Makefiles" && make commands.
See this answer for more details on both solutions.
Using Visual Studio compiler
Following Chris Drew comment, here's what I did in order to compile using CMake to generate a Visual Studio 2015 solution and compile this solution in command line.
Note that this is not using the GNU toolchain as we won't be using gcc / make but the Visual C++ Compiler.
Creating and moving to a build subdirectory (it's recommended since it will generate a lot of files, instead of just a standard Makefile) :
mkdir build && cd build
Generating the Visual Studio 2015 solution :
cmake . -G"Visual Studio 14 2015"
This will generate several project files including YourProjectName.sln that we will use to build the project using the following command :
msbuild YourProjectName.sln
Note that msbuild was not in my PATH, so I had to provide the complete path to the executable wich was, in my case, C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe.
Using an updated MinGW installer
Tive provided a link to a bundled installer that will automatically install GCC 5.1 on your system, this way you can use the normal GNU toolchain by generating an Unix Makefile, and using the make command.
Note that you will need to edit your PATH manually as the installer is not doing it for you.