它是一个项目构建工具,开源,跨平台,并且简单易用。项目管理文件为CMakeLists.txt,生成时一般使用外部构建,在项目根目录下创建build目录,进入到build目录中执行cmake ..,然后make。入门篇不介绍脚本具体格式,只介绍最基础的使用。
1.最简单的可执行程序
项目包含:main.cpp。CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(hello) ADD_EXECUTABLE(hello main.cpp)
2.包含头文件和cpp的可执行程序
项目包含:include/hello.h src/hello.cpp src/main.cpp。CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(hello) SET(SOURCES src/hello.cpp src/main.cpp ) ADD_EXECUTABLE(hello ${SOURCES}) TARGET_INCLUDE_DIRECTORIES(hello PRIVATE ${PROJECT_SOURCE_DIR}/include)
3.构建静态库
项目文件结构同2。CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(hello)
# 静态库hello_static
ADD_LIBRARY(hello_static STATIC src/hello.cpp)
TARGET_INCLUDE_DIRECTORIES(hello_static PUBLIC ${PROJECT_SOURCE_DIR}/include)
# 可执行程序
ADD_EXECUTABLE(hello src/main.cpp)
TARGET_LINK_LIBRARIES(hello PRIVATE hello_static)
4.构建动态库
项目文件结构同2。CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(hello) # 动态库hello_shared ADD_LIBRARY(hello_shared SHARED src/hello.cpp)
SET_TARGET_PROPERTIES(hello_shared PROPERTIES VERSION 1.2 SOVERSION 1) #动态库版本号设置
TARGET_INCLUDE_DIRECTORIES(hello_shared PUBLIC ${PROJECT_SOURCE_DIR}/include)
# 可执行程序
ADD_EXECUTABLE(hello src/main.cpp)
TARGET_LINK_LIBRARIES(hello PRIVATE hello_shared)
5.安装
在2基础上增加配置文件test.conf。CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(hello) # library ADD_LIBRARY(hello_lib SHARED src/hello.cpp) TARGET_INCLUDE_DIRECTORIES(hello_lib PUBLIC ${PROJECT_SOURCE_DIR}/include) # exe ADD_EXECUTABLE(hello src/main.cpp) TARGET_LINK_LIBRARIES(hello PRIVATE hello_lib) # install INSTALL(TARGETS hello DESTINATION bin) INSTALL(TARGETS hello_lib LIBRARY DESTINATION lib) INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include) #注意三个目标目录的写法是不同的 INSTALL(FILES test.conf DESTINATION etc)
可以使用make install DESTDIR=/XXX或者cmake -DCMAKE_INSTALL_PREFIX=/XXX ..来改变安装目录
6.指定编译类型
项目文件只有main.cpp。CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) MESSAGE("set build type to 'RelWithDebInfo' as none was specified.") SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "choose the type of build" FORCE) SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") ENDIF() PROJECT(hello) ADD_EXECUTABLE(hello main.cpp)
使用时cmake .. -DCMAKE_BUILD_TYPE=Release
7.使用编译选项
项目文件只有main.cpp,但是它的内容使用了预处理标志。
1 #include <iostream> 2 3 int main(int argc, char *argv[]) 4 { 5 std::cout << "Hello Compile Flags!" << std::endl; 6 7 // only print if compile flag set 8 #ifdef EX2 9 std::cout << "Hello Compile Flag EX2!" << std::endl; 10 #endif 11 12 #ifdef EX3 13 std::cout << "Hello Compile Flag EX3!" << std::endl; 14 #endif 15 16 return 0; 17 }
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "set c++ compiler flags" FORCE) PROJECT(hello) ADD_EXECUTABLE(hello main.cpp) TARGET_COMPILE_DEFINITIONS(hello PRIVATE EX3)
构建时可以使用cmake .. -DCMAKE_CXX_FLAG="-DEX3"
8.使用第三方库
项目只有main.cpp。CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(hello) FIND_PACKAGE(Boost REQUIRED COMPONENTS filesystem system) SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) # if 标志 IF(Boost_FOUND) MESSAGE("boost found") ELSE() MESSAGE(FATAL_ERROR "cannot find boost") ENDIF() ADD_EXECUTABLE(hello main.cpp) TARGET_LINK_LIBRARIES(hello PRIVATE Boost::filesystem)
9.子项目管理
有三个子项目,每个子项目有各自目录和项目文件。总项目CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(hello) ADD_SUBDIRECTORY(A) ADD_SUBDIRECTORY(B) ADD_SUBDIRECTORY(C)