Browse Source

Tutorial: Update step 7 style

Markus Ferrell 3 years ago
parent
commit
f9ef15f3dc

+ 128 - 25
Help/guide/tutorial/Adding System Introspection.rst

@@ -7,53 +7,156 @@ 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:`CheckCXXSourceCompiles` module in
+Exercise 1 - Assessing Dependency Availability
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Goal
+----
+
+Change implementation based on available system dependencies.
+
+Helpful Resources
+-----------------
+
+* :module:`CheckCXXSourceCompiles`
+* :command:`target_compile_definitions`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/mysqrt.cxx``
+
+Getting Started
+---------------
+
+The starting source code is provided in the ``Step7`` directory. In this
+exercise, complete ``TODO 1`` through ``TODO 5``.
+
+Start by editing ``MathFunctions/CMakeLists.txt``. Include the
+:module:`CheckCXXSourceCompiles` module. Then, use
+``check_cxx_source_compiles`` to determine whether ``log`` and ``exp`` are
+available from ``cmath``. If they are available, use
+:command:`target_compile_definitions` to specify ``HAVE_LOG`` and ``HAVE_EXP``
+as compile definitions.
+
+In the ``MathFunctions/mysqrt.cxx``, include ``cmath``. Then, if the system has
+``log`` and ``exp``, use them to compute the square root.
+
+Build and Run
+-------------
+
+Make a new directory called ``Step7_build``. 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.
+
+This can look like the following:
+
+.. code-block:: console
+
+  mkdir Step7_build
+  cd Step7_build
+  cmake ../Step7
+  cmake --build .
+
+Which function gives better results now, ``sqrt`` or ``mysqrt``?
+
+Solution
+--------
+
+In this exercise we will use functions from the
+:module:`CheckCXXSourceCompiles` module so first we must include it in
 ``MathFunctions/CMakeLists.txt``.
 
-Add the checks for ``log`` and ``exp`` to ``MathFunctions/CMakeLists.txt``,
-after the call to :command:`target_include_directories`:
+.. raw:: html
+
+  <details><summary>TODO 1: Click to show/hide answer</summary>
 
 .. literalinclude:: Step8/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
+  :caption: TODO 1: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-include-check_cxx_source_compiles
+  :language: cmake
+  :start-after: # does this system provide the log and exp functions?
+  :end-before: check_cxx_source_compiles
+
+.. raw:: html
+
+  </details>
+
+Then test for the availability of
+``log`` and ``exp`` using ``check_cxx_compiles_source``. This function
+lets us try compiling simple code with the required dependency prior to
+the true source code compilation. The resulting variables ``HAVE_LOG``
+and ``HAVE_EXP`` represent whether those dependencies are available.
+
+.. raw:: html
+
+  <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
+  :caption: TODO 2: MathFunctions/CMakeLists.txt
   :name: MathFunctions/CMakeLists.txt-check_cxx_source_compiles
   :language: cmake
-  :start-after: # to find MathFunctions.h, while we don't.
+  :start-after: include(CheckCXXSourceCompiles)
   :end-before: # add compile definitions
 
-If available, use :command:`target_compile_definitions` to specify
+.. raw:: html
+
+  </details>
+
+Next, we need to pass these CMake variables to our source code. This way,
+our source code can tell what resources are available. If both ``log`` and
+``exp`` are available, use :command:`target_compile_definitions` to specify
 ``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions.
 
+.. raw:: html
+
+  <details><summary>TODO 3: Click to show/hide answer</summary>
+
 .. literalinclude:: Step8/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
+  :caption: TODO 3: MathFunctions/CMakeLists.txt
   :name: MathFunctions/CMakeLists.txt-target_compile_definitions
   :language: cmake
   :start-after: # add compile definitions
   :end-before: # install libs
 
-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!):
+.. raw:: html
 
-.. literalinclude:: Step8/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
+  </details>
+
+Since we may be using ``log`` and ``exp``, we need to modify
+``mysqrt.cxx`` to include ``cmath``.
+
+.. raw:: html
 
-We will also need to modify ``mysqrt.cxx`` to include ``cmath``.
+  <details><summary>TODO 4: Click to show/hide answer</summary>
 
 .. literalinclude:: Step8/MathFunctions/mysqrt.cxx
-  :caption: MathFunctions/mysqrt.cxx
+  :caption: TODO 4: 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.
+.. raw:: html
 
-Which function gives better results now, ``sqrt`` or ``mysqrt``?
+  </details>
+
+If ``log`` and ``exp`` are available on the system, then use them to
+compute the square root in the ``mysqrt`` function. The ``mysqrt`` function in
+``MathFunctions/mysqrt.cxx`` will look as follows:
+
+.. raw:: html
+
+  <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
+  :caption: TODO 5: 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
+
+.. raw:: html
+
+  </details>

+ 20 - 0
Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt

@@ -9,6 +9,26 @@ target_include_directories(MathFunctions
 # link our compiler flags interface library
 target_link_libraries(MathFunctions tutorial_compiler_flags)
 
+# TODO 1: Include CheckCXXSourceCompiles
+
+# TODO 2: Use check_cxx_source_compiles with simple C++ code to verify
+# availability of:
+# * std::log
+# * std::exp
+# Store the results in HAVE_LOG and HAVE_EXP respectively.
+
+# Hint: Sample C++ code which uses log:
+# #include <cmath>
+# int main() {
+#   std::log(1.0);
+#   return 0;
+# }
+
+# TODO 3: Conditionally on HAVE_LOG and HAVE_EXP, add private compile
+# definitions "HAVE_LOG" and "HAVE_EXP" to the MathFunctions target.
+
+#Hint: Use target_compile_definitions()
+
 # install libs
 set(installable_libs MathFunctions tutorial_compiler_flags)
 install(TARGETS ${installable_libs} DESTINATION lib)

+ 10 - 0
Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx

@@ -1,5 +1,6 @@
 #include <iostream>
 
+// TODO 4: include cmath
 #include "MathFunctions.h"
 
 // a hack square root calculation using simple operations
@@ -9,6 +10,14 @@ double mysqrt(double x)
     return 0;
   }
 
+  // TODO 5: If both HAVE_LOG and HAVE_EXP are defined,  use the following:
+  //// double result = std::exp(std::log(x) * 0.5);
+  //// std::cout << "Computing sqrt of " << x << " to be " << result
+  ////        << " using log and exp" << std::endl;
+  // else, use the existing logic.
+
+  // Hint: Don't forget the #endif before returning the result!
+
   double result = x;
 
   // do ten iterations
@@ -20,5 +29,6 @@ double mysqrt(double x)
     result = result + 0.5 * delta / result;
     std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
   }
+
   return result;
 }