Installing and Testing.rst 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. Step 5: Installing and Testing
  2. ==============================
  3. Exercise 1 - Install Rules
  4. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  5. Often, it is not enough to only build an executable, it should also be
  6. installable. With CMake, we can specify install rules using the
  7. :command:`install` command. Supporting local installations for your builds in
  8. CMake is often as simple as specifying an install location and the targets and
  9. files to be installed.
  10. Goal
  11. ----
  12. Install the ``Tutorial`` executable and the ``MathFunctions`` library.
  13. Helpful Materials
  14. -----------------
  15. * :command:`install`
  16. Files to Edit
  17. -------------
  18. * ``MathFunctions/CMakeLists.txt``
  19. * ``CMakeLists.txt``
  20. Getting Started
  21. ---------------
  22. The starting code is provided in the ``Step5`` directory. In this
  23. exercise, complete ``TODO 1`` through ``TODO 4``.
  24. First, update ``MathFunctions/CMakeLists.txt`` to install the
  25. ``MathFunctions`` and ``tutorial_compiler_flags`` libraries to the ``lib``
  26. directory. In that same file, specify the install rules needed to install
  27. ``MathFunctions.h`` to the ``include`` directory.
  28. Then, update the top level ``CMakeLists.txt`` to install
  29. the ``Tutorial`` executable to the ``bin`` directory. Lastly, any header files
  30. should be installed to the ``include`` directory. Remember that
  31. ``TutorialConfig.h`` is in the :variable:`PROJECT_BINARY_DIR`.
  32. Build and Run
  33. -------------
  34. Make a new directory called ``Step5_build``. Run the
  35. :manual:`cmake <cmake(1)>` executable or the
  36. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  37. with your chosen build tool.
  38. Then, run the install step by using the :option:`--install <cmake --install>`
  39. option of the :manual:`cmake <cmake(1)>` command (introduced in 3.15, older
  40. versions of CMake must use ``make install``) from the command line. This step
  41. will install the appropriate header files, libraries, and executables.
  42. For example:
  43. .. code-block:: console
  44. cmake --install .
  45. For multi-configuration tools, don't forget to use the
  46. :option:`--config <cmake--build --config>` argument to specify the configuration.
  47. .. code-block:: console
  48. cmake --install . --config Release
  49. If using an IDE, simply build the ``INSTALL`` target. You can build the same
  50. install target from the command line like the following:
  51. .. code-block:: console
  52. cmake --build . --target install --config Debug
  53. The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
  54. root of where the files will be installed. If using the :option:`cmake --install`
  55. command, the installation prefix can be overridden via the
  56. :option:`--prefix <cmake--install --prefix>` argument. For example:
  57. .. code-block:: console
  58. cmake --install . --prefix "/home/myuser/installdir"
  59. Navigate to the install directory and verify that the installed ``Tutorial``
  60. runs.
  61. Solution
  62. --------
  63. The install rules for our project are fairly simple:
  64. * For ``MathFunctions``, we want to install the libraries and header file to
  65. the ``lib`` and ``include`` directories respectively.
  66. * For the ``Tutorial`` executable, we want to install the executable and
  67. configured header file to the ``bin`` and ``include`` directories
  68. respectively.
  69. So to the end of ``MathFunctions/CMakeLists.txt`` we add:
  70. .. raw:: html
  71. <details><summary>TODO 1: Click to show/hide answer</summary>
  72. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  73. :caption: TODO 1: MathFunctions/CMakeLists.txt
  74. :name: MathFunctions/CMakeLists.txt-install-TARGETS
  75. :language: cmake
  76. :start-after: # install libs
  77. :end-before: # install include headers
  78. .. raw:: html
  79. </details>
  80. and
  81. .. raw:: html
  82. <details><summary>TODO 2: Click to show/hide answer</summary>
  83. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  84. :caption: TODO 2: MathFunctions/CMakeLists.txt
  85. :name: MathFunctions/CMakeLists.txt-install-headers
  86. :language: cmake
  87. :start-after: # install include headers
  88. .. raw:: html
  89. </details>
  90. The install rules for the ``Tutorial`` executable and configured header file
  91. are similar. To the end of the top-level ``CMakeLists.txt`` we add:
  92. .. raw:: html
  93. <details><summary>TODO 3,4: Click to show/hide answer</summary>
  94. .. literalinclude:: Step6/CMakeLists.txt
  95. :caption: CMakeLists.txt
  96. :name: TODO 3,4: CMakeLists.txt-install-TARGETS
  97. :language: cmake
  98. :start-after: # add the install targets
  99. :end-before: # TODO 1: Replace enable_testing() with include(CTest)
  100. .. raw:: html
  101. </details>
  102. That is all that is needed to create a basic local
  103. install of the tutorial.
  104. .. _`Tutorial Testing Support`:
  105. Exercise 2 - Testing Support
  106. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  107. CTest offers a way to easily manage tests for your project. Tests can be
  108. added through the :command:`add_test` command. Although it is not
  109. explicitly covered in this tutorial, there is a lot of compatibility
  110. between CTest and other testing frameworks such as :module:`GoogleTest`.
  111. Goal
  112. ----
  113. Create unit tests for our executable using CTest.
  114. Helpful Materials
  115. -----------------
  116. * :command:`enable_testing`
  117. * :command:`add_test`
  118. * :command:`function`
  119. * :command:`set_tests_properties`
  120. * :manual:`ctest <ctest(1)>`
  121. Files to Edit
  122. -------------
  123. * ``CMakeLists.txt``
  124. Getting Started
  125. ---------------
  126. The starting source code is provided in the ``Step5`` directory. In this
  127. exercise, complete ``TODO 5`` through ``TODO 9``.
  128. First, we need to enable testing. Next, begin adding tests to our project
  129. using :command:`add_test`. We will work through adding 3 simple tests and
  130. then you can add additional testing as you see fit.
  131. Build and Run
  132. -------------
  133. Navigate to the build directory and rebuild the application. Then, run the
  134. :program:`ctest` executable: :option:`ctest -N` and :option:`ctest -VV`. For
  135. multi-config generators (e.g. Visual Studio), the configuration type must be
  136. specified with the :option:`-C \<mode\> <ctest -C>` flag. For example, to run tests in Debug
  137. mode use ``ctest -C Debug -VV`` from the build directory
  138. (not the Debug subdirectory!). Release mode would be executed from the same
  139. location but with a ``-C Release``. Alternatively, build the ``RUN_TESTS``
  140. target from the IDE.
  141. Solution
  142. --------
  143. Let's test our application. At the end of the top-level ``CMakeLists.txt``
  144. file we first need to enable testing with the
  145. :command:`enable_testing` command.
  146. .. raw:: html
  147. <details><summary>TODO 5: Click to show/hide answer</summary>
  148. .. literalinclude:: Step6/CMakeLists.txt
  149. :caption: TODO 5: CMakeLists.txt
  150. :name: CMakeLists.txt-enable_testing
  151. :language: cmake
  152. :start-after: # enable testing
  153. :end-before: # does the application run
  154. .. raw:: html
  155. </details>
  156. With testing enabled, we will add a number of basic tests to verify
  157. that the application is working correctly. First, we create a test using
  158. :command:`add_test` which runs the ``Tutorial`` executable with the
  159. parameter 25 passed in. For this test, we are not going to check the
  160. executable's computed answer. This test will verify that
  161. application runs, does not segfault or otherwise crash, and has a zero
  162. return value. This is the basic form of a CTest test.
  163. .. raw:: html
  164. <details><summary>TODO 6: Click to show/hide answer</summary>
  165. .. literalinclude:: Step6/CMakeLists.txt
  166. :caption: TODO 6: CMakeLists.txt
  167. :name: CMakeLists.txt-test-runs
  168. :language: cmake
  169. :start-after: # does the application run
  170. :end-before: # does the usage message work
  171. .. raw:: html
  172. </details>
  173. Next, let's use the :prop_test:`PASS_REGULAR_EXPRESSION` test property to
  174. verify that the output of the test contains certain strings. In this case,
  175. verifying that the usage message is printed when an incorrect number of
  176. arguments are provided.
  177. .. raw:: html
  178. <details><summary>TODO 7: Click to show/hide answer</summary>
  179. .. literalinclude:: Step6/CMakeLists.txt
  180. :caption: TODO 7: CMakeLists.txt
  181. :name: CMakeLists.txt-test-usage
  182. :language: cmake
  183. :start-after: # does the usage message work?
  184. :end-before: # define a function to simplify adding tests
  185. .. raw:: html
  186. </details>
  187. The next test we will add verifies the computed value is truly the
  188. square root.
  189. .. raw:: html
  190. <details><summary>TODO 8: Click to show/hide answer</summary>
  191. .. code-block:: cmake
  192. :caption: TODO 8: CMakeLists.txt
  193. :name: CMakeLists.txt-test-standard
  194. add_test(NAME StandardUse COMMAND Tutorial 4)
  195. set_tests_properties(StandardUse
  196. PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
  197. )
  198. .. raw:: html
  199. </details>
  200. This one test is not enough to give us confidence that it will
  201. work for all values passed in. We should add more tests to verify this.
  202. To easily add more tests, we make a function called ``do_test`` that runs the
  203. application and verifies that the computed square root is correct for
  204. given input. For each invocation of ``do_test``, another test is added to
  205. the project with a name, input, and expected results based on the passed
  206. arguments.
  207. .. raw:: html
  208. <details><summary>TODO 9: Click to show/hide answer</summary>
  209. .. literalinclude:: Step6/CMakeLists.txt
  210. :caption: TODO 9: CMakeLists.txt
  211. :name: CMakeLists.txt-generalized-tests
  212. :language: cmake
  213. :start-after: # define a function to simplify adding tests
  214. .. raw:: html
  215. </details>