cmake_minimum_required(VERSION 3.15)#setthe project name and versionproject(Tutorial VERSION 1.0)#specifythe C++ standardadd_library(tutorial_compiler_flags INTERFACE)target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)#addcompiler warning flags just when building this project via#theBUILD_INTERFACE genexset(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>""$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>")#controlwhere the static and shared libraries are built so that on windows#wedon't need to tinker with the path to run the executableset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")option(BUILD_SHARED_LIBS "Build using shared libraries" ON)#configurea header file to pass the version number onlyconfigure_file(TutorialConfig.h.in TutorialConfig.h)#addthe MathFunctions libraryadd_subdirectory(MathFunctions)#addthe executableadd_executable(Tutorial tutorial.cxx)target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)#addthe binary tree to the search path for include files#sothat we will find TutorialConfig.htarget_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}")#addthe install targetsinstall(TARGETS Tutorial DESTINATION bin)install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
DESTINATION include
)#enabletestinginclude(CTest)#doesthe application runadd_test(NAME Runs COMMAND Tutorial 25)#doesthe usage message work?add_test(NAME Usage COMMAND Tutorial)set_tests_properties(Usage
PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")#defineafunction to simplify adding testsfunction(do_test target arg result)add_test(NAME Comp${arg} COMMAND ${target} ${arg})set_tests_properties(Comp${arg}
PROPERTIES PASS_REGULAR_EXPRESSION ${result})endfunction()#doa bunch of result based testsdo_test(Tutorial 4"4 is 2")do_test(Tutorial 9"9 is 3")do_test(Tutorial 5"5 is 2.236")do_test(Tutorial 7"7 is 2.645")do_test(Tutorial 25"25 is 5")do_test(Tutorial -25"-25 is (-nan|nan|0)")do_test(Tutorial 0.0001"0.0001 is 0.01")#setupinstallerinclude(InstallRequiredSystemLibraries)set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")set(CPACK_SOURCE_GENERATOR "TGZ")include(CPack)install(EXPORT MathFunctionsTargets
FILE MathFunctionsTargets.cmake
DESTINATION lib/cmake/MathFunctions)include(CMakePackageConfigHelpers)#generatethe config file that includes the exportsconfigure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
INSTALL_DESTINATION "lib/cmake/MathFunctions"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO)write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
COMPATIBILITY AnyNewerVersion
)install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake
DESTINATION lib/cmake/MathFunctions
)export(
EXPORT MathFunctionsTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTagets.cmake")
MathFunctions/CMakeLists.txt
add the library that runs
add_library(MathFunctions MathFunctions.cxx)#statethat anybody linking to us needs to include the current source dir#tofind MathFunctions.h,while we don't.target_include_directories(MathFunctions
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)#shouldwe use our own math functionsoption(USE_MYMATH "Use tutorial provided math implementation" ON)if(USE_MYMATH)target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")include(MakeTable.cmake) # generates Table.h
#librarythat just does sqrtadd_library(SqrtLibrary STATIC
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)#statethat we depend on our binary dir to find Table.htarget_include_directories(SqrtLibrary PRIVATE
${CMAKE_CURRENT_BINARY_DIR})#statethat SqrtLibrary need PIC when the default is shared librariesset_target_properties(SqrtLibrary PROPERTIES
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})#linkSqrtLibrary to tutorial_compiler_flagstarget_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)target_link_libraries(MathFunctions PRIVATE SqrtLibrary)endif()#linkMathFunctions to tutorial_compiler_flagstarget_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)#definethesymbol stating we are using the declspec(dllexport) when#buildingon windowstarget_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")#installlibsset(installable_libs MathFunctions tutorial_compiler_flags)if(TARGET SqrtLibrary)list(APPEND installable_libs SqrtLibrary)endif()install(TARGETS ${installable_libs}
EXPORT MathFunctionsTargets
DESTINATION lib)#installinclude headersinstall(FILES MathFunctions.h DESTINATION include)