@@ -8,129 +8,85 @@ testing. This allows a single project to build many different outputs for differ
88platforms from a single source. Targets can also be consumed by other targets allowing
99more modular builds.
1010
11- ## Creating a Project with CMake
11+ ## Adapting our hello_world Project
1212
13- To start off, go back to your ` projects/ ` directory and create a new directory called
14- 'hello_cmake' .
13+ To start off, go back to your ` projects/hello_world ` directory and create a new file
14+ ` CMakeLists.txt ` .
1515
16- ``` sh
17- $ mkdir hello_cmake
18- $ cd hello_cmake
16+ ``` sh,icon=%gnubash,fp=Shell
17+ $ cd ~/projects/hello_world
18+ $ touch CMakeLists.txt
1919```
2020
21- Within this directory we will need to create three new files ` main.cxx ` , ` CMakeLists.txt `
22- and ` CMakePresets.json ` . For the ` main.cxx ` file you can copy the below code which is
23- identical to the one found on the previous page except printing slightly different
24- content.
25-
26- ``` cpp
27- {{#include examples/hello_cmake/main.cxx}}
21+ ``` haskell,icon=,fp=PowerShell
22+ Set-Location projects/hello_world
23+ New-Item -Path . -Name "CMakeLists.txt" -ItemType "File"
2824```
2925
30- We will first look at the `CMakeLists.txt` file.
26+ ``` haskell,icon=,fp=CommandPrompt
27+ > cd ~/projects/hello_world
28+ > echo. > CMakeLists.txt
29+ ```
3130
3231### CMake Configuration Files
3332
3433A CMake project is defined by a set of 'CMakeLists.txt' files located in the source tree
3534(directories containing your source code). These describe your projects targets, source
3635files etc.. For a simple single file project we only need a single 'CMakeLists.txt'
37- alongside our `main.cxx` source file. Copy the contents from [Listing 1-2](#listing1-2) .
36+ alongside our ` main.cxx ` source file. Copy the contents from below .
3837
39- <span id="listing1-2" class="caption">Listing 1-2: Basic CMake configuration file.</span>
40-
41- ```haskell
42- {{#include examples/hello_cmake/CMakeLists.txt}}
38+ ``` haskell,icon=%cmake,fp=CMakeLists.txt
39+ {{#include examples/hello_world/CMakeLists.txt}}
4340```
4441
4542Let's break down our ` CMakeLists.txt ` file. First we specify the minimum required version
4643of CMake this project uses. This helps to ensure that any CMake features used in the
4744projects configuration are available to end users and collaborators.
4845
49- ``` haskell
50- {{# include examples/ hello_cmake / CMakeLists. txt: 1 }}
46+ ``` haskell,icon=%cmake,fp=CMakeLists.txt
47+ {{#include examples/hello_world /CMakeLists.txt:1}}
5148```
5249
5350We then define the basic information about our project such as its name, description,
5451version and what languages it uses.
5552
56- ``` haskell
57- {{# include examples/ hello_cmake / CMakeLists. txt: 3 : 6 }}
53+ ``` haskell,icon=%cmake,fp=CMakeLists.txt
54+ {{#include examples/hello_world /CMakeLists.txt:3:6}}
5855```
5956
6057In order to mark our ` main.cxx ` as an executable we use the ` add_executable() ` function
6158where we specify the executable's name ie. the name of the target created from the
6259executable as well as the source file used to make the executable.
6360
64- ``` haskell
65- {{# include examples/ hello_cmake / CMakeLists. txt: 8 }}
61+ ``` haskell,icon=%cmake,fp=CMakeLists.txt
62+ {{#include examples/hello_world /CMakeLists.txt:8}}
6663```
6764
6865Finally, we can add compilation features; such as setting the C++ Standard to use for
6966building the target, using the ` target_compile_features() ` function. Here we add the
70- builtin CMake feature ` cxx_std_20 ` to our executable which ensures it is built using the
71- 2020 C++ Standard.
67+ builtin CMake feature ` cxx_std_17 ` to our executable which ensures it is built using the
68+ 2017 C++ Standard.
7269
73- ``` haskell
74- {{# include examples/ hello_cmake / CMakeLists. txt: 9 }}
70+ ``` haskell,icon=%cmake,fp=CMakeLists.txt
71+ {{#include examples/hello_world /CMakeLists.txt:9}}
7572```
7673
7774``` admonish info
78- See [Appendix D ](../appendix/standard-versions.md) for more information on C++ Standards.
75+ See [Appendix C ](../appendix/standard-versions.md) for more information on C++ Standards.
7976```
8077
78+ <!--
8179### CMake Presets
8280
8381We can also specify presets for CMake that define different configurations by a unique
8482name. These presets can be used to configure your project to compile on multiple
8583different platforms as well as set various flags and options depending on how your want
8684the project to be built. This is better than writing large 'CMakeLists.txt' files with
87- complicated conditional logic that makes just * writing* the configuration complicated. A
88- minimalistic ` CMakePresets.json ` file would look similar to [ Listing 1-3] ( #listing1-3 ) .
89-
90- <span id =" listing1-3 " class =" caption " >Listing 1-3: Minimalistic CMake presets file.</span >
91-
92- ``` json
93- {{#include examples/hello_cmake/CMakePresets.json }}
94- ```
95-
96- A ` CMakePresets.json ` file is starts with a key-value pair indicating the version of the
97- preset engine to use from CMake. We also specify the minimum CMake version required for
98- this project, similar to the first line [ Listing 1-2] ( #listing1-2 ) .
99-
100- ``` json
101- {{#include examples/hello_cmake/CMakePresets.json:2:7 }}
102- ```
103-
104- We then have a configuration array which stores our presets objects used for configuring
105- our projects for different targets. All presets must have a unique name used to identify
106- them.
107-
108- ``` json
109- {{#include examples/hello_cmake/CMakePresets.json:8 }}
110- // ... preset objects go here
111- {{#include examples/hello_cmake/CMakePresets.json:13 }}
112- ```
113-
114- In our preset named "default" specify where we want the resulting binary to be put. In
115- this case we specified it to be placed in the ` build/ ` directory at the root of our
116- project.
117-
118- ``` json
119- {{#include examples/hello_cmake/CMakePresets.json:9:12 }}
120- ```
121-
122- One final thing to mention is that ` CMakePresets.json ` files support macro expansions
123- which allow you to obtain common variables. The syntax for expanding a macro is to use a
124- dollar sign (` $ ` ) followed by the variables identifier surrounded in braces (` {} ` ). We
125- can see one being used in [ Listing 1-3] ( #listing1-3 ) when we specify where our binary
126- should be built. We can see that instead of hard coding a path or using relative path we
127- can leverage CMake knowing where our projects root is (which is where the root
128- ` CMakeLists.txt ` file is located) and obtain the root of our source directory using the
129- ` sourceDir ` variable, hence its expansion being used on line 11 eg.
130- ` "binaryDir": "${sourceDir}/build" ` . Variable names are always in camel case.
85+ complicated conditional logic that makes just *writing* the configuration complicated.
13186
13287More information of CMake's presets can be found on CMake's official documentation
13388[cmake-presets(7)](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html).
89+ -->
13490
13591## Building and Running a CMake Project
13692
@@ -144,7 +100,7 @@ For our project we only have a single target which also happens to correspond to
144100single preset so we can simply run the following to build our recipe.
145101
146102``` sh
147- $ cmake --preset=default
103+ $ cmake -S . -B build
148104-- The CXX compiler identification is GNU 11.4.0
149105-- Detecting CXX compiler ABI info
150106-- Detecting CXX compiler ABI info - done
@@ -153,33 +109,24 @@ $ cmake --preset=default
153109-- Detecting CXX compile features - done
154110-- Configuring done
155111-- Generating done
156- -- Build files have been written to: /home/user/projects/hello_cmake /build
112+ -- Build files have been written to: /home/user/projects/hello_world /build
157113```
158114
159- ~~~ admonish info
160- If you do not want to use presets you can manually build the project with the following
161- command.
162-
163- ```sh
164- $ cmake -S . -B build
165- ```
166- ~~~
167-
168115We can then build the target using the following command:
169116
170117``` sh
171118$ cmake --build build
172- [ 50%] Building CXX object CMakeFiles/hello_cmake .dir/main.cxx.o
173- [100%] Linking CXX executable hello_cmake
174- [100%] Built target hello_cmake
119+ [ 50%] Building CXX object CMakeFiles/hello_world .dir/main.cxx.o
120+ [100%] Linking CXX executable hello_world
121+ [100%] Built target hello_world
175122```
176123
177- This will produce a binary called ` hello_cmake ` in the ` build/ ` directory on Linux and
178- MacOS and the ` build/Debug/ ` directory on Windows. We can run our program like normal.
124+ This will produce a binary called ` hello_world ` in the ` build/ ` directory on Linux and
125+ macOS and the ` build/Debug/ ` directory on Windows. We can run our program like normal.
179126
180127``` sh
181- $ ./build/hello_cmake # ... or .\build\Debug\hello_cmake .exe on Windows
182- Hello, CMake !
128+ $ ./build/hello_world # ... or .\build\Debug\hello_world .exe on Windows
129+ Hello, World !
183130```
184131
185132~~~ admonish tip
@@ -190,11 +137,26 @@ CMake's `--config=<config>` flag during the build step. You can test creating a
190137build by running the following command which should now produce and executable in the
191138`build\Release\` directory.
192139
193- ```console
140+ ```haskell,icon=,fp=CommandPrompt
194141> cmake --build build --config=Release
195142```
196143~~~
197144
145+ ## Adding Compiler Flags to CMake Build
146+
147+ Remember in the previous chapter how I stated that it is good to specify warning flags in
148+ your C++ builds to catch common bugs. We seem to have abandoned them when introducing
149+ CMake, do not fret, we will reinstate them now.
150+
151+ ``` haskell,icon=%cmake,CMakeLists.txt
152+ {{#include examples/hello_world/CMakeLists2.txt}}
153+ ```
154+
155+ Yes, CMake has conditionals and yes they look a little weird but this is greatly the
156+ extent I will be discussing CMake until [ chapter 06] ( ../ch06/larger-projects.md ) when
157+ we look multi-file project structures.
158+
159+ <!--
198160## Compiling with Flags (Optional)
199161
200162Often we want to have specific flags set for the compiler(s) we are using but because
@@ -273,4 +235,4 @@ $ cmake -S . -B build/windows-x86 --preset=windows-x86 # configure
273235$ cmake --build build/windows-x86 --config=Release # build
274236$ ./build/windows-x86/Release/<exe-name>.exe # execute
275237```
276-
238+ -->
0 commit comments