index.rst 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. CMake Tutorial
  2. **************
  3. .. only:: html
  4. .. contents::
  5. Introduction
  6. ============
  7. The CMake tutorial provides a step-by-step guide that covers common build
  8. system issues that CMake helps address. Seeing how various topics all
  9. work together in an example project can be very helpful. The tutorial
  10. documentation and source code for examples can be found in the
  11. ``Help/guide/tutorial`` directory of the CMake source code tree. Each step has
  12. its own subdirectory containing code that may be used as a starting point. The
  13. tutorial examples are progressive so that each step provides the complete
  14. solution for the previous step.
  15. A Basic Starting Point (Step 1)
  16. ===============================
  17. The most basic project is an executable built from source code files.
  18. For simple projects, a three line ``CMakeLists.txt`` file is all that is
  19. required. This will be the starting point for our tutorial. Create a
  20. ``CMakeLists.txt`` file in the ``Step1`` directory that looks like:
  21. .. code-block:: cmake
  22. cmake_minimum_required(VERSION 3.10)
  23. # set the project name
  24. project(Tutorial)
  25. # add the executable
  26. add_executable(Tutorial tutorial.cxx)
  27. Note that this example uses lower case commands in the ``CMakeLists.txt`` file.
  28. Upper, lower, and mixed case commands are supported by CMake. The source
  29. code for ``tutorial.cxx`` is provided in the ``Step1`` directory and can be
  30. used to compute the square root of a number.
  31. Adding a Version Number and Configured Header File
  32. --------------------------------------------------
  33. The first feature we will add is to provide our executable and project with a
  34. version number. While we could do this exclusively in the source code, using
  35. ``CMakeLists.txt`` provides more flexibility.
  36. First, modify the ``CMakeLists.txt`` file to use the :command:`project` command
  37. to set the project name and version number.
  38. .. literalinclude:: Step2/CMakeLists.txt
  39. :language: cmake
  40. :end-before: # specify the C++ standard
  41. Then, configure a header file to pass the version number to the source
  42. code:
  43. .. literalinclude:: Step2/CMakeLists.txt
  44. :language: cmake
  45. :start-after: # to the source code
  46. :end-before: # add the executable
  47. Since the configured file will be written into the binary tree, we
  48. must add that directory to the list of paths to search for include
  49. files. Add the following lines to the end of the ``CMakeLists.txt`` file:
  50. .. literalinclude:: Step2/CMakeLists.txt
  51. :language: cmake
  52. :start-after: # so that we will find TutorialConfig.h
  53. Using your favorite editor, create ``TutorialConfig.h.in`` in the source
  54. directory with the following contents:
  55. .. literalinclude:: Step2/TutorialConfig.h.in
  56. :language: cmake
  57. When CMake configures this header file the values for
  58. ``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will be
  59. replaced.
  60. Next modify ``tutorial.cxx`` to include the configured header file,
  61. ``TutorialConfig.h``.
  62. Finally, let's print out the executable name and version number by updating
  63. ``tutorial.cxx`` as follows:
  64. .. literalinclude:: Step2/tutorial.cxx
  65. :language: c++
  66. :start-after: {
  67. :end-before: // convert input to double
  68. Specify the C++ Standard
  69. -------------------------
  70. Next let's add some C++11 features to our project by replacing ``atof`` with
  71. ``std::stod`` in ``tutorial.cxx``. At the same time, remove
  72. ``#include <cstdlib>``.
  73. .. literalinclude:: Step2/tutorial.cxx
  74. :language: c++
  75. :start-after: // convert input to double
  76. :end-before: // calculate square root
  77. We will need to explicitly state in the CMake code that it should use the
  78. correct flags. The easiest way to enable support for a specific C++ standard
  79. in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this
  80. tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the
  81. ``CMakeLists.txt`` file to 11 and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to
  82. True. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call
  83. to ``add_executable``.
  84. .. literalinclude:: Step2/CMakeLists.txt
  85. :language: cmake
  86. :end-before: # configure a header file to pass some of the CMake settings
  87. Build and Test
  88. --------------
  89. Run the :manual:`cmake <cmake(1)>` executable or the
  90. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  91. with your chosen build tool.
  92. For example, from the command line we could navigate to the
  93. ``Help/guide/tutorial`` directory of the CMake source code tree and create a
  94. build directory:
  95. .. code-block:: console
  96. mkdir Step1_build
  97. Next, navigate to the build directory and run CMake to configure the project
  98. and generate a native build system:
  99. .. code-block:: console
  100. cd Step1_build
  101. cmake ../Step1
  102. Then call that build system to actually compile/link the project:
  103. .. code-block:: console
  104. cmake --build .
  105. Finally, try to use the newly built ``Tutorial`` with these commands:
  106. .. code-block:: console
  107. Tutorial 4294967296
  108. Tutorial 10
  109. Tutorial
  110. Adding a Library (Step 2)
  111. =========================
  112. Now we will add a library to our project. This library will contain our own
  113. implementation for computing the square root of a number. The executable can
  114. then use this library instead of the standard square root function provided by
  115. the compiler.
  116. For this tutorial we will put the library into a subdirectory
  117. called ``MathFunctions``. This directory already contains a header file,
  118. ``MathFunctions.h``, and a source file ``mysqrt.cxx``. The source file has one
  119. function called ``mysqrt`` that provides similar functionality to the
  120. compiler's ``sqrt`` function.
  121. Add the following one line ``CMakeLists.txt`` file to the ``MathFunctions``
  122. directory:
  123. .. literalinclude:: Step3/MathFunctions/CMakeLists.txt
  124. :language: cmake
  125. To make use of the new library we will add an :command:`add_subdirectory`
  126. call in the top-level ``CMakeLists.txt`` file so that the library will get
  127. built. We add the new library to the executable, and add ``MathFunctions`` as
  128. an include directory so that the ``mqsqrt.h`` header file can be found. The
  129. last few lines of the top-level ``CMakeLists.txt`` file should now look like:
  130. .. code-block:: cmake
  131. # add the MathFunctions library
  132. add_subdirectory(MathFunctions)
  133. # add the executable
  134. add_executable(Tutorial tutorial.cxx)
  135. target_link_libraries(Tutorial PUBLIC MathFunctions)
  136. # add the binary tree to the search path for include files
  137. # so that we will find TutorialConfig.h
  138. target_include_directories(Tutorial PUBLIC
  139. "${PROJECT_BINARY_DIR}"
  140. "${PROJECT_SOURCE_DIR}/MathFunctions"
  141. )
  142. Now let us make the MathFunctions library optional. While for the tutorial
  143. there really isn't any need to do so, for larger projects this is a common
  144. occurrence. The first step is to add an option to the top-level
  145. ``CMakeLists.txt`` file.
  146. .. literalinclude:: Step3/CMakeLists.txt
  147. :language: cmake
  148. :start-after: # should we use our own math functions
  149. :end-before: # add the MathFunctions library
  150. This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
  151. :manual:`ccmake <ccmake(1)>`
  152. with a default value of ON that can be changed by the user. This setting will
  153. be stored in the cache so that the user does not need to set the value each
  154. time they run CMake on a build directory.
  155. The next change is to make building and linking the MathFunctions library
  156. conditional. To do this we change the end of the top-level ``CMakeLists.txt``
  157. file to look like the following:
  158. .. literalinclude:: Step3/CMakeLists.txt
  159. :language: cmake
  160. :start-after: # add the MathFunctions library
  161. Note the use of the variable ``EXTRA_LIBS`` to collect up any optional
  162. libraries to later be linked into the executable. The variable
  163. ``EXTRA_INCLUDES`` is used similarly for optional header files. This is a
  164. classic approach when dealing with many optional components, we will cover
  165. the modern approach in the next step.
  166. The corresponding changes to the source code are fairly straightforward.
  167. First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we
  168. need it:
  169. .. literalinclude:: Step3/tutorial.cxx
  170. :language: c++
  171. :start-after: // should we include the MathFunctions header
  172. :end-before: int main
  173. Then, in the same file, make ``USE_MYMATH`` control which square root
  174. function is used:
  175. .. literalinclude:: Step3/tutorial.cxx
  176. :language: c++
  177. :start-after: // which square root function should we use?
  178. :end-before: std::cout << "The square root of
  179. Since the source code now requires ``USE_MYMATH`` we can add it to
  180. ``TutorialConfig.h.in`` with the following line:
  181. .. literalinclude:: Step3/TutorialConfig.h.in
  182. :language: c
  183. :lines: 4
  184. **Exercise**: Why is it important that we configure ``TutorialConfig.h.in``
  185. after the option for ``USE_MYMATH``? What would happen if we inverted the two?
  186. Run the :manual:`cmake <cmake(1)>` executable or the
  187. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  188. with your chosen build tool. Then run the built Tutorial executable.
  189. Now let's update the value of ``USE_MYMATH``. The easiest way is to use the
  190. :manual:`cmake-gui <cmake-gui(1)>` or :manual:`ccmake <ccmake(1)>` if you're
  191. in the terminal. Or, alternatively, if you want to change the option from the
  192. command-line, try:
  193. .. code-block:: console
  194. cmake ../Step2 -DUSE_MYMATH=OFF
  195. Rebuild and run the tutorial again.
  196. Which function gives better results, sqrt or mysqrt?
  197. Adding Usage Requirements for Library (Step 3)
  198. ==============================================
  199. Usage requirements allow for far better control over a library or executable's
  200. link and include line while also giving more control over the transitive
  201. property of targets inside CMake. The primary commands that leverage usage
  202. requirements are:
  203. - :command:`target_compile_definitions`
  204. - :command:`target_compile_options`
  205. - :command:`target_include_directories`
  206. - :command:`target_link_libraries`
  207. Let's refactor our code from `Adding a Library (Step 2)`_ to use the modern
  208. CMake approach of usage requirements. We first state that anybody linking to
  209. MathFunctions needs to include the current source directory, while
  210. MathFunctions itself doesn't. So this can become an ``INTERFACE`` usage
  211. requirement.
  212. Remember ``INTERFACE`` means things that consumers require but the producer
  213. doesn't. Add the following lines to the end of
  214. ``MathFunctions/CMakeLists.txt``:
  215. .. literalinclude:: Step4/MathFunctions/CMakeLists.txt
  216. :language: cmake
  217. :start-after: # to find MathFunctions.h
  218. Now that we've specified usage requirements for MathFunctions we can safely
  219. remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
  220. ``CMakeLists.txt``, here:
  221. .. literalinclude:: Step4/CMakeLists.txt
  222. :language: cmake
  223. :start-after: # add the MathFunctions library
  224. :end-before: # add the executable
  225. And here:
  226. .. literalinclude:: Step4/CMakeLists.txt
  227. :language: cmake
  228. :start-after: # so that we will find TutorialConfig.h
  229. Once this is done, run the :manual:`cmake <cmake(1)>` executable or the
  230. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  231. with your chosen build tool or by using ``cmake --build .`` from the build
  232. directory.
  233. Installing and Testing (Step 4)
  234. ===============================
  235. Now we can start adding install rules and testing support to our project.
  236. Install Rules
  237. -------------
  238. The install rules are fairly simple: for MathFunctions we want to install the
  239. library and header file and for the application we want to install the
  240. executable and configured header.
  241. So to the end of ``MathFunctions/CMakeLists.txt`` we add:
  242. .. literalinclude:: Step5/MathFunctions/CMakeLists.txt
  243. :language: cmake
  244. :start-after: # install rules
  245. And to the end of the top-level ``CMakeLists.txt`` we add:
  246. .. literalinclude:: Step5/CMakeLists.txt
  247. :language: cmake
  248. :start-after: # add the install targets
  249. :end-before: # enable testing
  250. That is all that is needed to create a basic local install of the tutorial.
  251. Now run the :manual:`cmake <cmake(1)>` executable or the
  252. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  253. with your chosen build tool.
  254. Then run the install step by using the ``install`` option of the
  255. :manual:`cmake <cmake(1)>` command (introduced in 3.15, older versions of
  256. CMake must use ``make install``) from the command line. For
  257. multi-configuration tools, don't forget to use the ``--config`` argument to
  258. specify the configuration. If using an IDE, simply build the ``INSTALL``
  259. target. This step will install the appropriate header files, libraries, and
  260. executables. For example:
  261. .. code-block:: console
  262. cmake --install .
  263. The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
  264. root of where the files will be installed. If using the ``cmake --install``
  265. command, the installation prefix can be overridden via the ``--prefix``
  266. argument. For example:
  267. .. code-block:: console
  268. cmake --install . --prefix "/home/myuser/installdir"
  269. Navigate to the install directory and verify that the installed Tutorial runs.
  270. Testing Support
  271. ---------------
  272. Next let's test our application. At the end of the top-level ``CMakeLists.txt``
  273. file we can enable testing and then add a number of basic tests to verify that
  274. the application is working correctly.
  275. .. literalinclude:: Step5/CMakeLists.txt
  276. :language: cmake
  277. :start-after: # enable testing
  278. The first test simply verifies that the application runs, does not segfault or
  279. otherwise crash, and has a zero return value. This is the basic form of a
  280. CTest test.
  281. The next test makes use of the :prop_test:`PASS_REGULAR_EXPRESSION` test
  282. property to verify that the output of the test contains certain strings. In
  283. this case, verifying that the usage message is printed when an incorrect number
  284. of arguments are provided.
  285. Lastly, we have a function called ``do_test`` that runs the application and
  286. verifies that the computed square root is correct for given input. For each
  287. invocation of ``do_test``, another test is added to the project with a name,
  288. input, and expected results based on the passed arguments.
  289. Rebuild the application and then cd to the binary directory and run the
  290. :manual:`ctest <ctest(1)>` executable: ``ctest -N`` and ``ctest -VV``. For
  291. multi-config generators (e.g. Visual Studio), the configuration type must be
  292. specified. To run tests in Debug mode, for example, use ``ctest -C Debug -VV``
  293. from the build directory (not the Debug subdirectory!). Alternatively, build
  294. the ``RUN_TESTS`` target from the IDE.
  295. Adding System Introspection (Step 5)
  296. ====================================
  297. Let us consider adding some code to our project that depends on features the
  298. target platform may not have. For this example, we will add some code that
  299. depends on whether or not the target platform has the ``log`` and ``exp``
  300. functions. Of course almost every platform has these functions but for this
  301. tutorial assume that they are not common.
  302. If the platform has ``log`` and ``exp`` then we will use them to compute the
  303. square root in the ``mysqrt`` function. We first test for the availability of
  304. these functions using the :module:`CheckSymbolExists` module in the top-level
  305. ``CMakeLists.txt``. On some platforms, we will need to link to the m library.
  306. If ``log`` and ``exp`` are not initially found, require the m library and try
  307. again.
  308. We're going to use the new defines in ``TutorialConfig.h.in``, so be sure to
  309. set them before that file is configured.
  310. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  311. :language: cmake
  312. :start-after: # does this system provide the log and exp functions?
  313. :end-before: # add compile definitions
  314. Now let's add these defines to ``TutorialConfig.h.in`` so that we can use them
  315. from ``mysqrt.cxx``:
  316. .. code-block:: console
  317. // does the platform provide exp and log functions?
  318. #cmakedefine HAVE_LOG
  319. #cmakedefine HAVE_EXP
  320. If ``log`` and ``exp`` are available on the system, then we will use them to
  321. compute the square root in the ``mysqrt`` function. Add the following code to
  322. the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the
  323. ``#endif`` before returning the result!):
  324. .. literalinclude:: Step6/MathFunctions/mysqrt.cxx
  325. :language: c++
  326. :start-after: // if we have both log and exp then use them
  327. :end-before: // do ten iterations
  328. We will also need to modify ``mysqrt.cxx`` to include ``cmath``.
  329. .. literalinclude:: Step6/MathFunctions/mysqrt.cxx
  330. :language: c++
  331. :end-before: #include <iostream>
  332. Run the :manual:`cmake <cmake(1)>` executable or the
  333. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  334. with your chosen build tool and run the Tutorial executable.
  335. You will notice that we're not using ``log`` and ``exp``, even if we think they
  336. should be available. We should realize quickly that we have forgotten to
  337. include ``TutorialConfig.h`` in ``mysqrt.cxx``.
  338. We will also need to update ``MathFunctions/CMakeLists.txt`` so ``mysqrt.cxx``
  339. knows where this file is located:
  340. .. code-block:: cmake
  341. target_include_directories(MathFunctions
  342. INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
  343. PRIVATE ${CMAKE_BINARY_DIR}
  344. )
  345. After making this update, go ahead and build the project again and run the
  346. built Tutorial executable. If ``log`` and ``exp`` are still not being used,
  347. open the generated ``TutorialConfig.h`` file from the build directory. Maybe
  348. they aren't available on the current system?
  349. Which function gives better results now, sqrt or mysqrt?
  350. Specify Compile Definition
  351. --------------------------
  352. Is there a better place for us to save the ``HAVE_LOG`` and ``HAVE_EXP`` values
  353. other than in ``TutorialConfig.h``? Let's try to use
  354. :command:`target_compile_definitions`.
  355. First, remove the defines from ``TutorialConfig.h.in``. We no longer need to
  356. include ``TutorialConfig.h`` from ``mysqrt.cxx`` or the extra include in
  357. ``MathFunctions/CMakeLists.txt``.
  358. Next, we can move the check for ``HAVE_LOG`` and ``HAVE_EXP`` to
  359. ``MathFunctions/CMakeLists.txt`` and then specify those values as ``PRIVATE``
  360. compile definitions.
  361. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  362. :language: cmake
  363. :start-after: # does this system provide the log and exp functions?
  364. :end-before: # install rules
  365. After making these updates, go ahead and build the project again. Run the
  366. built Tutorial executable and verify that the results are same as earlier in
  367. this step.
  368. Adding a Custom Command and Generated File (Step 6)
  369. ===================================================
  370. Suppose, for the purpose of this tutorial, we decide that we never want to use
  371. the platform ``log`` and ``exp`` functions and instead would like to
  372. generate a table of precomputed values to use in the ``mysqrt`` function.
  373. In this section, we will create the table as part of the build process,
  374. and then compile that table into our application.
  375. First, let's remove the check for the ``log`` and ``exp`` functions in
  376. ``MathFunctions/CMakeLists.txt``. Then remove the check for ``HAVE_LOG`` and
  377. ``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove
  378. :code:`#include <cmath>`.
  379. In the ``MathFunctions`` subdirectory, a new source file named
  380. ``MakeTable.cxx`` has been provided to generate the table.
  381. After reviewing the file, we can see that the table is produced as valid C++
  382. code and that the output filename is passed in as an argument.
  383. The next step is to add the appropriate commands to the
  384. ``MathFunctions/CMakeLists.txt`` file to build the MakeTable executable and
  385. then run it as part of the build process. A few commands are needed to
  386. accomplish this.
  387. First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for
  388. ``MakeTable`` is added as any other executable would be added.
  389. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt
  390. :language: cmake
  391. :start-after: # first we add the executable that generates the table
  392. :end-before: # add the command to generate the source code
  393. Then we add a custom command that specifies how to produce ``Table.h``
  394. by running MakeTable.
  395. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt
  396. :language: cmake
  397. :start-after: # add the command to generate the source code
  398. :end-before: # add the main library
  399. Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
  400. file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
  401. of sources for the library MathFunctions.
  402. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt
  403. :language: cmake
  404. :start-after: # add the main library
  405. :end-before: # state that anybody linking
  406. We also have to add the current binary directory to the list of include
  407. directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
  408. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt
  409. :language: cmake
  410. :start-after: # state that we depend on our bin
  411. :end-before: # install rules
  412. Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
  413. ``Table.h``. Next, we can rewrite the mysqrt function to use the table:
  414. .. literalinclude:: Step7/MathFunctions/mysqrt.cxx
  415. :language: c++
  416. :start-after: // a hack square root calculation using simple operations
  417. Run the :manual:`cmake <cmake(1)>` executable or the
  418. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  419. with your chosen build tool.
  420. When this project is built it will first build the ``MakeTable`` executable.
  421. It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will
  422. compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the MathFunctions
  423. library.
  424. Run the Tutorial executable and verify that it is using the table.
  425. Building an Installer (Step 7)
  426. ==============================
  427. Next suppose that we want to distribute our project to other people so that
  428. they can use it. We want to provide both binary and source distributions on a
  429. variety of platforms. This is a little different from the install we did
  430. previously in `Installing and Testing (Step 4)`_ , where we were
  431. installing the binaries that we had built from the source code. In this
  432. example we will be building installation packages that support binary
  433. installations and package management features. To accomplish this we will use
  434. CPack to create platform specific installers. Specifically we need to add a
  435. few lines to the bottom of our top-level ``CMakeLists.txt`` file.
  436. .. literalinclude:: Step8/CMakeLists.txt
  437. :language: cmake
  438. :start-after: # setup installer
  439. That is all there is to it. We start by including
  440. :module:`InstallRequiredSystemLibraries`. This module will include any runtime
  441. libraries that are needed by the project for the current platform. Next we set
  442. some CPack variables to where we have stored the license and version
  443. information for this project. The version information was set earlier in this
  444. tutorial and the ``license.txt`` has been included in the top-level source
  445. directory for this step.
  446. Finally we include the :module:`CPack module <CPack>` which will use these
  447. variables and some other properties of the current system to setup an
  448. installer.
  449. The next step is to build the project in the usual manner and then run the
  450. :manual:`cpack <cpack(1)>` executable. To build a binary distribution, from the
  451. binary directory run:
  452. .. code-block:: console
  453. cpack
  454. To specify the generator, use the ``-G`` option. For multi-config builds, use
  455. ``-C`` to specify the configuration. For example:
  456. .. code-block:: console
  457. cpack -G ZIP -C Debug
  458. To create a source distribution you would type:
  459. .. code-block:: console
  460. cpack --config CPackSourceConfig.cmake
  461. Alternatively, run ``make package`` or right click the ``Package`` target and
  462. ``Build Project`` from an IDE.
  463. Run the installer found in the binary directory. Then run the installed
  464. executable and verify that it works.
  465. Adding Support for a Dashboard (Step 8)
  466. =======================================
  467. Adding support for submitting our test results to a dashboard is simple. We
  468. already defined a number of tests for our project in `Testing Support`_. Now we
  469. just have to run those tests and submit them to a dashboard. To include support
  470. for dashboards we include the :module:`CTest` module in our top-level
  471. ``CMakeLists.txt``.
  472. Replace:
  473. .. code-block:: cmake
  474. # enable testing
  475. enable_testing()
  476. With:
  477. .. code-block:: cmake
  478. # enable dashboard scripting
  479. include(CTest)
  480. The :module:`CTest` module will automatically call ``enable_testing()``, so we
  481. can remove it from our CMake files.
  482. We will also need to create a ``CTestConfig.cmake`` file in the top-level
  483. directory where we can specify the name of the project and where to submit the
  484. dashboard.
  485. .. literalinclude:: Step9/CTestConfig.cmake
  486. :language: cmake
  487. The :manual:`ctest <ctest(1)>` executable will read in this file when it runs.
  488. To create a simple dashboard you can run the :manual:`cmake <cmake(1)>`
  489. executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project,
  490. but do not build it yet. Instead, change directory to the binary tree, and then
  491. run:
  492. ctest [-VV] -D Experimental
  493. Remember, for multi-config generators (e.g. Visual Studio), the configuration
  494. type must be specified::
  495. ctest [-VV] -C Debug -D Experimental
  496. Or, from an IDE, build the ``Experimental`` target.
  497. The :manual:`ctest <ctest(1)>` executable will build and test the project and
  498. submit the results to Kitware's public dashboard:
  499. https://my.cdash.org/index.php?project=CMakeTutorial.
  500. Mixing Static and Shared (Step 9)
  501. =================================
  502. In this section we will show how the :variable:`BUILD_SHARED_LIBS` variable can
  503. be used to control the default behavior of :command:`add_library`,
  504. and allow control over how libraries without an explicit type (``STATIC``,
  505. ``SHARED``, ``MODULE`` or ``OBJECT``) are built.
  506. To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
  507. top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
  508. users to optionally select if the value should be ON or OFF.
  509. Next we are going to refactor MathFunctions to become a real library that
  510. encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling
  511. code to do this logic. This will also mean that ``USE_MYMATH`` will not control
  512. building MathFunctions, but instead will control the behavior of this library.
  513. The first step is to update the starting section of the top-level
  514. ``CMakeLists.txt`` to look like:
  515. .. literalinclude:: Step10/CMakeLists.txt
  516. :language: cmake
  517. :end-before: # add the binary tree
  518. Now that we have made MathFunctions always be used, we will need to update
  519. the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
  520. create a SqrtLibrary that will conditionally be built and installed when
  521. ``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
  522. explicitly require that SqrtLibrary is built statically.
  523. The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
  524. .. literalinclude:: Step10/MathFunctions/CMakeLists.txt
  525. :language: cmake
  526. :lines: 1-36,42-
  527. Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and
  528. ``detail`` namespaces:
  529. .. literalinclude:: Step10/MathFunctions/mysqrt.cxx
  530. :language: c++
  531. We also need to make some changes in ``tutorial.cxx``, so that it no longer
  532. uses ``USE_MYMATH``:
  533. #. Always include ``MathFunctions.h``
  534. #. Always use ``mathfunctions::sqrt``
  535. #. Don't include cmath
  536. Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
  537. .. literalinclude:: Step10/MathFunctions/MathFunctions.h
  538. :language: c++
  539. At this point, if you build everything, you may notice that linking fails
  540. as we are combining a static library without position independent code with a
  541. library that has position independent code. The solution to this is to
  542. explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
  543. SqrtLibrary to be True no matter the build type.
  544. .. literalinclude:: Step10/MathFunctions/CMakeLists.txt
  545. :language: cmake
  546. :lines: 37-42
  547. **Exercise**: We modified ``MathFunctions.h`` to use dll export defines.
  548. Using CMake documentation can you find a helper module to simplify this?
  549. Adding Generator Expressions (Step 10)
  550. ======================================
  551. :manual:`Generator expressions <cmake-generator-expressions(7)>` are evaluated
  552. during build system generation to produce information specific to each build
  553. configuration.
  554. :manual:`Generator expressions <cmake-generator-expressions(7)>` are allowed in
  555. the context of many target properties, such as :prop_tgt:`LINK_LIBRARIES`,
  556. :prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and others.
  557. They may also be used when using commands to populate those properties, such as
  558. :command:`target_link_libraries`, :command:`target_include_directories`,
  559. :command:`target_compile_definitions` and others.
  560. :manual:`Generator expressions <cmake-generator-expressions(7)>` may be used
  561. to enable conditional linking, conditional definitions used when compiling,
  562. conditional include directories and more. The conditions may be based on the
  563. build configuration, target properties, platform information or any other
  564. queryable information.
  565. There are different types of
  566. :manual:`generator expressions <cmake-generator-expressions(7)>` including
  567. Logical, Informational, and Output expressions.
  568. Logical expressions are used to create conditional output. The basic
  569. expressions are the 0 and 1 expressions. A ``$<0:...>`` results in the empty
  570. string, and ``<1:...>`` results in the content of "...". They can also be
  571. nested.
  572. A common usage of
  573. :manual:`generator expressions <cmake-generator-expressions(7)>` is to
  574. conditionally add compiler flags, such as those for language levels or
  575. warnings. A nice pattern is to associate this information to an ``INTERFACE``
  576. target allowing this information to propagate. Let's start by constructing an
  577. ``INTERFACE`` target and specifying the required C++ standard level of ``11``
  578. instead of using :variable:`CMAKE_CXX_STANDARD`.
  579. So the following code:
  580. .. literalinclude:: Step10/CMakeLists.txt
  581. :language: cmake
  582. :start-after: project(Tutorial VERSION 1.0)
  583. :end-before: # control where the static and shared libraries are built so that on windows
  584. Would be replaced with:
  585. .. literalinclude:: Step11/CMakeLists.txt
  586. :language: cmake
  587. :start-after: project(Tutorial VERSION 1.0)
  588. :end-before: # add compiler warning flags just when building this project via
  589. Next we add the desired compiler warning flags that we want for our project. As
  590. warning flags vary based on the compiler we use the ``COMPILE_LANG_AND_ID``
  591. generator expression to control which flags to apply given a language and a set
  592. of compiler ids as seen below:
  593. .. literalinclude:: Step11/CMakeLists.txt
  594. :language: cmake
  595. :start-after: # the BUILD_INTERFACE genex
  596. :end-before: # control where the static and shared libraries are built so that on windows
  597. Looking at this we see that the warning flags are encapsulated inside a
  598. ``BUILD_INTERFACE`` condition. This is done so that consumers of our installed
  599. project will not inherit our warning flags.
  600. **Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that all targets have
  601. a :command:`target_link_libraries` call to ``tutorial_compiler_flags``.
  602. Adding Export Configuration (Step 11)
  603. =====================================
  604. During `Installing and Testing (Step 4)`_ of the tutorial we added the ability
  605. for CMake to install the library and headers of the project. During
  606. `Building an Installer (Step 7)`_ we added the ability to package up this
  607. information so it could be distributed to other people.
  608. The next step is to add the necessary information so that other CMake projects
  609. can use our project, be it from a build directory, a local install or when
  610. packaged.
  611. The first step is to update our :command:`install(TARGETS)` commands to not
  612. only specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword
  613. generates and installs a CMake file containing code to import all targets
  614. listed in the install command from the installation tree. So let's go ahead and
  615. explicitly ``EXPORT`` the MathFunctions library by updating the ``install``
  616. command in ``MathFunctions/CMakeLists.txt`` to look like:
  617. .. literalinclude:: Complete/MathFunctions/CMakeLists.txt
  618. :language: cmake
  619. :start-after: # install rules
  620. Now that we have MathFunctions being exported, we also need to explicitly
  621. install the generated ``MathFunctionsTargets.cmake`` file. This is done by
  622. adding the following to the bottom of the top-level ``CMakeLists.txt``:
  623. .. literalinclude:: Complete/CMakeLists.txt
  624. :language: cmake
  625. :start-after: # install the configuration targets
  626. :end-before: include(CMakePackageConfigHelpers)
  627. At this point you should try and run CMake. If everything is setup properly
  628. you will see that CMake will generate an error that looks like:
  629. .. code-block:: console
  630. Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains
  631. path:
  632. "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions"
  633. which is prefixed in the source directory.
  634. What CMake is trying to say is that during generating the export information
  635. it will export a path that is intrinsically tied to the current machine and
  636. will not be valid on other machines. The solution to this is to update the
  637. MathFunctions :command:`target_include_directories` to understand that it needs
  638. different ``INTERFACE`` locations when being used from within the build
  639. directory and from an install / package. This means converting the
  640. :command:`target_include_directories` call for MathFunctions to look like:
  641. .. literalinclude:: Step12/MathFunctions/CMakeLists.txt
  642. :language: cmake
  643. :start-after: # to find MathFunctions.h, while we don't.
  644. :end-before: # should we use our own math functions
  645. Once this has been updated, we can re-run CMake and verify that it doesn't
  646. warn anymore.
  647. At this point, we have CMake properly packaging the target information that is
  648. required but we will still need to generate a ``MathFunctionsConfig.cmake`` so
  649. that the CMake :command:`find_package` command can find our project. So let's go
  650. ahead and add a new file to the top-level of the project called
  651. ``Config.cmake.in`` with the following contents:
  652. .. literalinclude:: Step12/Config.cmake.in
  653. Then, to properly configure and install that file, add the following to the
  654. bottom of the top-level ``CMakeLists.txt``:
  655. .. literalinclude:: Step12/CMakeLists.txt
  656. :language: cmake
  657. :start-after: # install the configuration targets
  658. :end-before: # generate the export
  659. At this point, we have generated a relocatable CMake Configuration for our
  660. project that can be used after the project has been installed or packaged. If
  661. we want our project to also be used from a build directory we only have to add
  662. the following to the bottom of the top level ``CMakeLists.txt``:
  663. .. literalinclude:: Step12/CMakeLists.txt
  664. :language: cmake
  665. :start-after: # needs to be after the install(TARGETS ) command
  666. With this export call we now generate a ``Targets.cmake``, allowing the
  667. configured ``MathFunctionsConfig.cmake`` in the build directory to be used by
  668. other projects, without needing it to be installed.
  669. Packaging Debug and Release (Step 12)
  670. =====================================
  671. **Note:** This example is valid for single-configuration generators and will
  672. not work for multi-configuration generators (e.g. Visual Studio).
  673. By default, CMake's model is that a build directory only contains a single
  674. configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is
  675. possible, however, to setup CPack to bundle multiple build directories and
  676. construct a package that contains multiple configurations of the same project.
  677. First, we want to ensure that the debug and release builds use different names
  678. for the executables and libraries that will be installed. Let's use `d` as the
  679. postfix for the debug executable and libraries.
  680. Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level
  681. ``CMakeLists.txt`` file:
  682. .. literalinclude:: Complete/CMakeLists.txt
  683. :language: cmake
  684. :start-after: project(Tutorial VERSION 1.0)
  685. :end-before: target_compile_features(tutorial_compiler_flags
  686. And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable:
  687. .. literalinclude:: Complete/CMakeLists.txt
  688. :language: cmake
  689. :start-after: # add the executable
  690. :end-before: # add the binary tree to the search path for include files
  691. Let's also add version numbering to the MathFunctions library. In
  692. ``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and
  693. :prop_tgt:`SOVERSION` properties:
  694. .. literalinclude:: Complete/MathFunctions/CMakeLists.txt
  695. :language: cmake
  696. :start-after: # setup the version numbering
  697. :end-before: # install rules
  698. From the ``Step12`` directory, create ``debug`` and ``release``
  699. subbdirectories. The layout will look like:
  700. .. code-block:: none
  701. - Step12
  702. - debug
  703. - release
  704. Now we need to setup debug and release builds. We can use
  705. :variable:`CMAKE_BUILD_TYPE` to set the configuration type:
  706. .. code-block:: console
  707. cd debug
  708. cmake -DCMAKE_BUILD_TYPE=Debug ..
  709. cmake --build .
  710. cd ../release
  711. cmake -DCMAKE_BUILD_TYPE=Release ..
  712. cmake --build .
  713. Now that both the debug and release builds are complete, we can use a custom
  714. configuration file to package both builds into a single release. In the
  715. ``Step12`` directory, create a file called ``MultiCPackConfig.cmake``. In this
  716. file, first include the default configuration file that was created by the
  717. :manual:`cmake <cmake(1)>` executable.
  718. Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which
  719. projects to install. In this case, we want to install both debug and release.
  720. .. literalinclude:: Complete/MultiCPackConfig.cmake
  721. :language: cmake
  722. From the ``Step12`` directory, run :manual:`cpack <cpack(1)>` specifying our
  723. custom configuration file with the ``config`` option:
  724. .. code-block:: console
  725. cpack --config MultiCPackConfig.cmake