Tutorial: Improve Step 6

* Print message when using the table
* Remove duplicated comment
* Remove HAVE_LOG and HAVE_EXP checks, use generated table instead
This commit is contained in:
Betsy McPhail 2019-07-26 12:46:08 -04:00 committed by Brad King
parent df9cdf629c
commit a36731c634
15 changed files with 35 additions and 145 deletions

View File

@ -43,10 +43,6 @@ if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(SqrtLibrary
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

View File

@ -4,8 +4,6 @@
// include the generated table
#include "Table.h"
#include <cmath>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations
@ -15,20 +13,13 @@ double mysqrt(double x)
return 0;
}
// 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 and exp" << std::endl;
#else
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}
// if we have both log and exp then use them
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
@ -38,7 +29,7 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
#endif
return result;
}
}

View File

@ -13,12 +13,6 @@ target_include_directories(MathFunctions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if(USE_MYMATH)
# 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)
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
@ -44,10 +38,6 @@ if(USE_MYMATH)
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
target_compile_definitions(SqrtLibrary PRIVATE
"$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
"$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

View File

@ -4,8 +4,6 @@
// include the generated table
#include "Table.h"
#include <cmath>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations
@ -15,12 +13,6 @@ double mysqrt(double x)
return 0;
}
// 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 and exp" << std::endl;
#else
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
@ -38,7 +30,7 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
#endif
return result;
}
}

View File

@ -39,17 +39,6 @@ if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# 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)
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(SqrtLibrary
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

View File

@ -4,8 +4,6 @@
// include the generated table
#include "Table.h"
#include <cmath>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations
@ -15,20 +13,13 @@ double mysqrt(double x)
return 0;
}
// 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 and exp" << std::endl;
#else
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}
// if we have both log and exp then use them
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
@ -38,7 +29,7 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
#endif
return result;
}
}

View File

@ -40,10 +40,6 @@ if(USE_MYMATH)
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(SqrtLibrary
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

View File

@ -4,8 +4,6 @@
// include the generated table
#include "Table.h"
#include <cmath>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations
@ -15,20 +13,13 @@ double mysqrt(double x)
return 0;
}
// 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 and exp" << std::endl;
#else
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}
// if we have both log and exp then use them
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {

View File

@ -24,17 +24,6 @@ target_include_directories(MathFunctions
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
# 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)
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
# install rules
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)

View File

@ -4,8 +4,6 @@
// include the generated table
#include "Table.h"
#include <cmath>
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@ -16,6 +14,7 @@ double mysqrt(double x)
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}

View File

@ -24,17 +24,6 @@ target_include_directories(MathFunctions
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
# 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)
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
# install rules
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)

View File

@ -4,8 +4,6 @@
// include the generated table
#include "Table.h"
#include <cmath>
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@ -13,20 +11,13 @@ double mysqrt(double x)
return 0;
}
// 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 and exp" << std::endl;
#else
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}
// if we have both log and exp then use them
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
@ -36,6 +27,6 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
#endif
return result;
}

View File

@ -26,17 +26,6 @@ target_include_directories(MathFunctions
# and that anything that links to use will get this define
target_compile_definitions(MathFunctions INTERFACE "USE_MYMATH")
# 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)
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
# install rules
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)

View File

@ -4,8 +4,6 @@
// include the generated table
#include "Table.h"
#include <cmath>
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@ -13,20 +11,13 @@ double mysqrt(double x)
return 0;
}
// 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 and exp" << std::endl;
#else
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}
// if we have both log and exp then use them
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
@ -36,6 +27,6 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
#endif
return result;
}

View File

@ -450,27 +450,29 @@ this step.
Adding a Custom Command and Generated File (Step 6)
===================================================
In this section, we will add a generated source file into the build process
of an application. For this example, we will create a table of precomputed
square roots as part of the build process, and then compile that
table into our application.
Suppose, for the purpose of this tutorial, we decide that we never want to use
the platform ``log`` and ``exp`` functions and instead would like to
generate a table of precomputed values to use in the ``mysqrt`` function.
In this section, we will create the table as part of the build process,
and then compile that table into our application.
To accomplish this, we first need a program that will generate the table. In
the MathFunctions subdirectory a new source file named ``MakeTable.cxx`` will
do just that.
First, let's remove the check for the ``log`` and ``exp`` functions in
MathFunctions/CMakeLists. Then remove the check for ``HAVE_LOG`` and
``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove
:code:`#include <cmath>`.
.. literalinclude:: Step7/MathFunctions/MakeTable.cxx
:language: c++
In the MathFunctions subdirectory, a new source file named ``MakeTable.cxx``
has been provided to generate the table.
Note that the table is produced as valid C++ code and that the output filename
is passed in as an argument.
After reviewing the file, we can see that the table is produced as valid C++
code and that the output filename is passed in as an argument.
The next step is to add the appropriate commands to MathFunctions' CMakeLists
The next step is to add the appropriate commands to MathFunctions CMakeLists
file to build the MakeTable executable and then run it as part of the build
process. A few commands are needed to accomplish this.
First, the executable for ``MakeTable`` is added as any other executable would
be added.
First, at the top of MathFunctions/CMakeLists, the executable for ``MakeTable``
is added as any other executable would be added.
.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
:language: cmake
@ -509,10 +511,14 @@ Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
:start-after: // a hack square root calculation using simple operations
Run **cmake** or **cmake-gui** to configure the project and then build it
with your chosen build tool. When this project is built it will first build
the ``MakeTable`` executable. It will then run ``MakeTable`` to produce
``Table.h``. Finally, it will compile ``mysqrt.cxx`` which includes
``Table.h`` to produce the MathFunctions library.
with your chosen build tool.
When this project is built it will first build the ``MakeTable`` executable.
It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will
compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the MathFunctions
library.
Run the Tutorial executable and verify that it is using the table.
Building an Installer (Step 7)
==============================