CMake - Linux基础教程
安装CMake
打开终端,输入:
sudo apt intsall cmake
查看安装CMake版本
cmake -version
工程组织架构
src目录存放源文件,include目录包含src所引用的头文件,搭建的环境生成的对象在build文件夹下,输出的elf文件位于bin文件夹下,动态库和静态库位于lib文件夹下。
CMakeLists.txt文件的编写
只有一个源文件
- bin
- build
- include
- src
- main.cpp
在根目录下新建一个CMakeLists.txt文件。
cmake_minimum_required (VERSION 2.8) # 指定cmake的最小版本
project (demo) # 定义工程名称
add_executable(main main.cpp) # 编译可执行程序
- cd到build目录下,执行
cmake ..
命令, 成功生成Makefile文件; - 再在build目录下,执行
make
命令, elf文件成功生成; - 切换到bin目录下,运行
./main
命令,显示运算结果 - 如果需要重新生成,则运行
make clean
命令
src下有多个源文件
- bin
- build
- include
- testFunc1.h
- testFunc.h
- src
- main.cpp
- testFunc1.cpp
- testFunc.cpp
一种方法是直接在add_executable
命令中添加所有的源文件。如果源文件过多,我们可以利用cmake提供的aux_source_directory(dir var)
命令,其中dir指定目录,var存放源文件列表的变量。
aux_source_directory(. SRC_LIST) # 将当前目录下的源文件存列表到变量SRC_LIST里
add_executable(main ${SRC_LIST}) # 调用SRC_LIST
aux_source_directory(. SRC_LIST)
命令会将src目录下的所有源文件添加进来,然而并不是所有的源文件是我们需要的,此时可以利用set
命令定义SRC_LIST
存放我们需要的源文件。
set( SRC_LIST
./main.cpp
./testFunc1.cpp
./testFunc.cpp)
add_executable(main ${SRC_LIST})
对于这种正规的工程架构,我们有两种CMakeLists.txt文件的编写方式,一种是在最外层目录下建一个CMakeLists.txt文件,调用src目录下的CMakeLists.txt文件
里外两层CMakeLists.txt
- 在最外层建一个CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (demo)
add_subdirectory (src) # 向当前工程添加存放源文件的子目录,并可指定中间二进制和目标二进制的存放位置
- 执行cmake时,调用src目录下的CMakeLists.txt运行
aux_source_directory (. SRC_LIST)
include_directories (../include)
add_executable (main ${SRC_LIST})
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # 把存放elf文件的位置设置为工程根目录下的bin目录
- cd切换至buildu目录,执行
cmake ..
,再执行make
只使用一层CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (demo)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory (src SRC_LIST)
include_directories (include)
add_executable (main ${SRC_LIST})
库的编译控制与链接
库也就是预先编译好的方法的集合,加上头文件就可以被别人调用。根据链接时期不同,库可以分为静态库和动态库。静态库在程序编译时链接(常用.a结尾),而动态库在程序运行时链接完成(常以.so结尾)。两者的最大区别在于,静态库链接时直接被加载到程序中,而动态库链接时只是保留接口,与程序代码独立,有利于降低程序的耦合性。
动态库和静态库的编译控制
- build
- CMakeLists.txt
- lib
- testFunc
- testFunc.cpp
- testFunc.h
cmake_minimum_required (VERSION 3.5)
project (demo)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/testFunc/testFunc.cpp)
add_library (testFunc_shared SHARED ${SRC_LIST}) # 第一个参数指定库的名字;第二个参数决定动态还是静态,默认静态;第3个参数指定生成库的源文件
add_library (testFunc_static STATIC ${SRC_LIST})
set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "testFunc")
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
其中:
add_library
: 生成静态库或动态库
set_target_properties
: 设置最终生成库的名称
库的链接
- bin
- build
- CMakeLists.txt
- src
- main.cpp
- testFunc
- inc
- testFunc.h
- lib
- libtestFunc.a
- libtestFunc.so
cmake_minimum_required (VERSION 3.5)
project (demo)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)
# find testFunc.h
include_directories (${PROJECT_SOURCE_DIR}/testFunc/inc)
find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib) # 第一个参数是变量名称,第二个参数是参数名称,第3个参数HINTS, 第4个参数是绝对路径
add_executable (main ${SRC_LIST})
target_link_libraries (main ${TESTFUNC_LIB})
其中:
find_library
: 在指定目录下查找指定库,把库的绝对路径放在变量里。再执行cmake ..
时就会去寻找库是否存在,提前发现错误。
target_link_libraries
: 链接库与目标文件