| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- # 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?
|