Tutorial: Refactor MathFunctions code

Propagate the refactor in Step 10 MathFunctions through all of the
steps. Use MathFunctions/MathFunctions.cxx instead of Tutorial.cxx
to determine which sqrt library is called. Adds .h files which
correspond to their .cxx files by name.
This commit is contained in:
Markus Ferrell
2023-02-10 16:07:06 -05:00
parent 78299083d2
commit 8ddf32196c
81 changed files with 650 additions and 521 deletions
@@ -160,7 +160,7 @@ The last command to call for a basic project is
:name: CMakeLists.txt-add_executable :name: CMakeLists.txt-add_executable
:language: cmake :language: cmake
:start-after: # add the executable :start-after: # add the executable
:end-before: # TODO 9: :end-before: # TODO 3:
.. raw:: html .. raw:: html
@@ -240,7 +240,7 @@ the following:
:name: tutorial.cxx-cxx11 :name: tutorial.cxx-cxx11
:language: c++ :language: c++
:start-after: // convert input to double :start-after: // convert input to double
:end-before: // TODO 12: :end-before: // TODO 6:
.. raw:: html .. raw:: html
@@ -265,7 +265,7 @@ add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
:name: CMakeLists.txt-CXX_STANDARD :name: CMakeLists.txt-CXX_STANDARD
:language: cmake :language: cmake
:start-after: # specify the C++ standard :start-after: # specify the C++ standard
:end-before: # TODO 7: :end-before: # configure a header file
.. raw:: html .. raw:: html
@@ -375,7 +375,7 @@ specified CMake variables replaced:
:name: CMakeLists.txt-configure_file :name: CMakeLists.txt-configure_file
:language: cmake :language: cmake
:start-after: # to the source code :start-after: # to the source code
:end-before: # TODO 8: :end-before: # TODO 2:
.. raw:: html .. raw:: html
@@ -420,7 +420,6 @@ be replaced with the corresponding version numbers from the project in
:caption: TODO 10: TutorialConfig.h.in :caption: TODO 10: TutorialConfig.h.in
:name: TutorialConfig.h.in :name: TutorialConfig.h.in
:language: c++ :language: c++
:end-before: // TODO 13:
.. raw:: html .. raw:: html
@@ -299,7 +299,7 @@ condition. The resulting full code looks like the following:
:name: CMakeLists.txt-target_compile_options-genex :name: CMakeLists.txt-target_compile_options-genex
:language: cmake :language: cmake
:start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>") :start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
:end-before: # should we use our own math functions :end-before: # configure a header file to pass some of the CMake settings
.. raw:: html .. raw:: html
@@ -119,7 +119,7 @@ our source code can tell what resources are available. If both ``log`` and
:name: MathFunctions/CMakeLists.txt-target_compile_definitions :name: MathFunctions/CMakeLists.txt-target_compile_definitions
:language: cmake :language: cmake
:start-after: # add compile definitions :start-after: # add compile definitions
:end-before: # install libs :end-before: # state
.. raw:: html .. raw:: html
@@ -136,7 +136,8 @@ Since we may be using ``log`` and ``exp``, we need to modify
:caption: TODO 4: MathFunctions/mysqrt.cxx :caption: TODO 4: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-include-cmath :name: MathFunctions/mysqrt.cxx-include-cmath
:language: c++ :language: c++
:end-before: #include <iostream> :start-after: #include "mysqrt.h"
:end-before: include <iostream>
.. raw:: html .. raw:: html
@@ -100,7 +100,7 @@ follows:
:name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE :name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
:language: cmake :language: cmake
:start-after: # to find MathFunctions.h :start-after: # to find MathFunctions.h
:end-before: # TODO 3: Link to :end-before: option
.. raw:: html .. raw:: html
@@ -119,7 +119,7 @@ safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
:name: CMakeLists.txt-remove-EXTRA_INCLUDES :name: CMakeLists.txt-remove-EXTRA_INCLUDES
:language: cmake :language: cmake
:start-after: # add the MathFunctions library :start-after: # add the MathFunctions library
:end-before: # add the executable :end-before: # TODO 2: Link to tutorial_compiler_flags
.. raw:: html .. raw:: html
@@ -23,15 +23,25 @@ The next step is to add the appropriate commands to the
then run it as part of the build process. A few commands are needed to then run it as part of the build process. A few commands are needed to
accomplish this. accomplish this.
First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for First, in the ``USE_MYMATH`` section of ``MathFunctions/CMakeLists.txt``,
``MakeTable`` is added as any other executable would be added. we add an executable for ``MakeTable``.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt .. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt :caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_executable-MakeTable :name: MathFunctions/CMakeLists.txt-add_executable-MakeTable
:language: cmake :language: cmake
:start-after: # first we add the executable that generates the table :start-after: # first we add the executable that generates the table
:end-before: # add the command to generate the source code :end-before: target_link_libraries
After creating the executable, we add the ``tutorial_compiler_flags`` to our
executable using :command:`target_link_libraries`.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-link-tutorial-compiler-flags
:language: cmake
:start-after: add_executable
:end-before: # add the command to generate
Then we add a custom command that specifies how to produce ``Table.h`` Then we add a custom command that specifies how to produce ``Table.h``
by running MakeTable. by running MakeTable.
@@ -41,7 +51,7 @@ by running MakeTable.
:name: MathFunctions/CMakeLists.txt-add_custom_command-Table.h :name: MathFunctions/CMakeLists.txt-add_custom_command-Table.h
:language: cmake :language: cmake
:start-after: # add the command to generate the source code :start-after: # add the command to generate the source code
:end-before: # add the main library :end-before: # library that just does sqrt
Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
file ``Table.h``. This is done by adding the generated ``Table.h`` to the list file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
@@ -51,8 +61,8 @@ of sources for the library MathFunctions.
:caption: MathFunctions/CMakeLists.txt :caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-Table.h :name: MathFunctions/CMakeLists.txt-add_library-Table.h
:language: cmake :language: cmake
:start-after: # add the main library :start-after: # library that just does sqrt
:end-before: # state that anybody linking :end-before: # state that we depend on
We also have to add the current binary directory to the list of include We also have to add the current binary directory to the list of include
directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``. directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
@@ -62,7 +72,19 @@ directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
:name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h :name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
:language: cmake :language: cmake
:start-after: # state that we depend on our bin :start-after: # state that we depend on our bin
:end-before: # install libs :end-before: target_link_libraries
As the last thing in our ``USE_MYMATH`` section, we need to link the our
flags onto ``SqrtLibrary`` and then link ``SqrtLibrary`` onto
``MathFunctions``. This makes the resulting ``USE_MYMATH`` section look like
the following:
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-full_USE_MYMATH-section
:language: cmake
:start-after: if (USE_MYMATH)
:end-before: endif()
Now let's use the generated table. First, modify ``mysqrt.cxx`` to include Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table: ``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:
+74 -147
View File
@@ -51,11 +51,13 @@ then use this library instead of the standard square root function provided by
the compiler. the compiler.
For this tutorial we will put the library into a subdirectory called For this tutorial we will put the library into a subdirectory called
``MathFunctions``. This directory already contains a header file, ``MathFunctions``. This directory already contains the header files
``MathFunctions.h``, and a source file ``mysqrt.cxx``. We will not need to ``MathFunctions.h`` and ``mysqrt.h``. Their respective source files
modify either of these files. The source file has one function called ``MathFunctions.cxx`` and ``mysqrt.cxx`` are also provided. We will not need
to modify any of these files. ``mysqrt.cxx`` has one function called
``mysqrt`` that provides similar functionality to the compiler's ``sqrt`` ``mysqrt`` that provides similar functionality to the compiler's ``sqrt``
function. function. ``MathFunctions.cxx`` contains one function ``sqrt`` which serves
to hide the implementation details of ``sqrt``.
From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and
complete through ``TODO 6``. complete through ``TODO 6``.
@@ -91,10 +93,10 @@ Solution
In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
a library target called ``MathFunctions`` with :command:`add_library`. The a library target called ``MathFunctions`` with :command:`add_library`. The
source file for the library is passed as an argument to source files for the library are passed as an argument to
:command:`add_library`. This looks like the following line: :command:`add_library`. This looks like the following line:
.. raw:: html .. raw:: html/
<details><summary>TODO 1: Click to show/hide answer</summary> <details><summary>TODO 1: Click to show/hide answer</summary>
@@ -171,36 +173,40 @@ Now let's use our library. In ``tutorial.cxx``, include ``MathFunctions.h``:
<details><summary>TODO 5: Click to show/hide answer</summary> <details><summary>TODO 5: Click to show/hide answer</summary>
.. code-block:: c++ .. literalinclude:: Step3/tutorial.cxx
:caption: TODO 5 : tutorial.cxx :caption: TODO 5: tutorial.cxx
:name: tutorial.cxx-include_MathFunctions.h :name: CMakeLists.txt-include-MathFunctions.h
:language: cmake
#include "MathFunctions.h" :start-after: #include <string>
:end-before: #include "TutorialConfig.h"
.. raw:: html .. raw:: html
</details> </details>
Lastly, replace ``sqrt`` with our library function ``mysqrt``. Lastly, replace ``sqrt`` with our library function ``mathfunctions::mysqrt``.
.. raw:: html .. raw:: html
<details><summary>TODO 6: Click to show/hide answer</summary> <details><summary>TODO 6: Click to show/hide answer</summary>
.. code-block:: c++ .. literalinclude:: Step3/tutorial.cxx
:caption: TODO 6 : tutorial.cxx :caption: TODO 7: tutorial.cxx
:name: tutorial.cxx-call_mysqrt :name: CMakeLists.txt-option
:language: cmake
const double outputValue = mysqrt(inputValue); :start-after: const double inputValue = std::stod(argv[1]);
:end-before: std::cout
.. raw:: html .. raw:: html
</details> </details>
Exercise 2 - Making Our Library Optional Exercise 2 - Adding an Option
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now let us make the MathFunctions library optional. While for the tutorial Now let us add an option in the MathFunctions library to allow developers to
select either the custom square root implementation or the built in standard
implementation. While for the tutorial
there really isn't any need to do so, for larger projects this is a common there really isn't any need to do so, for larger projects this is a common
occurrence. occurrence.
@@ -219,28 +225,26 @@ Helpful Resources
----------------- -----------------
* :command:`if` * :command:`if`
* :command:`list`
* :command:`option` * :command:`option`
* :command:`cmakedefine <configure_file>` * :command:`target_compile_definitions`
Files to Edit Files to Edit
------------- -------------
* ``CMakeLists.txt`` * ``MathFunctions/CMakeLists.txt``
* ``tutorial.cxx`` * ``MathFunctions/MathFunctions.cxx``
* ``TutorialConfig.h.in``
Getting Started Getting Started
--------------- ---------------
Start with the resulting files from Exercise 1. Complete ``TODO 7`` through Start with the resulting files from Exercise 1. Complete ``TODO 7`` through
``TODO 13``. ``TODO 9``.
First create a variable ``USE_MYMATH`` using the :command:`option` command First create a variable ``USE_MYMATH`` using the :command:`option` command
in the top-level ``CMakeLists.txt`` file. In that same file, use that option in ``MathFunctions/CMakeLists.txt``. In that same file, use that option
to determine whether to build and use the ``MathFunctions`` library. to pass a compile definition to the ``MathFunctions`` library.
Then, update ``tutorial.cxx`` and ``TutorialConfig.h.in`` to use Then, update ``MathFunctions.cxx`` to redirect compilation based on
``USE_MYMATH``. ``USE_MYMATH``.
Build and Run Build and Run
@@ -279,7 +283,7 @@ or ``mysqrt``?
Solution Solution
-------- --------
The first step is to add an option to the top-level ``CMakeLists.txt`` file. The first step is to add an option to ``MathFunctions/CMakeLists.txt``.
This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
:manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be :manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
changed by the user. changed by the user.
@@ -288,172 +292,95 @@ changed by the user.
<details><summary>TODO 7: Click to show/hide answer</summary> <details><summary>TODO 7: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 7: CMakeLists.txt :caption: TODO 7: MathFunctions/CMakeLists.txt
:name: CMakeLists.txt-option :name: CMakeLists.txt-option-library-level
:language: cmake :language: cmake
:start-after: # should we use our own math functions :start-after: # should we use our own math functions
:end-before: # configure a header file to pass some of the CMake settings :end-before: if (USE_MYMATH)
.. raw:: html .. raw:: html
</details> </details>
Next, make building and linking the ``MathFunctions`` library Next, make building and linking our library with ``mysqrt`` function
conditional. conditional using this new option.
Start by creating a :command:`list` of the optional library targets for our Create an :command:`if` statement which checks the value of
project. At the moment, it is just ``MathFunctions``. Let's name our list
``EXTRA_LIBS``.
Similarly, we need to make a :command:`list` for the optional includes which
we will call ``EXTRA_INCLUDES``. In this list, we will ``APPEND`` the path of
the header file needed for our library.
Next, create an :command:`if` statement which checks the value of
``USE_MYMATH``. Inside the :command:`if` block, put the ``USE_MYMATH``. Inside the :command:`if` block, put the
:command:`add_subdirectory` command from Exercise 1 with the additional :command:`target_compile_definitions` command with the compile
:command:`list` commands. definition ``USE_MYMATH``.
When ``USE_MYMATH`` is ``ON``, the lists will be generated and will be added to
our project. When ``USE_MYMATH`` is ``OFF``, the lists stay empty. With this
strategy, we allow users to toggle ``USE_MYMATH`` to manipulate what library is
used in the build.
The top-level CMakeLists.txt file will now look like the following:
.. raw:: html .. raw:: html
<details><summary>TODO 8: Click to show/hide answer</summary> <details><summary>TODO 8: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 8: CMakeLists.txt :caption: TODO 8: MathFunctions/CMakeLists.txt
:name: CMakeLists.txt-USE_MYMATH :name: CMakeLists.txt-USE_MYMATH
:language: cmake :language: cmake
:start-after: # add the MathFunctions library :start-after: USE_MYMATH "Use tutorial provided math implementation" ON)
:end-before: # add the executable
.. raw:: html .. raw:: html
</details> </details>
Now that we have these two lists, we need to update The corresponding changes to the source code are fairly straightforward.
:command:`target_link_libraries` and :command:`target_include_directories` to In ``MathFunctions.cxx``, we make ``USE_MYMATH`` control which square root
use them. Changing them is fairly straightforward. function is used:
For :command:`target_link_libraries`, we replace the written out
library names with ``EXTRA_LIBS``. This looks like the following:
.. raw:: html .. raw:: html
<details><summary>TODO 9: Click to show/hide answer</summary> <details><summary>TODO 9: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
:caption: TODO 9: CMakeLists.txt :caption: TODO 9: MathFunctions/MathFunctions.cxx
:name: CMakeLists.txt-target_link_libraries-EXTRA_LIBS :name: MathFunctions-USE_MYMATH-if
:language: cmake :language: c++
:start-after: add_executable(Tutorial tutorial.cxx) :start-after: which square root function should we use?
:end-before: # TODO 3 :end-before: }
.. raw:: html .. raw:: html
</details> </details>
Then, we do the same thing with :command:`target_include_directories` and Next, we need to include ``mysqrt.h`` if ``USE_MYMATH`` is defined.
``EXTRA_INCLUDES``.
.. raw:: html .. raw:: html
<details><summary>TODO 10: Click to show/hide answer</summary> <details><summary>TODO 10: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
:caption: TODO 10 : CMakeLists.txt :caption: TODO 10: MathFunctions/MathFunctions.cxx
:name: CMakeLists.txt-target_link_libraries-EXTRA_INCLUDES :name: MathFunctions-USE_MYMATH-if-include
:language: cmake :language: c++
:start-after: # so that we will find TutorialConfig.h :start-after: include <cmath>
:end-before: namespace mathfunctions
.. raw:: html .. raw:: html
</details> </details>
Note that this is a classic approach when dealing with many components. We Finally, we need to include ``cmath`` now that we are using ``std::sqrt``.
will cover the modern approach in the Step 3 of the tutorial.
The corresponding changes to the source code are fairly straightforward.
First, in ``tutorial.cxx``, we include the ``MathFunctions.h`` header if
``USE_MYMATH`` is defined.
.. raw:: html .. raw:: html
<details><summary>TODO 11: Click to show/hide answer</summary> <details><summary>TODO 11: Click to show/hide answer</summary>
.. literalinclude:: Step3/tutorial.cxx .. code-block:: c++
:caption: TODO 11 : tutorial.cxx :caption: TODO 11 : MathFunctions/MathFunctions.cxx
:name: tutorial.cxx-ifdef-include :name: tutorial.cxx-include_cmath
:language: c++
:start-after: // should we include the MathFunctions header #include <cmath>
:end-before: int main
.. raw:: html .. raw:: html
</details> </details>
Then, in the same file, we make ``USE_MYMATH`` control which square root When ``USE_MYMATH`` is ``ON``, the compile definition ``USE_MYMATH`` will
function is used: be set. We can then use this compile definition to enable or disable
sections of our source code. With this strategy, we allow users to
toggle ``USE_MYMATH`` to manipulate what library is used in the build.
.. raw:: html With these changes, the ``mysqrt`` function is now completely optional to
whoever is building and using the ``MathFunctions`` library.
<details><summary>TODO 12: Click to show/hide answer</summary>
.. literalinclude:: Step3/tutorial.cxx
:caption: TODO 12 : tutorial.cxx
:name: tutorial.cxx-ifdef-const
:language: c++
:start-after: // which square root function should we use?
:end-before: std::cout << "The square root of
.. raw:: html
</details>
Since the source code now requires ``USE_MYMATH`` we can add it to
``TutorialConfig.h.in`` with the following line:
.. raw:: html
<details><summary>TODO 13: Click to show/hide answer</summary>
.. literalinclude:: Step3/TutorialConfig.h.in
:caption: TODO 13 : TutorialConfig.h.in
:name: TutorialConfig.h.in-cmakedefine
:language: c++
:lines: 4
.. raw:: html
</details>
With these changes, our library is now completely optional to whoever is
building and using it.
Bonus Question
--------------
Why is it important that we configure ``TutorialConfig.h.in``
after the option for ``USE_MYMATH``? What would happen if we inverted the two?
Answer
------
.. raw:: html
<details><summary>Click to show/hide answer</summary>
We configure after because ``TutorialConfig.h.in`` uses the value of
``USE_MYMATH``. If we configure the file before
calling :command:`option`, we won't be using the expected value of
``USE_MYMATH``.
.. raw:: html
</details>
@@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else
@@ -10,49 +10,22 @@ To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
users to optionally select if the value should be ``ON`` or ``OFF``. users to optionally select if the value should be ``ON`` or ``OFF``.
Next we are going to refactor ``MathFunctions`` to become a real library that
encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling
code to do this logic. This will also mean that ``USE_MYMATH`` will not control
building ``MathFunctions``, but instead will control the behavior of this
library.
The first step is to update the starting section of the top-level
``CMakeLists.txt`` to look like:
.. literalinclude:: Step11/CMakeLists.txt .. literalinclude:: Step11/CMakeLists.txt
:caption: CMakeLists.txt :caption: CMakeLists.txt
:name: CMakeLists.txt-option-BUILD_SHARED_LIBS :name: CMakeLists.txt-option-BUILD_SHARED_LIBS
:language: cmake :language: cmake
:end-before: # add the binary tree :start-after: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
:end-before: # configure a header file to pass the version number only
Now that we have made ``MathFunctions`` always be used, we will need to update Next, we need to specify output directories for our static and shared
the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to libraries.
create a SqrtLibrary that will conditionally be built and installed when
``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
explicitly require that SqrtLibrary is built statically.
The end result is that ``MathFunctions/CMakeLists.txt`` should look like: .. literalinclude:: Step11/CMakeLists.txt
:caption: CMakeLists.txt
.. literalinclude:: Step11/MathFunctions/CMakeLists.txt :name: CMakeLists.txt-cmake-output-directories
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-STATIC
:language: cmake :language: cmake
:lines: 1-36,42- :start-after: # we don't need to tinker with the path to run the executable
:end-before: # configure a header file to pass the version number only
Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and
``detail`` namespaces:
.. literalinclude:: Step11/MathFunctions/mysqrt.cxx
:caption: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-namespace
:language: c++
We also need to make some changes in ``tutorial.cxx``, so that it no longer
uses ``USE_MYMATH``:
#. Always include ``MathFunctions.h``
#. Always use ``mathfunctions::sqrt``
#. Don't include ``cmath``
Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines: Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
+3 -10
View File
@@ -16,22 +16,15 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>" "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
) )
# should we use our own math functions # configure a header file to pass the version number only
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags) target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
@@ -1,32 +1,51 @@
# first we add the executable that generates the table # add the library that runs
add_executable(MakeTable MakeTable.cxx) add_library(MathFunctions MathFunctions.cxx)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# add the main library
add_library(MathFunctions
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
# state that anybody linking to us needs to include the current source dir # state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't. # to find MathFunctions.h, while we don't.
# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR} )
)
# link our compiler flags interface library # should we use our own math functions
target_link_libraries(MathFunctions tutorial_compiler_flags) option(USE_MYMATH "Use tutorial provided math implementation" ON)
if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# library that just does sqrt
add_library(SqrtLibrary STATIC
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
# state that we depend on our binary dir to find Table.h
target_include_directories(SqrtLibrary PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
)
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs # install libs
set(installable_libs MathFunctions tutorial_compiler_flags) set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib) install(TARGETS ${installable_libs} DESTINATION lib)
# install include headers # install include headers
install(FILES MathFunctions.h DESTINATION include) install(FILES MathFunctions.h DESTINATION include)
@@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else
@@ -1 +1,3 @@
double mysqrt(double x); namespace mathfunctions {
double sqrt(double x);
}
@@ -5,6 +5,8 @@
// include the generated table // include the generated table
#include "Table.h" #include "Table.h"
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -31,3 +33,5 @@ double mysqrt(double x)
return result; return result;
} }
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+3 -12
View File
@@ -1,15 +1,11 @@
// A simple program that computes the square root of a number // A simple program that computes the square root of a number
#include <cmath>
#include <iostream> #include <iostream>
#include <sstream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;
@@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else
@@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else
-16
View File
@@ -7,36 +7,20 @@ project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
# TODO 7: Create a variable USE_MYMATH using option and set default to ON
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# TODO 8: Use list() and APPEND to create a list of optional libraries
# called EXTRA_LIBS and a list of optional include directories called
# EXTRA_INCLUDES. Add the MathFunctions library and source directory to
# the appropriate lists.
#
# Only call add_subdirectory and only add MathFunctions specific values
# to EXTRA_LIBS and EXTRA_INCLUDES if USE_MYMATH is true.
# TODO 2: Use add_subdirectory() to add MathFunctions to this project # TODO 2: Use add_subdirectory() to add MathFunctions to this project
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
# TODO 9: Use EXTRA_LIBS instead of the MathFunctions specific values
# in target_link_libraries.
# TODO 3: Use target_link_libraries to link the library to our executable # TODO 3: Use target_link_libraries to link the library to our executable
# TODO 4: Add MathFunctions to Tutorial's target_include_directories() # TODO 4: Add MathFunctions to Tutorial's target_include_directories()
# Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder! # Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!
# TODO 10: Use EXTRA_INCLUDES instead of the MathFunctions specific values
# in target_include_directories.
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC target_include_directories(Tutorial PUBLIC
@@ -1,2 +1,7 @@
# TODO 1: Add a library called MathFunctions # TODO 1: Add a library called MathFunctions
# Hint: You will need the add_library command # Hint: You will need the add_library command
# TODO 7: Create a variable USE_MYMATH using option and set default to ON
# TODO 8: If USE_MYMATH is ON, use target_compile_definitions to pass
# USE_MYMATH as a precompiled definition to our source files
@@ -0,0 +1,15 @@
#include "MathFunctions.h"
// TODO 11: include cmath
// TODO 10: Wrap the mysqrt include in a precompiled ifdef based on USE_MYMATH
#include "mysqrt.h"
namespace mathfunctions {
double sqrt(double x)
{
// TODO 9: If USE_MYMATH is defined, use detail::mysqrt.
// Otherwise, use std::sqrt.
return detail::mysqrt(x);
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,5 +1,9 @@
#include "mysqrt.h"
#include <iostream> #include <iostream>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -20,3 +24,5 @@ double mysqrt(double x)
} }
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,5 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
// TODO 13: use cmakedefine to define USE_MYMATH
+2 -7
View File
@@ -3,11 +3,8 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "TutorialConfig.h"
// TODO 11: Only include MathFunctions if USE_MYMATH is defined
// TODO 5: Include MathFunctions.h // TODO 5: Include MathFunctions.h
#include "TutorialConfig.h"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@@ -22,9 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// TODO 12: Use mysqrt if USE_MYMATH is defined and sqrt otherwise // TODO 6: Replace sqrt with mathfunctions::sqrt
// TODO 6: Replace sqrt with mysqrt
// calculate square root // calculate square root
const double outputValue = sqrt(inputValue); const double outputValue = sqrt(inputValue);
+3 -9
View File
@@ -7,9 +7,6 @@ project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
@@ -17,16 +14,13 @@ configure_file(TutorialConfig.h.in TutorialConfig.h)
# TODO 2: Remove EXTRA_INCLUDES list # TODO 2: Remove EXTRA_INCLUDES list
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions) list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
list(APPEND EXTRA_LIBS MathFunctions)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) target_link_libraries(Tutorial PUBLIC MathFunctions)
# TODO 3: Remove use of EXTRA_INCLUDES # TODO 3: Remove use of EXTRA_INCLUDES
@@ -1,5 +1,11 @@
add_library(MathFunctions mysqrt.cxx) add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# TODO 1: State that anybody linking to MathFunctions needs to include the # TODO 1: State that anybody linking to MathFunctions needs to include the
# current source directory, while MathFunctions itself doesn't. # current source directory, while MathFunctions itself doesn't.
# Hint: Use target_include_directories with the INTERFACE keyword # Hint: Use target_include_directories with the INTERFACE keyword
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
@@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,7 +1,9 @@
#include "mysqrt.h"
#include <iostream> #include <iostream>
#include "MathFunctions.h" namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -22,3 +24,5 @@ double mysqrt(double x)
} }
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+2 -11
View File
@@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;
+2 -8
View File
@@ -31,25 +31,19 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
# build-tree # build-tree
# Hint: Use BUILD_INTERFACE # Hint: Use BUILD_INTERFACE
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
# TODO 2: Link to tutorial_compiler_flags # TODO 2: Link to tutorial_compiler_flags
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) target_link_libraries(Tutorial PUBLIC MathFunctions)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
@@ -1,9 +1,15 @@
add_library(MathFunctions mysqrt.cxx) add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir # state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't. # to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
# TODO 3: Link to tutorial_compiler_flags # TODO 3: Link to tutorial_compiler_flags
@@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,7 +1,9 @@
#include "mysqrt.h"
#include <iostream> #include <iostream>
#include "MathFunctions.h" namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -22,3 +24,5 @@ double mysqrt(double x)
} }
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+2 -11
View File
@@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;
+3 -8
View File
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>" "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
@@ -1,13 +1,19 @@
add_library(MathFunctions mysqrt.cxx) add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir # state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't. # to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
# link our compiler flags interface library # link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags) target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# TODO 1: Create a variable called installable_libs that is a list of all # TODO 1: Create a variable called installable_libs that is a list of all
# libraries we want to install (e.g. MathFunctions and tutorial_compiler_flags) # libraries we want to install (e.g. MathFunctions and tutorial_compiler_flags)
@@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,7 +1,9 @@
#include "mysqrt.h"
#include <iostream> #include <iostream>
#include "MathFunctions.h" namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -22,3 +24,5 @@ double mysqrt(double x)
} }
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+2 -11
View File
@@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;
+3 -8
View File
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>" "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
@@ -1,13 +1,19 @@
add_library(MathFunctions mysqrt.cxx) add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir # state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't. # to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
# link our compiler flags interface library # link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags) target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs # install libs
set(installable_libs MathFunctions tutorial_compiler_flags) set(installable_libs MathFunctions tutorial_compiler_flags)
@@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,7 +1,9 @@
#include "mysqrt.h"
#include <iostream> #include <iostream>
#include "MathFunctions.h" namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -22,3 +24,5 @@ double mysqrt(double x)
} }
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+2 -11
View File
@@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;
+3 -8
View File
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>" "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
@@ -1,33 +1,39 @@
add_library(MathFunctions mysqrt.cxx) add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir # state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't. # to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# 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()
endif()
# link our compiler flags interface library # link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags) target_link_libraries(MathFunctions PUBLIC 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 # install libs
set(installable_libs MathFunctions tutorial_compiler_flags) set(installable_libs MathFunctions tutorial_compiler_flags)
@@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,8 +1,9 @@
#include "mysqrt.h"
#include <iostream> #include <iostream>
// TODO 4: include cmath namespace mathfunctions {
#include "MathFunctions.h" namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -32,3 +33,5 @@ double mysqrt(double x)
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+2 -11
View File
@@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;
+3 -9
View File
@@ -16,23 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>" "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
@@ -1,36 +1,43 @@
add_library(MathFunctions mysqrt.cxx) add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# does this system provide the log and exp functions?
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <cmath>
int main() {
std::log(1.0);
return 0;
}
" HAVE_LOG)
check_cxx_source_compiles("
#include <cmath>
int main() {
std::exp(1.0);
return 0;
}
" HAVE_EXP)
# add compile definitions
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP"
)
endif()
endif()
# state that anybody linking to us needs to include the current source dir # state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't. # to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
) )
# link our compiler flags interface library # link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags) target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# does this system provide the log and exp functions?
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <cmath>
int main() {
std::log(1.0);
return 0;
}
" HAVE_LOG)
check_cxx_source_compiles("
#include <cmath>
int main() {
std::exp(1.0);
return 0;
}
" HAVE_EXP)
# add compile definitions
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
# install libs # install libs
set(installable_libs MathFunctions tutorial_compiler_flags) set(installable_libs MathFunctions tutorial_compiler_flags)
@@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,8 +1,10 @@
#include "mysqrt.h"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include "MathFunctions.h" namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -30,3 +32,5 @@ double mysqrt(double x)
#endif #endif
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+2 -11
View File
@@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;
+3 -8
View File
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>" "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
) )
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
@@ -1,34 +1,49 @@
# first we add the executable that generates the table add_library(MathFunctions MathFunctions.cxx)
add_executable(MakeTable MakeTable.cxx)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# add the main library
add_library(MathFunctions
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
# state that anybody linking to us needs to include the current source dir # state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't. # to find MathFunctions.h, while we don't.
# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the
# TutorialConfig.h include is an implementation detail
# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR} )
)
# link our compiler flags interface library # should we use our own math functions
target_link_libraries(MathFunctions tutorial_compiler_flags) option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# library that just does sqrt
add_library(SqrtLibrary STATIC
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
# state that we depend on our binary dir to find Table.h
target_include_directories(SqrtLibrary PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
)
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs # install libs
set(installable_libs MathFunctions tutorial_compiler_flags) set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib) install(TARGETS ${installable_libs} DESTINATION lib)
# install include headers # install include headers
install(FILES MathFunctions.h DESTINATION include) install(FILES MathFunctions.h DESTINATION include)
@@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}
@@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}
@@ -1,10 +1,12 @@
#include <iostream> #include "mysqrt.h"
#include "MathFunctions.h" #include <iostream>
// include the generated table // include the generated table
#include "Table.h" #include "Table.h"
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@@ -31,3 +33,5 @@ double mysqrt(double x)
return result; return result;
} }
}
}
@@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
+2 -11
View File
@@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;