Adding a Custom Command and Generated File — CMake 4.0.2 Documentation (original) (raw)

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 inMathFunctions/CMakeLists.txt. Then remove the check for HAVE_LOG andHAVE_EXP from mysqrt.cxx. At the same time, we can remove#include <cmath>.

In the MathFunctions subdirectory, a new source file namedMakeTable.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.

MathFunctions/MakeTable.cmake

add_executable(MakeTable MakeTable.cxx)

After creating the executable, we add the tutorial_compiler_flags to our executable using target_link_libraries().

MathFunctions/MakeTable.cmake

target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)

Then we add a custom command that specifies how to produce Table.hby running MakeTable.

MathFunctions/MakeTable.cmake

add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h DEPENDS MakeTable )

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.

MathFunctions/CMakeLists.txt

add_library(SqrtLibrary STATIC mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h )

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.

MathFunctions/CMakeLists.txt

target_include_directories(SqrtLibrary PRIVATE ${CMAKE_CURRENT_BINARY_DIR} )

link SqrtLibrary to tutorial_compiler_flags

As the last step, we need to includeMakeTable.cmake at the top of the MathFunctions/CMakeLists.txt.

MathFunctions/CMakeLists.txt

Now let's use the generated table. First, modify mysqrt.cxx to includeTable.h. Next, we can rewrite the mysqrt function to use the table:

MathFunctions/mysqrt.cxx

double mysqrt(double x) { if (x <= 0) { return 0; }

// use the table to help find an initial value double result = x; if (x >= 1 && x < 10) { std::cout << "Use the table to help find an initial value " << std::endl; result = sqrtTable[static_cast(x)]; }

// do ten iterations for (int i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } double delta = x - (result * result); result = result + 0.5 * delta / result; std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; }

return result; } } }

Run the cmake executable or thecmake-gui 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 theMathFunctions library.

Run the Tutorial executable and verify that it is using the table.