A Basic Starting Point.rst 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  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. .. literalinclude:: Step2/CMakeLists.txt
  86. :caption: TODO 1: CMakeLists.txt
  87. :name: CMakeLists.txt-cmake_minimum_required
  88. :language: cmake
  89. :end-before: # set the project name and version
  90. The next step to make a basic project is to use the :command:`project`
  91. command as follows to set the project name:
  92. .. code-block:: cmake
  93. :caption: TODO 2: CMakeLists.txt
  94. :name: CMakeLists.txt-project
  95. project(Tutorial)
  96. The last command to call for a basic project is
  97. :command:`add_executable`. We call it as follows:
  98. .. literalinclude:: Step2/CMakeLists.txt
  99. :caption: TODO 3: CMakeLists.txt
  100. :name: CMakeLists.txt-add_executable
  101. :language: cmake
  102. :start-after: # add the executable
  103. :end-before: # add the binary tree to the search path for include files
  104. Exercise 2 - Specifying the C++ Standard
  105. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  106. CMake has some special variables that are either created behind the scenes or
  107. have meaning to CMake when set by project code. Many of these variables start
  108. with ``CMAKE_``. Avoid this naming convention when creating variables for your
  109. projects. Two of these special user settable variables are
  110. :variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
  111. These may be used together to specify the C++ standard needed to build the
  112. project.
  113. Goal
  114. ----
  115. Add a feature that requires C++11.
  116. Helpful Resources
  117. -----------------
  118. * :variable:`CMAKE_CXX_STANDARD`
  119. * :variable:`CMAKE_CXX_STANDARD_REQUIRED`
  120. * :command:`set`
  121. Files to Edit
  122. -------------
  123. * ``CMakeLists.txt``
  124. * ``tutorial.cxx``
  125. Getting Started
  126. ---------------
  127. Continue editing files in the ``Step1`` directory. Start with ``TODO 4`` and
  128. complete through ``TODO 6``.
  129. First, edit ``tutorial.cxx`` by adding a feature that requires C++11. Then
  130. update ``CMakeLists.txt`` to require C++11.
  131. Build and Run
  132. -------------
  133. Let's build our project again. Since we already created a build directory and
  134. ran CMake for Exercise 1, we can skip to the build step:
  135. .. code-block:: console
  136. cd Step1_build
  137. cmake --build .
  138. Now we can try to use the newly built ``Tutorial`` with same commands as
  139. before:
  140. .. code-block:: console
  141. Tutorial 4294967296
  142. Tutorial 10
  143. Tutorial
  144. Solution
  145. --------
  146. We start by adding some C++11 features to our project by replacing
  147. ``atof`` with ``std::stod`` in ``tutorial.cxx``. This looks like
  148. the following:
  149. .. literalinclude:: Step2/tutorial.cxx
  150. :caption: TODO 4: tutorial.cxx
  151. :name: tutorial.cxx-cxx11
  152. :language: c++
  153. :start-after: // convert input to double
  154. :end-before: // calculate square root
  155. To complete ``TODO 5``, simply remove ``#include <cstdlib>``.
  156. We will need to explicitly state in the CMake code that it should use the
  157. correct flags. One way to enable support for a specific C++ standard in CMake
  158. is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this tutorial, set
  159. the :variable:`CMAKE_CXX_STANDARD` variable in the ``CMakeLists.txt`` file to
  160. ``11`` and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to ``True``. Make sure to
  161. add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
  162. :command:`add_executable`.
  163. .. literalinclude:: Step2/CMakeLists.txt
  164. :caption: TODO 6: CMakeLists.txt
  165. :name: CMakeLists.txt-CXX_STANDARD
  166. :language: cmake
  167. :start-after: # specify the C++ standard
  168. :end-before: # configure a header file to pass some of the CMake settings
  169. Exercise 3 - Adding a Version Number and Configured Header File
  170. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  171. Sometimes it may be useful to have a variable that is defined in your
  172. ``CMakelists.txt`` file also be available in your source code. In this case, we
  173. would like to print the project version.
  174. One way to accomplish this is by using a configured header file. We create an
  175. input file with one or more variables to replace. These variables have special
  176. syntax which looks like ``@VAR@``.
  177. Then, we use the :command:`configure_file` command to copy the input file to a
  178. given output file and replace these variables with the current value of ``VAR``
  179. in the ``CMakelists.txt`` file.
  180. While we could edit the version directly in the source code, using this
  181. feature is preferred since it creates a single source of truth and avoids
  182. duplication.
  183. Goal
  184. ----
  185. Define and report the project's version number.
  186. Helpful Resources
  187. -----------------
  188. * :variable:`<PROJECT-NAME>_VERSION_MAJOR`
  189. * :variable:`<PROJECT-NAME>_VERSION_MINOR`
  190. * :command:`configure_file`
  191. * :command:`target_include_directories`
  192. Files to Edit
  193. -------------
  194. * ``CMakeLists.txt``
  195. * ``tutorial.cxx``
  196. Getting Started
  197. ---------------
  198. Continue to edit files from ``Step1``. Start on ``TODO 7`` and complete through
  199. ``TODO 12``. In this exercise, we start by adding a project version number in
  200. ``CMakeLists.txt``. In that same file, use :command:`configure_file` to copy a
  201. given input file to an output file and substitute some variable values in the
  202. input file content.
  203. Next, create an input header file ``TutorialConfig.h.in`` defining version
  204. numbers which will accept variables passed from :command:`configure_file`.
  205. Finally, update ``tutorial.cxx`` to print out its version number.
  206. Build and Run
  207. -------------
  208. Let's build our project again. As before, we already created a build directory
  209. and ran CMake so we can skip to the build step:
  210. .. code-block:: console
  211. cd Step1_build
  212. cmake --build .
  213. Verify that the version number is now reported when running the executable
  214. without any arguments.
  215. Solution
  216. --------
  217. In this exercise, we improve our executable by printing a version number.
  218. While we could do this exclusively in the source code, using ``CMakeLists.txt``
  219. lets us maintain a single source of data for the version number.
  220. First, we modify the ``CMakeLists.txt`` file to use the
  221. :command:`project` command to set both the project name and version number.
  222. When the command:`project` command is called, CMake defines
  223. ``Tutorial_VERSION_MAJOR`` and ``Tutorial_VERSION_MINOR`` behind the scenes.
  224. .. literalinclude:: Step2/CMakeLists.txt
  225. :caption: TODO 7: CMakeLists.txt
  226. :name: CMakeLists.txt-project-VERSION
  227. :language: cmake
  228. :start-after: # set the project name and version
  229. :end-before: # specify the C++ standard
  230. Then we used :command:`configure_file` to copy the input file with the
  231. specified CMake variables replaced:
  232. .. literalinclude:: Step2/CMakeLists.txt
  233. :caption: TODO 8: CMakeLists.txt
  234. :name: CMakeLists.txt-configure_file
  235. :language: cmake
  236. :start-after: # to the source code
  237. :end-before: # add the executable
  238. Since the configured file will be written into the project binary
  239. directory, we must add that directory to the list of paths to search for
  240. include files.
  241. **Note:** Throughout this tutorial, we will refer to the project build and
  242. the project binary directory interchangeably. These are the same and are not
  243. meant to refer to a `bin/` directory.
  244. We used :command:`target_include_directories` to specify
  245. where the executable target should look for include files.
  246. .. literalinclude:: Step2/CMakeLists.txt
  247. :caption: TODO 9: CMakeLists.txt
  248. :name: CMakeLists.txt-target_include_directories
  249. :language: cmake
  250. :start-after: # so that we will find TutorialConfig.h
  251. ``TutorialConfig.h.in`` is the input header file to be configured.
  252. When :command:`configure_file` is called from our ``CMakeLists.txt``, the
  253. values for ``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will
  254. be replaced with the corresponding version numbers from the project in
  255. ``TutorialConfig.h``.
  256. .. literalinclude:: Step2/TutorialConfig.h.in
  257. :caption: TODO 10: TutorialConfig.h.in
  258. :name: TutorialConfig.h.in
  259. :language: c++
  260. Next, we need to modify ``tutorial.cxx`` to include the configured header file,
  261. ``TutorialConfig.h``.
  262. .. code-block:: c++
  263. :caption: TODO 11: tutorial.cxx
  264. #include "TutorialConfig.h"
  265. Finally, we print out the executable name and version number by updating
  266. ``tutorial.cxx`` as follows:
  267. .. literalinclude:: Step2/tutorial.cxx
  268. :caption: TODO 12 : tutorial.cxx
  269. :name: tutorial.cxx-print-version
  270. :language: c++
  271. :start-after: {
  272. :end-before: // convert input to double