|
|
|
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.
|