Tutorial: Simplify logic checking for cmath functions

Since commit 07223c5c27 (Tutorial: Update Step 5 to work on Windows,
2020-02-18, v3.18.0-rc1~655^2) the logic does not work on non-Windows
platforms when cmake is re-run on an existing build tree.  It is also
more complicated than we'd like for a tutorial example.  Avoid the need
to consider the `m` library case by performing the check as C++.

Since `check_cxx_symbol_exists` cannot handle overloaded functions
like `exp` and `log`, check with `check_cxx_source_compiles` instead.
This also presents a more general-purpose example in the tutorial.

Fixes: #23524
This commit is contained in:
Brad King
2022-06-01 13:30:51 -04:00
parent 18be0f9267
commit 5c84eca210
3 changed files with 19 additions and 19 deletions
@@ -9,17 +9,15 @@ tutorial assume that they are not common.
If the platform has ``log`` and ``exp`` then we will use them to compute the 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 square root in the ``mysqrt`` function. We first test for the availability of
these functions using the :module:`CheckSymbolExists` module in these functions using the :module:`CheckCXXSourceCompiles` module in
``MathFunctions/CMakeLists.txt``. On some platforms, we will need to link to ``MathFunctions/CMakeLists.txt``.
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``, Add the checks for ``log`` and ``exp`` to ``MathFunctions/CMakeLists.txt``,
after the call to :command:`target_include_directories`: after the call to :command:`target_include_directories`:
.. literalinclude:: Step6/MathFunctions/CMakeLists.txt .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt :caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-check_symbol_exists :name: MathFunctions/CMakeLists.txt-check_cxx_source_compiles
:language: cmake :language: cmake
:start-after: # to find MathFunctions.h, while we don't. :start-after: # to find MathFunctions.h, while we don't.
:end-before: # add compile definitions :end-before: # add compile definitions
@@ -7,19 +7,21 @@ target_include_directories(MathFunctions
) )
# does this system provide the log and exp functions? # does this system provide the log and exp functions?
include(CheckSymbolExists) include(CheckCXXSourceCompiles)
check_symbol_exists(log "math.h" HAVE_LOG) check_cxx_source_compiles("
check_symbol_exists(exp "math.h" HAVE_EXP) #include <cmath>
if(NOT (HAVE_LOG AND HAVE_EXP)) int main() {
unset(HAVE_LOG CACHE) std::log(1.0);
unset(HAVE_EXP CACHE) return 0;
set(CMAKE_REQUIRED_LIBRARIES "m") }
check_symbol_exists(log "math.h" HAVE_LOG) " HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP) check_cxx_source_compiles("
if(HAVE_LOG AND HAVE_EXP) #include <cmath>
target_link_libraries(MathFunctions PRIVATE m) int main() {
endif() std::exp(1.0);
endif() return 0;
}
" HAVE_EXP)
# add compile definitions # add compile definitions
if(HAVE_LOG AND HAVE_EXP) if(HAVE_LOG AND HAVE_EXP)
@@ -12,7 +12,7 @@ double mysqrt(double x)
// if we have both log and exp then use them // if we have both log and exp then use them
#if defined(HAVE_LOG) && defined(HAVE_EXP) #if defined(HAVE_LOG) && defined(HAVE_EXP)
double result = exp(log(x) * 0.5); double result = std::exp(std::log(x) * 0.5);
std::cout << "Computing sqrt of " << x << " to be " << result std::cout << "Computing sqrt of " << x << " to be " << result
<< " using log and exp" << std::endl; << " using log and exp" << std::endl;
#else #else