# 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 CheckSymbolExists.cmake macro in the top-level CMakeLists file as follows: # does this system provide the log and exp functions? include(CheckSymbolExists) set(CMAKE_REQUIRED_LIBRARIES "m") check_symbol_exists(log "math.h" HAVE_LOG) check_symbol_exists(exp "math.h" HAVE_EXP) Now let's add these defines to TutorialConfig.h.in so that we can use them from mysqrt.cxx: // does the platform provide exp and log functions? #cmakedefine HAVE_LOG #cmakedefine HAVE_EXP Modify mysqrt.cxx to include math.h. Next, in the mysqrt function we can provide an alternate implementation based on log and exp if they are available on the system using the following code: // if we have both log and exp then use them #if defined(HAVE_LOG) && defined (HAVE_EXP) double result = exp(log(x)*0.5); std::cout << "Computing sqrt of " << x << " to be " << result << " using log" << std::endl; #else ... Run cmake or cmake-gui to configure the project and then build it with your chosen build tool. You will notice that even though HAVE_LOG and HAVE_EXP are both defined mysqrt isn't using them. We should realize quickly that we have forgotten to include TutorialConfig.h in mysqrt.cxx. We will also need to update MathFunctions/CMakeLists.txt with where it is located. So let's go ahead and update MathFunctions/CMakeLists.txt to look like: add_library(MathFunctions mysqrt.cxx) target_include_directories(MathFunctions INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${Tutorial_BINARY_DIR} ) install(TARGETS MathFunctions DESTINATION lib) install(FILES MathFunctions.h DESTINATION include) Now all we need to do is include TutorialConfig.h in mysqrt.cxx At this point you should go ahead and build the project again. Run the built Tutorial executable. Which function gives better results now, Step1’s sqrt or Step5’s mysqrt? Exercise: Why is it important that we configure TutorialConfig.h.in after the checks for HAVE_LOG and HAVE_EXP? What would happen if we inverted the two? Exercise: Is there a better place for us to save the HAVE_LOG and HAVE_EXP values other than in TutorialConfig.h?