1 概述
cmake 是kitware 公司以及一些开源开发者在开发几个工具套件(VTK)的过程中衍生品,最终形成体系,成为一个独立的开放源代码项目。
CMake 可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档。CMake 支持 in-place 建构(二进档和源代码在同一个目录树中)和 out-of-place 建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake 也支持静态与动态程式库的建构。
“CMake”这个名字是“cross platform make”的缩写。虽然名字中含有“make”,但是CMake和Unix上常见的“make”系统是分开的,而且更为高阶。
cmake的主要特点:
(1)开放源代码,使用类BSD 许可发布。http://cmake.org/HTML/Copyright.html
(2)跨平台,并可生成native 编译配置文件,在Linux/Unix 平台,生成 makefile,在苹果平台,可以生成xcode,在 Windows 平台,可以生成 MSVC 的工程文件。
(3)能够管理大型项目,KDE4 就是最好的证明。
(4)简化编译构建过程和编译过程。Cmake 的工具链非常简单:cmake+make。
(5)高效虑,按照KDE 官方说法,CMake 构建KDE4 的 kdelibs 要比使用autotools 来构建KDE3.5.6 的 kdelibs 快40%,主要是因为 Cmake 在工具链中没有libtool。
(6)可扩展,可以为cmake 编写特定功能的模块,扩充cmake 功能。
2 安装cmake
2.1 卸载已经安装的旧版的CMake[非必需]
apt-get autoremove cmake
2.2 下载并解压cmake
wget https://cmake.org/files/v3.21/cmake-3.21.3-linux-x86_64.tar.gz tar -xvf cmake-3.21.3-linux-x86_64.tar.gz
2.3 安装cmake
先将解压后的cmake放到/opt目录下
mv cmake-3.21.3-Linux-x86_64 /opt/cmake-3.21.3
2.4 创建软链接
sudo ln -sf /opt/cmake-3.21.3/bin/* /usr/bin/
3 CMake语法分析
CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
CMake指定工程名
PROJECT(0VOICE)
手动加入文件 KaTeX parse error: Expected 'EOF', got '}' at position 6: {变量名}}̲ ,比如{SRC_LIST}
SET(SRC_LIST main.c)
生产执行文件名0voice 0voice2
ADD_EXECUTABLE(0voice ${SRC_LIST})
引用动态库
ADD_EXECUTABLE(darren ${SRC_LIST})
添加链接库。强制找静态库,完整的库文件名libDir1.a
#TARGET_LINK_LIBRARIES(darren libDir1.a) #TARGET_LINK_LIBRARIES(darren lDir1) target_link_libraries(multi-dir Dir1 Dir2)
添加子目录
ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/dir1")
设置子目录
set(SUB_DIR_LIST "${CMAKE_CURRENT_SOURCE_DIR}/dir1" "${CMAKE_CURRENT_SOURCE_DIR}/dir2")
安装doc到 share/doc/cmake/0voice目录,默认/usr/local/。指定自定义目录,比如 cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr
# 将doc文件夹安装到/usr/local/share/doc/cmake/0voice INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/0voice) # 将执行文件安装到bin目录 INSTALL(TARGETS darren RUNTIME DESTINATION bin)
编译过程中打印输出:
MESSAGE(STATUS "THIS IS BINARY DIR " ${PROJECT_BINARY_DIR})
添加头文件路径
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/dir1")
查找当前目录下的所有源文件,并将名称保存到 DIR_LIB_SRCS 变量
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
添加库, 默认是静态库
#ADD_LIBRARY (dir1 SHARED ${DIR_SRCS}) ADD_LIBRARY (dir1 ${DIR_SRCS})
设置lib库目录
SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
遍历源文件
foreach(SUB_DIR ${SUB_DIR_LIST}) #遍历源文件 aux_source_directory(${SUB_DIR} SRC_LIST) MESSAGE(STATUS "SUB_DIR-> " ${SUB_DIR}) MESSAGE(STATUS "SRC_LIST-> " ${SRC_LIST}) endforeach()
设置Release版本还是Debug版本
# 设置release版本还是debug版本 if(${CMAKE_BUILD_TYPE} MATCHES "Release") MESSAGE(STATUS "Release版本") SET(BuildType "Release") else() SET(BuildType "Debug") MESSAGE(STATUS "Debug版本") endif()
debug和release版本目录不一样,设置生成的so动态库最后输出的路径
#SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/${BuildType})
增加编译选项
ADD_COMPILE_OPTIONS(-fPIC)
默认生成静态库链接库Dir1
ADD_LIBRARY (Dir1 ${DIR_LIB_SRCS})
SHARED生成动态库
ADD_LIBRARY (Dir1 SHARED ${DIR_LIB_SRCS})
设置lib库目录
SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
将库文件安装到lib目录
INSTALL(TARGETS Dir1 ARCHIVE DESTINATION lib)
将头文件include
INSTALL(FILES dir1.h DESTINATION include) #INSTALL(FILES *.h DESTINATION include)
设置生成的so动态库最后输出的路径
SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
设置bin和lib库目录, debug和release版本目录不一样
SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType})
找在某个路径下的所有源文件
aux_source_directory(<dir> <variable>)
install: 配置程序打包过程中的目标(TARGETS)、文件(FILES)、路径(DIRECTORY)、代码
(CODE)和输出配置(EXPORT)
install(TARGETS <target>... [...]) install({FILES | PROGRAMS} <file>... [...]) install(DIRECTORY <dir>... [...]) install(SCRIPT <file> [...]) install(CODE <code> [...]) install(EXPORT <export-name> [...])
4 cmake使用举例
cmake执行方法:
1、在当前目录下执行 cmake .
2、创建build目录,进入build目录后再cmake ..
4.1 单个文件目录实现
main.c
#include <stdio.h> int main(int argc, char *argv[]) { printf("0voice CMake!!!\n"); return 0; }
外层CMakeLists.txt
# CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) PROJECT(0VOICE) # 添加子目录 ADD_SUBDIRECTORY(src) #INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/0voice) # 安装doc到 share/doc/cmake/0voice目录 # 默认/usr/local/ #指定自定义目录,比如 cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr .. INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/0voice)
src目录下CMakeLists.txt
# 单个目录实现 # CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 工程 # PROJECT(0VOICE) # 手动加入文件 SET(SRC_LIST main.c) MESSAGE(STATUS "THIS IS BINARY DIR " ${PROJECT_BINARY_DIR}) MESSAGE(STATUS "THIS IS SOURCE DIR " ${PROJECT_SOURCE_DIR}) ADD_EXECUTABLE(youzi ${SRC_LIST}) # 演示 ADD_EXECUTABLE(youzi2 ${SRC_LIST}) # 将执行文件安装到bin目录 # 默认/usr/local/ #指定自定义目录,比如 cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr .. INSTALL(TARGETS youzi RUNTIME DESTINATION bin) INSTALL(TARGETS youzi2 RUNTIME DESTINATION bin)
执行cmake
执行make
生成文件如下
4.2 多个目录实现-子目录编译成库文件
外层CMAkeLists.txt
# CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) PROJECT(0VOICE) ADD_SUBDIRECTORY(src bin) #INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/0voice) INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/0voice)
src目录下CMakeLists.txt
# 单个目录实现 # CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 工程 PROJECT(0VOICE) # 手动加入文件 SET(SRC_LIST main.c) MESSAGE(STATUS "THIS IS BINARY DIR " ${PROJECT_BINARY_DIR}) MESSAGE(STATUS "THIS IS SOURCE DIR " ${PROJECT_SOURCE_DIR}) # 添加头文件路径 INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/dir1") INCLUDE_DIRECTORIES(dir1) MESSAGE(STATUS "CMAKE_CURRENT_SOURCE_DIR -> " ${CMAKE_CURRENT_SOURCE_DIR}) # 添加 dir1 子目录 ADD_SUBDIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/dir1") # 添加头文件路径 INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/dir2") # 添加 dir2 子目录 ADD_SUBDIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/dir2") ADD_EXECUTABLE(darren ${SRC_LIST} ) TARGET_LINK_LIBRARIES(darren dir1 dir2) # 将执行文件安装到bin目录 INSTALL(TARGETS darren RUNTIME DESTINATION bin)
src/dir1目录下CMakeLists.txt
# 加载所有的源码,和makefile wildcard类似 AUX_SOURCE_DIRECTORY(. DIR_SRCS) # SET(DIR_SRCS dir1.c dir12.c) # 默认是静态库 #ADD_LIBRARY (dir1 SHARED ${DIR_SRCS}) ADD_LIBRARY (dir1 ${DIR_SRCS})
src/dir2目录下CMakeLists.txt
AUX_SOURCE_DIRECTORY(. DIR_SRCS) ADD_LIBRARY(dir2 ${DIR_SRCS})
执行顺序解析:当在最外层执行cmake .(或者build目录下执行cmake …)时,会先执行最外层的CMakeLists.txt文件的命令。遇到ADD_SUBDIRECTORY,会进入到src目录下继续执行子CMakeLists.txt。当执行到src目录下的MESSAGE指令时,会向控制台打印Binary和Source目录,然后接着在src目录下的CMakeLists.txt文件中往下执行。碰到INCLUDE_DIRECTORIES时将“目录加到头文件环境变量中,然后碰到,添加子目录。同理。再执行,表示依赖于CMAKECURRENTSOURCEDIR/dir1”目录加到头文件环境变量中,然后碰到ADDSUBDIRECTORY,添加dir1子目录。dir2同理。再执行ADDEXECUTABLE,表示依赖于{CMAKE_CURRENT_SOURCE_DIR}/dir1”目录加到头文件环境变量中,然后碰到ADD_SUBDIRECTORY,添加 dir1 子目录。dir2同理。再执行ADD_EXECUTABLE,表示依赖于 {SRC_LIST}生成执行文件名darren。TARGET_LINK_LIBRARIES表示链接dir1动态库和dir2动态库。最后之星INSTALL将执行文件安装到bin目录。执行完后切换到最外层的CMakeLists.txt,执行INSTALL完成doc目录拷贝到share/doc/cmake/0voice的操作。
4.3 多个目录实现-子目录使用源码编译
最外层CMakeLists.txt
# CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) PROJECT(0VOICE) ADD_SUBDIRECTORY(src bin) MESSAGE(STATUS "TOP CMAKE_CURRENT_SOURCE_DIR -> " ${CMAKE_CURRENT_SOURCE_DIR}) #INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/0voice) INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/0voice)
src目录下CMakeLists.txt
# 单个目录实现 # CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 工程 # PROJECT(0VOICE) # 手动加入文件 SET(SRC_LIST main.c) MESSAGE(STATUS "THIS IS BINARY DIR " ${PROJECT_BINARY_DIR}) MESSAGE(STATUS "THIS IS SOURCE DIR " ${PROJECT_SOURCE_DIR}) #设置子目录 set(SUB_DIR_LIST "${CMAKE_CURRENT_SOURCE_DIR}/dir1" "${CMAKE_CURRENT_SOURCE_DIR}/dir2") foreach(SUB_DIR ${SUB_DIR_LIST}) #遍历源文件 aux_source_directory(${SUB_DIR} SRC_LIST) MESSAGE(STATUS "SUB_DIR-> " ${SUB_DIR}) MESSAGE(STATUS "SRC_LIST-> " ${SRC_LIST}) endforeach() # 添加头文件路径 INCLUDE_DIRECTORIES("dir1") INCLUDE_DIRECTORIES("dir2") ADD_EXECUTABLE(darren ${SRC_LIST} ) # 将执行文件安装到bin目录 INSTALL(TARGETS darren RUNTIME DESTINATION bin)
通过set(SUB_DIR_LIST "${CMAKE_CURRENT_SOURCE_DIR}/dir1" "${CMAKE_CURRENT_SOURCE_DIR}/dir2")
将子目录dir1、dir2下的源文件添加到集合变量$SUB_DIR_LIST
中,然后使用foreach遍历$SUB_DIR_LIST
,通过aux_source_directory
4.4 生成库-生成动态库
命令行生成Debug版本:cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr …
命令行生成Release版本:cmake -DCMAKE_BUILD_TYPE=Release …
cmake_minimum_required(VERSION 2.8s) # 设置release版本还是debug版本 if(${CMAKE_BUILD_TYPE} MATCHES "Release") MESSAGE(STATUS "Release版本") SET(BuildType "Release") else() SET(BuildType "Debug") MESSAGE(STATUS "Debug版本") endif() #设置lib库目录 SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release) # debug和release版本目录不一样 #设置生成的so动态库最后输出的路径 #SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/${BuildType}) ADD_COMPILE_OPTIONS(-fPIC) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_LIB_SRCS 变量 AUX_SOURCE_DIRECTORY(. DIR_LIB_SRCS) # 默认生成静态库链接库Dir1 #ADD_LIBRARY (Dir1 ${DIR_LIB_SRCS}) # SHARED生成动态库 ADD_LIBRARY (Dir1 SHARED ${DIR_LIB_SRCS})
4.5 生成库-生成静态库+安装到指定目录
cmake_minimum_required(VERSION 2.8s) # 设置release版本还是debug版本 if(${CMAKE_BUILD_TYPE} MATCHES "Release") MESSAGE(STATUS "Release版本") SET(BuildType "Release") else() SET(BuildType "Debug") MESSAGE(STATUS "Debug版本") endif() #设置lib库目录 SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release) # debug和release版本目录不一样 #设置生成的so动态库最后输出的路径 #SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/${BuildType}) ADD_COMPILE_OPTIONS(-fPIC) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_LIB_SRCS 变量 AUX_SOURCE_DIRECTORY(. DIR_LIB_SRCS) # 默认生成静态库链接库Dir1 #ADD_LIBRARY (Dir1 ${DIR_LIB_SRCS}) # SHARED生成动态库 ADD_LIBRARY (Dir1 SHARED ${DIR_LIB_SRCS})
4.6 编译选项
# CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 设置release版本还是debug版本 if(${CMAKE_BUILD_TYPE} MATCHES "Release") message(STATUS "Release版本") set(BuildType "Release") SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -DNODEBUG -O3 -Wall") SET(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -DNODEBUG -O3 -Wall") MESSAGE(STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS}) MESSAGE(STATUS "CFLAGS: " ${CMAKE_C_FLAGS}) else() # CMAKE_BUILD_TYPE 不带参数就是debug版本 set(BuildType "Debug") message(STATUS "Debug版本") SET(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall -O0 -gdwarf-3 -g -pg ") SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -O0 -gdwarf-3 -g -pg") MESSAGE(STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS}) MESSAGE(STATUS "CFLAGS: " ${CMAKE_C_FILAGS}) endif() #设置生成的so动态库最后输出的路径 #设置bin和lib库目录 SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release) #设置bin和lib库目录 # debug和release版本目录不一样 SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) add_compile_options(-fPIC) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_SRCS 变量 aux_source_directory(. DIR_SRCS) # 添加头文件路径 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/dir1") # 添加 dir1 子目录 add_subdirectory(dir1) # 添加头文件路径 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/dir2") # 添加 dir2 子目录 add_subdirectory(dir2) # 指定生成目标 add_executable(multi-dir main.c) # 添加链接库 target_link_libraries(multi-dir Dir1 Dir2) # 将执行文件安装到bin目录 INSTALL(TARGETS multi-dir RUNTIME DESTINATION bin)
4.7 设置执行目录+编译debug和release版本
最外层CMakeLists.txt
# CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) PROJECT(0VOICE) ADD_SUBDIRECTORY(src bin) SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release) #INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/0voice) INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/0voice)
src目录下CMakeLists.txt
# CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 设置release版本还是debug版本 if(${CMAKE_BUILD_TYPE} MATCHES "Release") message(STATUS "Release版本") set(BuildType "Release") SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -DNODEBUG -O3 -Wall") SET(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -DNODEBUG -O3 -Wall") MESSAGE(STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS}) MESSAGE(STATUS "CFLAGS: " ${CMAKE_C_FLAGS}) else() # CMAKE_BUILD_TYPE 不带参数就是debug版本 set(BuildType "Debug") message(STATUS "Debug版本") SET(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -Wall -O0 -gdwarf-3 -g -pg ") SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -O0 -gdwarf-3 -g -pg") MESSAGE(STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS}) MESSAGE(STATUS "CFLAGS: " ${CMAKE_C_FILAGS}) endif() #设置生成的so动态库最后输出的路径 #设置bin和lib库目录 SET(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release) #设置bin和lib库目录 # debug和release版本目录不一样 SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) add_compile_options(-fPIC) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_SRCS 变量 aux_source_directory(. DIR_SRCS) # 添加头文件路径 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/dir1") # 添加 dir1 子目录 add_subdirectory(dir1) # 添加头文件路径 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/dir2") # 添加 dir2 子目录 add_subdirectory(dir2) # 指定生成目标 add_executable(multi-dir main.c) # 添加链接库 target_link_libraries(multi-dir Dir1 Dir2) # 将执行文件安装到bin目录 INSTALL(TARGETS multi-dir RUNTIME DESTINATION bin)
src/dir1目录下CMakeLists.txt
# 设置release版本还是debug版本 if(${CMAKE_BUILD_TYPE} MATCHES "Release") message(STATUS "Release版本") set(BuildType "Release") else() set(BuildType "Debug") message(STATUS "Debug版本") #SET(CMAKE_C_FILAGS "-O0 -g") endif() #设置lib库目录 set(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release) # debug和release版本目录不一样 #设置生成的so动态库最后输出的路径 SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) add_compile_options(-fPIC) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_LIB_SRCS 变量 aux_source_directory(. DIR_LIB_SRCS) # 生成链接库Dir1 #add_library (Dir1 ${DIR_LIB_SRCS}) # 生成动态库 add_library (Dir1 SHARED ${DIR_LIB_SRCS}) # 将库文件安装到lib目录 INSTALL(TARGETS Dir1 DESTINATION lib) # 将头文件include INSTALL(FILES dir1.h DESTINATION include)
src/dir2目录下CMakeLists.txt
# 设置release版本还是debug版本 if(${CMAKE_BUILD_TYPE} MATCHES "Release") message(STATUS "Release版本") set(BuildType "Release") MESSAGE(STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS}) MESSAGE(STATUS "CFLAGS: " ${CMAKE_C_FLAGS}) else() set(BuildType "Debug") message(STATUS "Debug版本") MESSAGE(STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS}) MESSAGE(STATUS "CFLAGS: " ${CMAKE_C_FLAGS}) endif() #设置lib库目录 set(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release) # debug和release版本目录不一样 #设置生成的so动态库最后输出的路径 SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType}) add_compile_options(-fPIC) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_LIB_SRCS 变量 aux_source_directory(. DIR_LIB_SRCS) # 生成链接库Dir2 #add_library (libDir2.a STATIC ${DIR_LIB_SRCS}) # 生成动态库 add_library (Dir2 SHARED ${DIR_LIB_SRCS}) # 将库文件安装到lib目录 INSTALL(TARGETS Dir2 DESTINATION lib) # 将头文件include INSTALL(FILES dir2.h DESTINATION include)