Adding a Custom Command and Generated File.rst 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. Step 8: Adding a Custom Command and Generated File
  2. ==================================================
  3. Suppose, for the purpose of this tutorial, we decide that we never want to use
  4. the platform ``log`` and ``exp`` functions and instead would like to
  5. generate a table of precomputed values to use in the ``mysqrt`` function.
  6. In this section, we will create the table as part of the build process,
  7. and then compile that table into our application.
  8. First, let's remove the check for the ``log`` and ``exp`` functions in
  9. ``MathFunctions/CMakeLists.txt``. Then remove the check for ``HAVE_LOG`` and
  10. ``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove
  11. :code:`#include <cmath>`.
  12. In the ``MathFunctions`` subdirectory, a new source file named
  13. ``MakeTable.cxx`` has been provided to generate the table.
  14. After reviewing the file, we can see that the table is produced as valid C++
  15. code and that the output filename is passed in as an argument.
  16. The next step is to create ``MathFunctions/MakeTable.cmake``. Then, add the
  17. appropriate commands to the file to build the ``MakeTable`` executable and
  18. then run it as part of the build process. A few commands are needed to
  19. accomplish this.
  20. First, we add an executable for ``MakeTable``.
  21. .. literalinclude:: Step9/MathFunctions/MakeTable.cmake
  22. :caption: MathFunctions/MakeTable.cmake
  23. :name: MathFunctions/MakeTable.cmake-add_executable-MakeTable
  24. :language: cmake
  25. :start-after: # first we add the executable that generates the table
  26. :end-before: target_link_libraries
  27. After creating the executable, we add the ``tutorial_compiler_flags`` to our
  28. executable using :command:`target_link_libraries`.
  29. .. literalinclude:: Step9/MathFunctions/MakeTable.cmake
  30. :caption: MathFunctions/MakeTable.cmake
  31. :name: MathFunctions/MakeTable.cmake-link-tutorial-compiler-flags
  32. :language: cmake
  33. :start-after: add_executable
  34. :end-before: # add the command to generate
  35. Then we add a custom command that specifies how to produce ``Table.h``
  36. by running MakeTable.
  37. .. literalinclude:: Step9/MathFunctions/MakeTable.cmake
  38. :caption: MathFunctions/MakeTable.cmake
  39. :name: MathFunctions/MakeTable.cmake-add_custom_command-Table.h
  40. :language: cmake
  41. :start-after: # add the command to generate the source code
  42. Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
  43. file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
  44. of sources for the library ``SqrtLibrary``.
  45. .. literalinclude:: Step9/MathFunctions/CMakeLists.txt
  46. :caption: MathFunctions/CMakeLists.txt
  47. :name: MathFunctions/CMakeLists.txt-add_library-Table.h
  48. :language: cmake
  49. :start-after: # library that just does sqrt
  50. :end-before: # state that we depend on
  51. We also have to add the current binary directory to the list of include
  52. directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
  53. .. literalinclude:: Step9/MathFunctions/CMakeLists.txt
  54. :caption: MathFunctions/CMakeLists.txt
  55. :name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
  56. :language: cmake
  57. :start-after: # state that we depend on our bin
  58. :end-before: target_link_libraries
  59. As the last step, we need to include
  60. ``MakeTable.cmake`` at the top of the ``MathFunctions/CMakeLists.txt``.
  61. .. literalinclude:: Step9/MathFunctions/CMakeLists.txt
  62. :caption: MathFunctions/CMakeLists.txt
  63. :name: MathFunctions/CMakeLists.txt-include-MakeTable.cmake
  64. :language: cmake
  65. :start-after: # generate Table.h
  66. :end-before: # library that just does sqrt
  67. Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
  68. ``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:
  69. .. literalinclude:: Step9/MathFunctions/mysqrt.cxx
  70. :caption: MathFunctions/mysqrt.cxx
  71. :name: MathFunctions/mysqrt.cxx
  72. :language: c++
  73. :start-after: // a hack square root calculation using simple operations
  74. Run the :manual:`cmake <cmake(1)>` executable or the
  75. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  76. with your chosen build tool.
  77. When this project is built it will first build the ``MakeTable`` executable.
  78. It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will
  79. compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the
  80. ``MathFunctions`` library.
  81. Run the Tutorial executable and verify that it is using the table.