aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/docs/cmake.md
blob: d101dc7f319ec0a76116b8f45fbd9e4c6be1cc14 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
Default generator
-----------------

As of CMake 3.26, the default generator (unless set explicitly) is:

  * the newest Visual Studio or "NMake Makefiles" on Windows,
  * "Unix Makefiles" otherwise.

This is [regardless] of whether any executables like gcc, cl or make are
available.

[regardless]: https://github.com/Kitware/CMake/blob/v3.26.4/Source/cmake.cxx#L2484

Makefile generators
-------------------

CMake has a number of "... Makefiles" generators.  "Unix Makefiles" [uses
gmake/make/smake], whichever is found first, and [prefers cc]/[c++] symlinks
for compiler detection.  "MinGW Makefiles" [looks for mingw32-make.exe] in a
number of well-known locations instead.  In addition, "Unix Makefiles" [uses
/bin/sh] as the SHELL value in the Makefile, while the MinGW version [uses
cmd.exe].  I don't think it matters on Windows though, since the non-existent
/bin/sh is [ignored anyway].  "NMake Makefiles" is similar, except it defaults
to [using cl].

[uses gmake/make/smake]: https://github.com/Kitware/CMake/blob/v3.26.4/Modules/CMakeUnixFindMake.cmake
[prefers cc]: https://github.com/Kitware/CMake/blob/v3.26.4/Modules/CMakeDetermineCCompiler.cmake
[c++]: https://github.com/Kitware/CMake/blob/v3.26.4/Modules/CMakeDetermineCXXCompiler.cmake
[looks for mingw32-make.exe]: https://github.com/Kitware/CMake/blob/v3.26.4/Modules/CMakeMinGWFindMake.cmake
[uses /bin/sh]: https://github.com/Kitware/CMake/blob/v3.26.4/Source/cmLocalUnixMakefileGenerator3.cxx#L651
[uses cmd.exe]: https://github.com/Kitware/CMake/blob/v3.26.4/Source/cmLocalUnixMakefileGenerator3.cxx#L644
[ignored anyway]: https://www.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html
[using cl]: https://github.com/Kitware/CMake/blob/v3.26.4/Source/cmGlobalNMakeMakefileGenerator.cxx#L41

It's important to _not_ use the -A parameter with any of the Makefile
generators - it's an error.  This goes for "NMake Makefiles" also.  "NMake
Makefiles" [doesn't attempt] to search for installed Visual Studio compilers,
you need to use it from one of the Visual Studio-provided shells.

[doesn't attempt]: https://github.com/Kitware/CMake/blob/v3.26.4/Source/cmGlobalNMakeMakefileGenerator.cxx#L93

Visual Studio generators
------------------------

These are special.  They ignore the CMAKE_\<LANG\>_COMPILER parameters and [use
cl by default].  They support specifying the toolset to use via the -T
parameter (the "Platform Toolset" value in the project's properties) [since
3.8].  The toolset list varies between Visual Studio versions, and I'm too lazy
to learn exactly which version supports which toolsets.

[use cl by default]: https://gitlab.kitware.com/cmake/cmake/-/issues/19174
[since 3.8]: https://cmake.org/cmake/help/v3.8/release/3.8.html

`cmake --build` uses msbuild with Visual Studio generators.  You can pass the
path to a different cl.exe by doing something like

    msbuild ... /p:CLToolExe=another-cl.exe /p:CLToolPath=C:\parent\dir

It's important that the generators for Visual Studio 2017 or older [use Win32]
as the default platform.  Because of that, we need to pass the -A parameter.

[use Win32]: https://cmake.org/cmake/help/v3.18/generator/Visual%20Studio%2015%202017.html

mingw32-make vs make
--------------------

No idea what the actual differences are.  The [explanation] in the FAQ about
how GNU make "is lacking in some functionality and has modified functionality
due to the lack of POSIX on Win32" isn't terribly helpful.

[explanation]: http://mingw.org/wiki/FAQ

It's important that you can install either on Windows (`choco install make` for
GNU make and `choco install mingw` to install a MinGW-w64 distribution with
mingw32-make.exe included).  Personally, I don't see any difference between
using either make.exe or mingw32-make.exe w/ CMake on Windows.  But, since
MinGW-w64 distributions do include mingw32-make.exe and not make.exe, we'll try
to detect that.

Cross-compilation
-----------------

If you want to e.g. build x86 binaries on x64 and vice versa, the easiest way
seems to be to make a CMake "toolset file", which initializes the proper
compiler flags (like -m64/-m32, etc.).  Such file could look like this:

    set(CMAKE_C_COMPILER   gcc)
    set(CMAKE_C_FLAGS      -m32)
    set(CMAKE_CXX_COMPILER g++)
    set(CMAKE_CXX_FLAGS    -m32)

You can then pass the path to it using the CMAKE_TOOLCHAIN_FILE parameter.

If you use the Visual Studio generators, just use the -A parameter: `-A Win32`.

As a side note, if you want to cross-compile between x86 and x64 using GCC on
Ubuntu, you need to install the gcc-multilib package.

Windows & Clang
---------------

Using Clang on Windows is no easy task, of course.  Prior to 3.15, there was
[no support] for building things using the clang++.exe executable, only
clang-cl.exe was supported.  If you specified `-DCMAKE_CXX_COMPILER=clang++`,
CMake [would still] pass MSVC-style command line options to the compiler (like
`/MD`, `/nologo`, etc.), which clang++ doesn't like.

[no support]: https://cmake.org/cmake/help/v3.15/release/3.15.html#compilers
[would still]: https://github.com/Kitware/CMake/blob/v3.14.7/Modules/Platform/Windows-Clang.cmake

So, in summary, you can only use clang++ since 3.15.  clang-cl doesn't work
with Visual Studio generators unless you specify the proper toolset using the
-T parameter.  You can set the ClToolExe property using msbuild, but while that
might work in practice, clang-cl.exe needs to map some unsupported options for
everything to work properly.  For an example of how this is done, see the
[LLVM.Cpp.Common.* files].

[LLVM.Cpp.Common.* files]: https://github.com/llvm/llvm-project/tree/e408935bb5339e20035d84307c666fbdd15e99e0/llvm/tools/msbuild

I recommend using Clang (either clang-cl or clang++ since 3.15) using the
"NMake Makefiles" generator.