Step 5: Adding System Introspection | |
=================================== | |
Let us consider adding some code to our project that depends on features the | |
target platform may not have. For this example, we will add some code that | |
depends on whether or not the target platform has the ``log`` and ``exp`` | |
functions. Of course almost every platform has these functions but for this | |
tutorial assume that they are not common. | |
If the platform has ``log`` and ``exp`` then we will use them to compute the | |
square root in the ``mysqrt`` function. We first test for the availability of | |
these functions using the :module:`CheckSymbolExists` module in | |
``MathFunctions/CMakeLists.txt``. On some platforms, we will need to link to | |
the ``m`` library. If ``log`` and ``exp`` are not initially found, require the | |
``m`` library and try again. | |
Add the checks for ``log`` and ``exp`` to ``MathFunctions/CMakeLists.txt``, | |
after the call to :command:`target_include_directories`: | |
.. literalinclude:: Step6/MathFunctions/CMakeLists.txt | |
:caption: MathFunctions/CMakeLists.txt | |
:name: MathFunctions/CMakeLists.txt-check_symbol_exists | |
:language: cmake | |
:start-after: # to find MathFunctions.h, while we don't. | |
:end-before: # add compile definitions | |
If available, use :command:`target_compile_definitions` to specify | |
``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions. | |
.. literalinclude:: Step6/MathFunctions/CMakeLists.txt | |
:caption: MathFunctions/CMakeLists.txt | |
:name: MathFunctions/CMakeLists.txt-target_compile_definitions | |
:language: cmake | |
:start-after: # add compile definitions | |
:end-before: # install rules | |
If ``log`` and ``exp`` are available on the system, then we will use them to | |
compute the square root in the ``mysqrt`` function. Add the following code to | |
the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the | |
``#endif`` before returning the result!): | |
.. literalinclude:: Step6/MathFunctions/mysqrt.cxx | |
:caption: MathFunctions/mysqrt.cxx | |
:name: MathFunctions/mysqrt.cxx-ifdef | |
:language: c++ | |
:start-after: // if we have both log and exp then use them | |
:end-before: // do ten iterations | |
We will also need to modify ``mysqrt.cxx`` to include ``cmath``. | |
.. literalinclude:: Step6/MathFunctions/mysqrt.cxx | |
:caption: MathFunctions/mysqrt.cxx | |
:name: MathFunctions/mysqrt.cxx-include-cmath | |
:language: c++ | |
:end-before: #include <iostream> | |
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 and run the Tutorial executable. | |
Which function gives better results now, ``sqrt`` or ``mysqrt``? |