step 1
the minal project
cmake_minimum_required(VERSION 3.10)
project(Tutorial)
add_executable(Tutorial tutorial.cxx)
specifying c++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
project version
project(Tutorial VERSION 1.0)
# the config file
configure_file(TutorialConfig.h.in TutorialConfig.h)
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
the definiation
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
step 2 add library
different level of cmake
# MathFunctions/CMakeLists.txt
add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# main
add_subdirectory(MathFunctions)
target_link_libraries(Tutorial PUBLIC MathFunctions) # link
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/MathFunctions"
)
add option 通常和 宏定义一起使用
# MathFunctions/CMakeLists.txt
add_library(MathFunctions MathFunctions.cxx )
# define a cache variable and set it on
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# use if
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
add_library(SqrtLibrary STATIC
mysqrt.cxx
)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
我们将自己的 mysqrt.cxx 作为一个库, 如果 有 USE_MYMATH 我们会将其作为一个库添加到 MathFunctions, 在外部 Tutorial 中,只需要知道链接 MathFunctions 就可以了,不需要具体的实现细节。
the cxx file
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
step3 add usage required lib
任何想要使用 MathFunctions
的 都需要 inlucde 当前文件,但是 MathFunctions
不需要。因此我们使用 INTERFACE
Remember INTERFACE
means things that consumers require but the producer doesn't.
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
此时 main 中 我们就可以移除 add_include 文件。 main 中只需要使用 target_link_libraries()
链接目标哭的名字。
为库添加特性
创建一个 INTERFACE 的库 --- 一个虚拟库。然后给这个接口库设置了一个编译特性cxx_std_11。那么只要依赖找个虚拟库的对象,在编译时都会使用到cxx_std_11找个特征。
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
此时 在不同的库 就可以通过引入这个库来添加 c++ 11 的特性
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
当然也可以直接,设置,上面的好处是可以同时设置多个。
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
target_compile_features(Tutorial INTERFACE cxx_std_11)
step4 : add generator expression
# 当编译单元的语言与language匹配且CMake编译器id和compiler_ids中任意匹配则为1,否则为0
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
# 当使用c++和msvc编译器时mscv_cxx变量值为1
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
cmake构建分为config和build阶段,生成器表达式的值在build阶段才得到。生成器表达式可用于根据某些条件设置某些变量和编译选项。
$<condition:true_string>
$<IF:condition,true_string,false_string>
当condition为真则返回true_string字符串,否则返回空字符串
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>"
"$<${msvc_cxx}:-W3>"
)
可以嵌套
$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>
标签:set,CMake,target,cxx,MathFunctions,add,Tutorial
From: https://www.cnblogs.com/bigsharker/p/18198475