mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-22 06:59:01 -06:00
Help: Populate tutorial guide text
Migrate tutorial text from individual `directions.txt` files to the main tutorial document. Add some comments to source code to provide anchors for inclusion.
This commit is contained in:
@@ -3,7 +3,7 @@ project(Tutorial)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
# the version number.
|
||||
# set the version number
|
||||
set(Tutorial_VERSION_MAJOR 1)
|
||||
set(Tutorial_VERSION_MINOR 0)
|
||||
|
||||
|
||||
@@ -31,5 +31,6 @@ if(HAVE_LOG AND HAVE_EXP)
|
||||
PRIVATE "HAVE_LOG" "HAVE_EXP")
|
||||
endif()
|
||||
|
||||
# install rules
|
||||
install(TARGETS MathFunctions DESTINATION lib)
|
||||
install(FILES MathFunctions.h DESTINATION include)
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
# Mixing Static and Shared #
|
||||
|
||||
In this section we will show how by using the BUILD_SHARED_LIBS variable we can
|
||||
control the default behavior of add_library, and allow control over how
|
||||
libraries without an explicit type ( STATIC/SHARED/MODULE/OBJECT ) are built.
|
||||
|
||||
To accomplish this we need to add BUILD_SHARED_LIBS to the top level
|
||||
CMakeLists.txt. We use the option command as it allows 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
|
||||
MathFuctions, 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:
|
||||
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
project(Tutorial)
|
||||
|
||||
# control where the static and shared libraries are built so that on windows
|
||||
# we don't need to tinker with the path to run the executable
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
|
||||
|
||||
# the version number.
|
||||
set(Tutorial_VERSION_MAJOR 1)
|
||||
set(Tutorial_VERSION_MINOR 0)
|
||||
|
||||
# configure a header file to pass the version number only
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
|
||||
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
|
||||
)
|
||||
|
||||
# add the MathFunctions library
|
||||
add_subdirectory(MathFunctions)
|
||||
|
||||
# add the executable
|
||||
add_executable(Tutorial tutorial.cxx)
|
||||
target_link_libraries(Tutorial PUBLIC MathFunctions)
|
||||
|
||||
Now that we have made MathFunctions always be used, we will need to update
|
||||
the logic of that library. So, in MathFunctions/CMakeLists.txt we need to
|
||||
create a SqrtLibrary that will conditionally be built 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:
|
||||
|
||||
# add the library that runs
|
||||
add_library(MathFunctions MathFunctions.cxx)
|
||||
|
||||
# state that anybody linking to us needs to include the current source dir
|
||||
# to find MathFunctions.h, while we don't.
|
||||
target_include_directories(MathFunctions
|
||||
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# should we use our own math functions
|
||||
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)
|
||||
|
||||
# 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_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()
|
||||
|
||||
# define the symbol stating we are using the declspec(dllexport) when
|
||||
# building on windows
|
||||
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
|
||||
|
||||
install(TARGETS MathFunctions DESTINATION lib)
|
||||
install(FILES MathFunctions.h DESTINATION include)
|
||||
|
||||
Next, update MathFunctions/mysqrt.cxx to use the mathfunctions and detail namespaces:
|
||||
|
||||
#include <iostream>
|
||||
#include "MathFunctions.h"
|
||||
|
||||
// include the generated table
|
||||
#include "Table.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace mathfunctions {
|
||||
namespace detail {
|
||||
// a hack square root calculation using simple operations
|
||||
double mysqrt(double x)
|
||||
{
|
||||
...
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
We also need to make some changes in tutorial.cxx, so that it no longer uses USE_MYMATH:
|
||||
1. Always include MathFunctions.h
|
||||
2. Always use mathfunctions::sqrt
|
||||
|
||||
Finally, update MathFunctions/MathFunctions.h to use dll export defines:
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(EXPORTING_MYMATH)
|
||||
#define DECLSPEC __declspec(dllexport)
|
||||
#else
|
||||
#define DECLSPEC __declspec(dllimport)
|
||||
#endif
|
||||
#else //non windows
|
||||
#define DECLSPEC
|
||||
#endif
|
||||
|
||||
namespace mathfunctions
|
||||
{
|
||||
double DECLSPEC sqrt(double x);
|
||||
}
|
||||
|
||||
At this point, if you build everything, you will notice that linking fails
|
||||
as we are combining a static library without position enabled code with a
|
||||
library that has position enabled code. This solution to this is to explicitly
|
||||
set the POSITION_INDEPENDENT_CODE target property of SqrtLibrary to be True no
|
||||
matter the build type.
|
||||
|
||||
Exercise: We modified MathFunctions.h to use dll export defines. Using CMake
|
||||
documentation can you find a helper module to simplify this?
|
||||
|
||||
Exercise: Determine what command is enabling PIC for SqrtLibrary.
|
||||
What happens if we remove said command?
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "TutorialConfig.h"
|
||||
|
||||
// should we include the MathFunctions header?
|
||||
#ifdef USE_MYMATH
|
||||
# include "MathFunctions.h"
|
||||
#endif
|
||||
@@ -13,6 +14,7 @@
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
// report version
|
||||
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
|
||||
<< Tutorial_VERSION_MINOR << std::endl;
|
||||
std::cout << "Usage: " << argv[0] << " number" << std::endl;
|
||||
@@ -21,6 +23,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
double inputValue = std::stod(argv[1]);
|
||||
|
||||
// which square root function should we use?
|
||||
#ifdef USE_MYMATH
|
||||
double outputValue = mysqrt(inputValue);
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user