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