add_library(calclib STATIC src/calclib.cpp include/calc/lib.hpp) target_include_directories(calclib PUBLIC include) target_compile_features(calclib PUBLIC cxx_std_11)
add_executable(calc apps/calc.cpp) target_link_libraries(calc PUBLIC calclib)
OPTION(ENABLE_ASAN "Enable build with address sanitizer"ON) OPTION(WITH_UNIT_TESTS "Compile miniob with unit tests"ON) OPTION(CONCURRENCY "Support concurrency operations"OFF) OPTION(STATIC_STDLIB "Link std library static or dynamic, such as libgcc, libstdc++, libasan"OFF)
函数名不区分大小写;函数内部提倡关键字用大写,变量用小写。
set(CMAKE_CXX_STANDARD 20)
相当于赋值语句。CMAKE_CXX_STANDARD = 20
如果一个变量在先前没有出现,那么它应该是内建关键字,具体RTFM
MESSAGE(STATUS "This is Project source dir " ${PROJECT_SOURCE_DIR})
打印指令
${foobar} 表示解引用。 >
[cmake] -- This is Project source dir /home/junyu33/Desktop/github/miniob
OPTION(foobar "comment" ON/OFF)
可以理解为对bool类型的set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
MESSAGE(STATUS "HOME dir: $ENV{HOME}") #SET(ENV{变量名} 值) IF(WIN32) MESSAGE(STATUS "This is windows.") ADD_DEFINITIONS(-DWIN32) ELSEIF(WIN64) MESSAGE(STATUS "This is windows.") ADD_DEFINITIONS(-DWIN64) ELSEIF(APPLE) MESSAGE(STATUS "This is apple") # normally __MACH__ has already been defined ADD_DEFINITIONS(-D__MACH__ ) ELSEIF(UNIX) MESSAGE(STATUS "This is UNIX") ADD_DEFINITIONS(-DUNIX -DLINUX) ELSE() MESSAGE(STATUS "This is UNKNOW OS") ENDIF(WIN32)
注意${foobar}在引号里也可以解引用
这里WIN32 WIN64 APPLE等都是内建关键字
IF ELSEIF中条件为真的有以下类型:
ON, YES, TRUE,
Y, or non zero number
为假的有以下类型:
0, OFF, NO,
FALSE, N, IGNORE,
NOTFOUND, "", or ends in
-NOTFOUND
ADD_DEFINITIONS:跟编译选项添加-D的语法一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# This is for clangd plugin for vscode SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wall -Werror") IF(DEBUG) MESSAGE(STATUS "DEBUG has been set as TRUE ${DEBUG}") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -O0 -g -DDEBUG ") ADD_DEFINITIONS(-DENABLE_DEBUG) ELSEIF(NOTDEFINED ENV{DEBUG}) MESSAGE(STATUS "Disable debug") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -O2 -g ") ELSE() MESSAGE(STATUS "Enable debug") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -O0 -g -DDEBUG") ADD_DEFINITIONS(-DENABLE_DEBUG) ENDIF(DEBUG)
注意CMAKE_COMMON_FLAGS是一个用户定义的变量,你可以发现这里的添加都是增量添加
ENV,取系统环境变量,ENV{foo}取环境变量foo
1 2 3 4 5 6 7 8 9 10
IF (CONCURRENCY) MESSAGE(STATUS "CONCURRENCY is ON") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -DCONCURRENCY") ADD_DEFINITIONS(-DCONCURRENCY) ENDIF (CONCURRENCY)
MESSAGE(STATUS "CMAKE_CXX_COMPILER_ID is "${CMAKE_CXX_COMPILER_ID}) IF ("${CMAKE_CXX_COMPILER_ID}"STREQUAL"GNU"AND${STATIC_STDLIB}) ADD_LINK_OPTIONS(-static-libgcc -static-libstdc++) ENDIF()
IF (ENABLE_ASAN) SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -fno-omit-frame-pointer -fsanitize=address") IF ("${CMAKE_CXX_COMPILER_ID}"STREQUAL"GNU"AND${STATIC_STDLIB}) ADD_LINK_OPTIONS(-static-libasan) ENDIF() ENDIF()
IF (CMAKE_INSTALL_PREFIX) MESSAGE(STATUS "CMAKE_INSTALL_PREFIX has been set as "${CMAKE_INSTALL_PREFIX} ) ELSEIF(DEFINED ENV{CMAKE_INSTALL_PREFIX}) SET(CMAKE_INSTALL_PREFIX $ENV{CMAKE_INSTALL_PREFIX}) ELSE() SET(CMAKE_INSTALL_PREFIX /tmp/${PROJECT_NAME}) ENDIF() MESSAGE(STATUS "Install target dir is "${CMAKE_INSTALL_PREFIX})
IF (DEFINED ENV{LD_LIBRARY_PATH}) SET(LD_LIBRARY_PATH_STR $ENV{LD_LIBRARY_PATH}) string(REPLACE ":"";" LD_LIBRARY_PATH_LIST ${LD_LIBRARY_PATH_STR}) MESSAGE(" Add LD_LIBRARY_PATH to -L flags "${LD_LIBRARY_PATH_LIST}) LINK_DIRECTORIES(${LD_LIBRARY_PATH_LIST}) ENDIF ()
This command should be in the source directory root because ctest
expects to find a test file in the build directory root. This command is
automatically invoked when the CTest module is included, except if the
BUILD_TESTING option is turned off.
find_library (<VAR> name1 [path1 path2 ...]):查找名字为readline的库文件。
> Each library name given to the NAMES option is first considered as
a library file name and then considered with platform-specific prefixes
(e.g. lib) and suffixes (e.g. .so). Therefore one may specify library
file names such as libfoo.a directly. This can be used to locate static
libraries on UNIX-like systems.
[cmake] readline include dir: /usr/include/readline[cmake] readline library: /usr/lib/libreadline.so
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
IF (HAVE_READLINE) TARGET_LINK_LIBRARIES(observer_static ${READLINE_LIBRARY}) TARGET_INCLUDE_DIRECTORIES(observer_static PRIVATE ${READLINE_INCLUDE_DIR}) ADD_DEFINITIONS(-DUSE_READLINE) MESSAGE ("observer_static use readline") ELSE () MESSAGE ("readline is not found") ENDIF()