| 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``? |