A Basic Starting Point.rst 13 KB

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