https://cmake.org/cmake/help/latest/guide/tutorial/index.html
############################################################################################################
# MathFunctions/CMakeLists.txt
add_library(MathFunctions mysqrt.cxx)#生成链接库,(链接库名称, 链接库函数)
target_include_directories(MathFunctions
# INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}#INTERFACE意味着只有使用链接库头文件的才需要,链接库本身不需要
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}#在使用Table.h被包含进来。
)
option(USE_MYMATH "Use tutorial provided math implementation" ON)#为项目添加可选字段USE_MYMATH,并默认为ON
if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
add_executable(MakeTable MakeTable.cxx)#生成一个MakeTable可执行文件
add_custom_command(#添加自定义命令;即如何通过MakeTable可执行文件,生成Table.h文件
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
add_library(SqrtLibrary STATIC#生成链接库,(链接库名称, 链接库函数)
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h# 让cmake知道mysqrt.cxx要依赖Table.h文件;直接将Table.h添加到MathFunctions的链接库源文件里面
)
set_target_properties(SqrtLibrary PROPERTIES# 显示的指定位置无关代码来连接静态库
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
target_include_directories(SqrtLibrary
#INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}# INTERFACE意味着只有使用链接库头文件的才需要,链接库本身不需要
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}#在使用Table.h被包含进来。
)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")# 在windows上构建时使用declspec(dllexport)的符号说明
set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0")# 设置MathFunctions链接库版本号
set_property(TARGET MathFunctions PROPERTY SOVERSION "1")# 设置MathFunctions链接库版本号
######################################################
set(installable_libs MathFunctions tutorial_compiler_flags)# install rules
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib EXPORT MathFunctionsTargets)#将链接库放入对应的lib文件夹
install(FILES MathFunctions.h DESTINATION include)#将链接库头文件放入对应的include文件夹
######################################################
# include(CheckSymbolExists)# 包含CheckSymbolExists模块;使用MakeTabel.cxx代替
# check_symbol_exists(log "math.h" HAVE_LOG)# 测试当前平台存在log函数
# check_symbol_exists(exp "math.h" HAVE_EXP)# 测试当前平台存在exp函数
# if(NOT (HAVE_LOG AND HAVE_EXP))
# unset(HAVE_LOG CACHE)
# unset(HAVE_EXP CACHE)
# set(CMAKE_REQUIRED_LIBRARIES "m")# 某些平台需要链接m库
# check_symbol_exists(log "math.h" HAVE_LOG)# 测试当前平台存在log函数
# check_symbol_exists(exp "math.h" HAVE_EXP)# 测试当前平台存在exp函数
# if(HAVE_LOG AND HAVE_EXP)
# target_link_libraries(MathFunctions PRIVATE m)# 如果确实仅包含在m库里面,则将m库链接进来。
# endif()
# endif()
# if(HAVE_LOG AND HAVE_EXP)
# target_compile_definitions(MathFunctions PRIVATE "HAVE_LOG" "HAVE_EXP")#指定HAVE_LOG和HAVE_EXP为PRIVATE编译定义
# endif()
######################################################
# MathFunctions/mysqrt.cxx
# #include<cmath># 使用MakeTabel.cxx代替
# #if defined(HAVE_LOG) && defined(HAVE_EXP)#如果log和exp函数在系统中可用
# double result = exp(log(x) * 0.5);
# std::cout << "Computing sqrt of " << x << " to be " << result
# << " using log and exp" << std::endl;
# #else
# double result = x;
# ...
# #endif
#include <iostream>
#include "MathFunctions.h"
// include the generated table
#include "Table.h"
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
if (x <= 0) {
return 0;
}
// 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)];
}
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
result = 0.1;
}
double delta = x - (result * result);
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
return result;
}
}
}
######################################################
# MathFunctions/MathFunctions.h
#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);#使用dll导出定义
}
############################################################################################################
# Tutorial/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)#cmake 最低版本
project(Tutorial VERSION 1.0)#工程名,这里面也可以追加版本号project(Tutorial)
#set(CMAKE_CXX_STANDARD 11)#指定c++ 11标准,并且CMAKE_CXX_STANDARD要在add_executable之前定义才行。
#set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_DEBUG_POSTFIX d)#添加debug后缀d
add_library(tutorial_compiler_flags INTERFACE)# 构造一个接口目标,
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)#指定所需的c++标准级别11;不使用CMAKE_CXX_STANDARD
######################################################
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")# 警告标志
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>>"
)
######################################################
set(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)#是否构建动态库
add_subdirectory(MathFunctions)#在主cmake文件中追加MathFunctions文件夹,该文件夹应当包含相应的子项目相关的cmake可读文件。
add_executable(Tutorial tutorial.cxx)#编译可执行文件 add_executable(exe文件名 cxx文件)
set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
######################################################
configure_file(TutorialConfig.h.in TutorialConfig.h)# 配置一个头文件.h.in将版本号传递给源文件.h
######################################################
# 在源文件目录中追加 TutorialConfig.h.in文件,并在该文件中定义以下内容
# // the configured options and settings for Tutorial
# #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
# #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
# @Tutorial_VERSION_MAJOR@ 和 @Tutorial_VERSION_MINOR@的值将被替换掉。
# 在对应的tutorial.cxx中添加头文件TutorialConfig.h
######################################################
# c++ 11中使用std::stod来替换atof,并且需要包含头文件#include<cstdlib>。
######################################################
# 在TutorialConfig.h.in文件中追加USE_MYMATH定义
# #cmakedefine USE_MYMATH
######################################################
# 在源代码tutorial.cxx中确定是否需要使用MathFunctions.h头文件
# #ifdef USE_MYMATH
# # include "MathFunctions.h"
# #endif
# 确定使用哪种函数
# #ifdef USE_MYMATH
# const double outputValue = mysqrt(inputValue);
# #else
# const double outputValue = sqrt(inputValue);
# #endif
# 1、包含MathFunctions.h头文件
# 2、使用mathfunctions::sqrt
# 3、不包含cmath
######################################################
if(USE_MYMATH)
list(APPEND EXTRA_LIBS MathFunctions)#获取MathFunctions文件夹中链接库
#list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")#获取MathFunctions文件夹中头文件;如果MathFunctions中target_include_directories使用了INTERFACE,则该行可注释。
endif()
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})#添加链接库,(当前项目,,链接库)
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
#${EXTRA_INCLUDES}如果MathFunctions中target_include_directories使用了INTERFACE,则该行可注释
)#包含链接库头文件
######################################################
install(TARGETS Tutorial DESTINATION bin)#将exe可执行放入对应的bin文件
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"#将头文件放入include文件
DESTINATION include
)
@PACKAGE_INIT@
include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" )
install(EXPORT MathFunctionsTargets
FILE MathFunctionsTargets.cmake
DESTINATION lib/cmake/MathFunctions
)
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in#生成包含导出的配置文件
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
INSTALL_DESTINATION "lib/cmake/example"
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
DESTINATION lib/cmake/MathFunctions
)
######################################################
include(CTest)#使用Dashboard;会自动的调用enable_testing
# enable_testing()# 允许测试;使用Dashboard
add_test(NAME Runs COMMAND Tutorial 25)# 直接测试运行,正常运行返回值为0;否则为segfault或者crash
add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(Usage
PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"# 关于Usage属性的正则项表达式,如果验证不正确,则输出特定的字符串
)
function(do_test target arg result)#定一个测试函数;包含待测试程序名、输入和预期的结果
add_test(NAME Comp${arg} COMMAND ${target} ${arg})#运行一个程序
set_tests_properties(Comp${arg}
PROPERTIES PASS_REGULAR_EXPRESSION ${result}#验证输入变量
)
endfunction(do_test)
do_test(Tutorial 4 "4 is 2")# do a bunch of result based tests
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")
######################################################
# Tutorial/CTestConfig.cmake
set(CTEST_PROJECT_NAME "CMakeTutorial")# 指定项目名称
set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial")# 提交仪表板的位置
set(CTEST_DROP_SITE_CDASH TRUE)
######################################################
include(InstallRequiredSystemLibraries)# 该模块将包括当前平台项目所需的任何运行时库。;cpace就是将源代码或者二进制文件做成一个压缩包;右击PACKAGE,然后生成就好了
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")#将CPack变量设置为存储这个项目的许可证和版本信息的位置。
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include(CPack)
############################################################################################################
export(EXPORT MathFunctionsTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
)
############################################################################################################
MultiCPackConfig.cmake.