cmake

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.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值