Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Help / guide / tutorial / A Basic Starting Point.rst
1 Step 1: A Basic Starting Point
2 ==============================
3
4 Where do I start with CMake? This step will provide an introduction to some of
5 CMake's basic syntax, commands, and variables. As these concepts are
6 introduced, we will work through three exercises and create a simple CMake
7 project.
8
9 Each exercise in this step will start with some background information. Then, a
10 goal and list of helpful resources are provided. Each file in the
11 ``Files to Edit`` section is in the ``Step1`` directory and contains one or
12 more ``TODO`` comments. Each ``TODO`` represents a line or two of code to
13 change or add. The ``TODO`` s are intended to be completed in numerical order,
14 first complete  ``TODO 1`` then ``TODO 2``, etc. The ``Getting Started``
15 section will give some helpful hints and guide you through the exercise. Then
16 the ``Build and Run`` section will walk step-by-step through how to build and
17 test the exercise. Finally, at the end of each exercise the intended solution
18 is discussed.
19
20 Also note that each step in the tutorial builds on the next. So, for example,
21 the starting code for ``Step2`` is the complete solution to ``Step1``.
22
23 Exercise 1 - Building a Basic Project
24 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25
26 The most basic CMake project is an executable built from a single source code
27 file. For simple projects like this, a ``CMakeLists.txt`` file with three
28 commands is all that is required.
29
30 **Note:** Although upper, lower and mixed case commands are supported by CMake,
31 lower case commands are preferred and will be used throughout the tutorial.
32
33 Any project's top most CMakeLists.txt must start by specifying a minimum CMake
34 version using the :command:`cmake_minimum_required` command. This establishes
35 policy settings and ensures that the following CMake functions are run with a
36 compatible version of CMake.
37
38 To start a project, we use the :command:`project` command to set the project
39 name. This call is required with every project and should be called soon after
40 :command:`cmake_minimum_required`. As we will see later, this command can
41 also be used to specify other project level information such as the language
42 or version number.
43
44 Finally, the :command:`add_executable` command tells CMake to create an
45 executable using the specified source code files.
46
47 Goal
48 ----
49
50 Understand how to create a simple CMake project.
51
52 Helpful Resources
53 -----------------
54
55 * :command:`add_executable`
56 * :command:`cmake_minimum_required`
57 * :command:`project`
58
59 Files to Edit
60 -------------
61
62 * ``CMakeLists.txt``
63
64 Getting Started
65 ----------------
66
67 The source code for ``tutorial.cxx`` is provided in the
68 ``Help/guide/tutorial/Step1`` directory and can be used to compute the square
69 root of a number. This file does not need to be edited in this step.
70
71 In the same directory is a ``CMakeLists.txt`` file which you will complete.
72 Start with ``TODO 1`` and work through ``TODO 3``.
73
74 Build and Run
75 -------------
76
77 Once ``TODO 1`` through ``TODO 3`` have been completed, we are ready to build
78 and run our project! First, run the :manual:`cmake <cmake(1)>` executable or the
79 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
80 with your chosen build tool.
81
82 For example, from the command line we could navigate to the
83 ``Help/guide/tutorial`` directory of the CMake source code tree and create a
84 build directory:
85
86 .. code-block:: console
87
88   mkdir Step1_build
89
90 Next, navigate to that build directory and run
91 :manual:`cmake <cmake(1)>` to configure the project and generate a native build
92 system:
93
94 .. code-block:: console
95
96   cd Step1_build
97   cmake ../Step1
98
99 Then call that build system to actually compile/link the project:
100
101 .. code-block:: console
102
103   cmake --build .
104
105 Finally, try to use the newly built ``Tutorial`` with these commands:
106
107 .. code-block:: console
108
109   Tutorial 4294967296
110   Tutorial 10
111   Tutorial
112
113 Solution
114 --------
115
116 As mentioned above, a three line ``CMakeLists.txt`` is all that we need to get
117 up and running. The first line is to use :command:`cmake_minimum_required` to
118 set the CMake version as follows:
119
120 .. raw:: html
121
122   <details><summary>TODO 1: Click to show/hide answer</summary>
123
124 .. literalinclude:: Step2/CMakeLists.txt
125   :caption: TODO 1: CMakeLists.txt
126   :name: CMakeLists.txt-cmake_minimum_required
127   :language: cmake
128   :end-before: # set the project name and version
129
130 .. raw:: html
131
132   </details>
133
134 The next step to make a basic project is to use the :command:`project`
135 command as follows to set the project name:
136
137 .. raw:: html
138
139   <details><summary>TODO 2: Click to show/hide answer</summary>
140
141 .. code-block:: cmake
142   :caption: TODO 2: CMakeLists.txt
143   :name: CMakeLists.txt-project
144
145   project(Tutorial)
146
147 .. raw:: html
148
149   </details>
150
151 The last command to call for a basic project is
152 :command:`add_executable`. We call it as follows:
153
154 .. raw:: html
155
156   <details><summary>TODO 3: Click to show/hide answer</summary>
157
158 .. literalinclude:: Step2/CMakeLists.txt
159   :caption: TODO 3: CMakeLists.txt
160   :name: CMakeLists.txt-add_executable
161   :language: cmake
162   :start-after: # add the executable
163   :end-before: # TODO 9:
164
165 .. raw:: html
166
167   </details>
168
169 Exercise 2 - Specifying the C++ Standard
170 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171
172 CMake has some special variables that are either created behind the scenes or
173 have meaning to CMake when set by project code. Many of these variables start
174 with ``CMAKE_``. Avoid this naming convention when creating variables for your
175 projects. Two of these special user settable variables are
176 :variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
177 These may be used together to specify the C++ standard needed to build the
178 project.
179
180 Goal
181 ----
182
183 Add a feature that requires C++11.
184
185 Helpful Resources
186 -----------------
187
188 * :variable:`CMAKE_CXX_STANDARD`
189 * :variable:`CMAKE_CXX_STANDARD_REQUIRED`
190 * :command:`set`
191
192 Files to Edit
193 -------------
194
195 * ``CMakeLists.txt``
196 * ``tutorial.cxx``
197
198 Getting Started
199 ---------------
200
201 Continue editing files in the ``Step1`` directory. Start with ``TODO 4`` and
202 complete through ``TODO 6``.
203
204 First, edit ``tutorial.cxx`` by adding a feature that requires C++11. Then
205 update ``CMakeLists.txt`` to require C++11.
206
207 Build and Run
208 -------------
209
210 Let's build our project again. Since we already created a build directory and
211 ran CMake for Exercise 1, we can skip to the build step:
212
213 .. code-block:: console
214
215   cd Step1_build
216   cmake --build .
217
218 Now we can try to use the newly built ``Tutorial`` with same commands as
219 before:
220
221 .. code-block:: console
222
223   Tutorial 4294967296
224   Tutorial 10
225   Tutorial
226
227 Solution
228 --------
229
230 We start by adding some C++11 features to our project by replacing
231 ``atof`` with ``std::stod`` in ``tutorial.cxx``. This looks like
232 the following:
233
234 .. raw:: html
235
236   <details><summary>TODO 4: Click to show/hide answer</summary>
237
238 .. literalinclude:: Step2/tutorial.cxx
239   :caption: TODO 4: tutorial.cxx
240   :name: tutorial.cxx-cxx11
241   :language: c++
242   :start-after: // convert input to double
243   :end-before: // TODO 12:
244
245 .. raw:: html
246
247   </details>
248
249 To complete ``TODO 5``, simply remove ``#include <cstdlib>``.
250
251 We will need to explicitly state in the CMake code that it should use the
252 correct flags. One way to enable support for a specific C++ standard in CMake
253 is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this tutorial, set
254 the :variable:`CMAKE_CXX_STANDARD` variable in the ``CMakeLists.txt`` file to
255 ``11`` and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to ``True``. Make sure to
256 add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
257 :command:`add_executable`.
258
259 .. raw:: html
260
261   <details><summary>TODO 6: Click to show/hide answer</summary>
262
263 .. literalinclude:: Step2/CMakeLists.txt
264   :caption: TODO 6: CMakeLists.txt
265   :name: CMakeLists.txt-CXX_STANDARD
266   :language: cmake
267   :start-after: # specify the C++ standard
268   :end-before: # TODO 7:
269
270 .. raw:: html
271
272   </details>
273
274 Exercise 3 - Adding a Version Number and Configured Header File
275 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
276
277 Sometimes it may be useful to have a variable that is defined in your
278 ``CMakelists.txt`` file also be available in your source code. In this case, we
279 would like to print the project version.
280
281 One way to accomplish this is by using a configured header file. We create an
282 input file with one or more variables to replace. These variables have special
283 syntax which looks like ``@VAR@``.
284 Then, we use the :command:`configure_file` command to copy the input file to a
285 given output file and replace these variables with the current value of ``VAR``
286 in the ``CMakelists.txt`` file.
287
288 While we could edit the version directly in the source code, using this
289 feature is preferred since it creates a single source of truth and avoids
290 duplication.
291
292 Goal
293 ----
294
295 Define and report the project's version number.
296
297 Helpful Resources
298 -----------------
299
300 * :variable:`<PROJECT-NAME>_VERSION_MAJOR`
301 * :variable:`<PROJECT-NAME>_VERSION_MINOR`
302 * :command:`configure_file`
303 * :command:`target_include_directories`
304
305 Files to Edit
306 -------------
307
308 * ``CMakeLists.txt``
309 * ``tutorial.cxx``
310
311 Getting Started
312 ---------------
313
314 Continue to edit files from ``Step1``. Start on ``TODO 7`` and complete through
315 ``TODO 12``. In this exercise, we start by adding a project version number in
316 ``CMakeLists.txt``. In that same file, use :command:`configure_file` to copy a
317 given input file to an output file and substitute some variable values in the
318 input file content.
319
320 Next, create an input header file ``TutorialConfig.h.in`` defining version
321 numbers which will accept variables passed from :command:`configure_file`.
322
323 Finally, update ``tutorial.cxx`` to print out its version number.
324
325 Build and Run
326 -------------
327
328 Let's build our project again. As before, we already created a build directory
329 and ran CMake so we can skip to the build step:
330
331 .. code-block:: console
332
333   cd Step1_build
334   cmake --build .
335
336 Verify that the version number is now reported when running the executable
337 without any arguments.
338
339 Solution
340 --------
341
342 In this exercise, we improve our executable by printing a version number.
343 While we could do this exclusively in the source code, using ``CMakeLists.txt``
344 lets us maintain a single source of data for the version number.
345
346 First, we modify the ``CMakeLists.txt`` file to use the
347 :command:`project` command to set both the project name and version number.
348 When the :command:`project` command is called, CMake defines
349 ``Tutorial_VERSION_MAJOR`` and ``Tutorial_VERSION_MINOR`` behind the scenes.
350
351 .. raw:: html
352
353   <details><summary>TODO 7: Click to show/hide answer</summary>
354
355 .. literalinclude:: Step2/CMakeLists.txt
356   :caption: TODO 7: CMakeLists.txt
357   :name: CMakeLists.txt-project-VERSION
358   :language: cmake
359   :start-after: # set the project name and version
360   :end-before: # specify the C++ standard
361
362 .. raw:: html
363
364   </details>
365
366 Then we used :command:`configure_file` to copy the input file with the
367 specified CMake variables replaced:
368
369 .. raw:: html
370
371   <details><summary>TODO 8: Click to show/hide answer</summary>
372
373 .. literalinclude:: Step2/CMakeLists.txt
374   :caption: TODO 8: CMakeLists.txt
375   :name: CMakeLists.txt-configure_file
376   :language: cmake
377   :start-after: # to the source code
378   :end-before: # TODO 8:
379
380 .. raw:: html
381
382   </details>
383
384 Since the configured file will be written into the project binary
385 directory, we must add that directory to the list of paths to search for
386 include files.
387
388 **Note:** Throughout this tutorial, we will refer to the project build and
389 the project binary directory interchangeably. These are the same and are not
390 meant to refer to a `bin/` directory.
391
392 We used :command:`target_include_directories` to specify
393 where the executable target should look for include files.
394
395 .. raw:: html
396
397   <details><summary>TODO 9: Click to show/hide answer</summary>
398
399 .. literalinclude:: Step2/CMakeLists.txt
400   :caption: TODO 9: CMakeLists.txt
401   :name: CMakeLists.txt-target_include_directories
402   :language: cmake
403   :start-after: # so that we will find TutorialConfig.h
404
405 .. raw:: html
406
407   </details>
408
409 ``TutorialConfig.h.in`` is the input header file to be configured.
410 When :command:`configure_file` is called from our ``CMakeLists.txt``, the
411 values for ``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will
412 be replaced with the corresponding version numbers from the project in
413 ``TutorialConfig.h``.
414
415 .. raw:: html
416
417   <details><summary>TODO 10: Click to show/hide answer</summary>
418
419 .. literalinclude:: Step2/TutorialConfig.h.in
420   :caption: TODO 10: TutorialConfig.h.in
421   :name: TutorialConfig.h.in
422   :language: c++
423   :end-before: // TODO 13:
424
425 .. raw:: html
426
427   </details>
428
429 Next, we need to modify ``tutorial.cxx`` to include the configured header file,
430 ``TutorialConfig.h``.
431
432 .. raw:: html
433
434   <details><summary>TODO 11: Click to show/hide answer</summary>
435
436 .. code-block:: c++
437   :caption: TODO 11: tutorial.cxx
438
439   #include "TutorialConfig.h"
440
441 .. raw:: html
442
443   </details>
444
445 Finally, we print out the executable name and version number by updating
446 ``tutorial.cxx`` as follows:
447
448 .. raw:: html
449
450   <details><summary>TODO 12: Click to show/hide answer</summary>
451
452 .. literalinclude:: Step2/tutorial.cxx
453   :caption: TODO 12 : tutorial.cxx
454   :name: tutorial.cxx-print-version
455   :language: c++
456   :start-after: {
457   :end-before: // convert input to double
458
459 .. raw:: html
460
461   </details>