| Step 8: Adding a Custom Command and Generated File | |
| ================================================== | |
| Suppose, for the purpose of this tutorial, we decide that we never want to use | |
| the platform ``log`` and ``exp`` functions and instead would like to | |
| generate a table of precomputed values to use in the ``mysqrt`` function. | |
| In this section, we will create the table as part of the build process, | |
| and then compile that table into our application. | |
| First, let's remove the check for the ``log`` and ``exp`` functions in | |
| ``MathFunctions/CMakeLists.txt``. Then remove the check for ``HAVE_LOG`` and | |
| ``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove | |
| :code:`#include <cmath>`. | |
| In the ``MathFunctions`` subdirectory, a new source file named | |
| ``MakeTable.cxx`` has been provided to generate the table. | |
| After reviewing the file, we can see that the table is produced as valid C++ | |
| code and that the output filename is passed in as an argument. | |
| The next step is to create ``MathFunctions/MakeTable.cmake``. Then, add the | |
| appropriate commands to the file to build the ``MakeTable`` executable and | |
| then run it as part of the build process. A few commands are needed to | |
| accomplish this. | |
| First, we add an executable for ``MakeTable``. | |
| .. literalinclude:: Step9/MathFunctions/MakeTable.cmake | |
| :caption: MathFunctions/MakeTable.cmake | |
| :name: MathFunctions/MakeTable.cmake-add_executable-MakeTable | |
| :language: cmake | |
| :start-after: # first we add the executable that generates the table | |
| :end-before: target_link_libraries | |
| After creating the executable, we add the ``tutorial_compiler_flags`` to our | |
| executable using :command:`target_link_libraries`. | |
| .. literalinclude:: Step9/MathFunctions/MakeTable.cmake | |
| :caption: MathFunctions/MakeTable.cmake | |
| :name: MathFunctions/MakeTable.cmake-link-tutorial-compiler-flags | |
| :language: cmake | |
| :start-after: add_executable | |
| :end-before: # add the command to generate | |
| Then we add a custom command that specifies how to produce ``Table.h`` | |
| by running MakeTable. | |
| .. literalinclude:: Step9/MathFunctions/MakeTable.cmake | |
| :caption: MathFunctions/MakeTable.cmake | |
| :name: MathFunctions/MakeTable.cmake-add_custom_command-Table.h | |
| :language: cmake | |
| :start-after: # add the command to generate the source code | |
| Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated | |
| file ``Table.h``. This is done by adding the generated ``Table.h`` to the list | |
| of sources for the library ``SqrtLibrary``. | |
| .. literalinclude:: Step9/MathFunctions/CMakeLists.txt | |
| :caption: MathFunctions/CMakeLists.txt | |
| :name: MathFunctions/CMakeLists.txt-add_library-Table.h | |
| :language: cmake | |
| :start-after: # library that just does sqrt | |
| :end-before: # state that we depend on | |
| We also have to add the current binary directory to the list of include | |
| directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``. | |
| .. literalinclude:: Step9/MathFunctions/CMakeLists.txt | |
| :caption: MathFunctions/CMakeLists.txt | |
| :name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h | |
| :language: cmake | |
| :start-after: # state that we depend on our bin | |
| :end-before: target_link_libraries | |
| As the last step, we need to include | |
| ``MakeTable.cmake`` at the top of the ``MathFunctions/CMakeLists.txt``. | |
| .. literalinclude:: Step9/MathFunctions/CMakeLists.txt | |
| :caption: MathFunctions/CMakeLists.txt | |
| :name: MathFunctions/CMakeLists.txt-include-MakeTable.cmake | |
| :language: cmake | |
| :start-after: # generate Table.h | |
| :end-before: # library that just does sqrt | |
| Now let's use the generated table. First, modify ``mysqrt.cxx`` to include | |
| ``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table: | |
| .. literalinclude:: Step9/MathFunctions/mysqrt.cxx | |
| :caption: MathFunctions/mysqrt.cxx | |
| :name: MathFunctions/mysqrt.cxx | |
| :language: c++ | |
| :start-after: // a hack square root calculation using simple operations | |
| Run the :manual:`cmake <cmake(1)>` executable or the | |
| :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it | |
| with your chosen build tool. | |
| When this project is built it will first build the ``MakeTable`` executable. | |
| It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will | |
| compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the | |
| ``MathFunctions`` library. | |
| Run the Tutorial executable and verify that it is using the table. |