工具链
单源文件可以直接命令生成.exe
命令行直接编译源文件
g++ *.cpp -o app
app.exe
./app
编写CMakelist.txt
# ======================================================================================
# 指定cmake的最低版本
cmake_minimum_required(VERSION 3.0.0)
# 指定工程名
project(CALC)
# 生成可执行文件名app: add_executable(可执行程序名 源文件名称) 后面的源文件用空格or;
# add_executable(app add.c div.c main.c mult.c sub.c)
# ======================================================================================
# 设置变量值: set(变量名, 变量值) 后面的变量值用空格隔开
set(SRC_LIST add.c div.c main.c mult.c sub.c)
# 取变量值
add_executable(app ${SRC_LIST})
# 设置c++版本为c++11
set(CMAKE_CXX_STANDARD 11)
# 设置app.exe的输出路径
set(HOME /home/fyq/...)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
# ======================================================================================
# 搜索文件
# aux_source_directory(${PROJECT_SOURSE_DIR} SRC_LIST)
# file(GLOB/GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURSE_DIR}/*.cpp)
# ======================================================================================
执行cmake
命令,cmake
后面跟的目录是CMakelist.txt
所在的目录,会生成一系列文件,一般是在build
文件夹中执行,生成Makefile
文件后执行make
命令即可生成可执行文件
set
命令
set(SRC_LIST add.c div.c main.c mult.c sub.c)
:设置SRC_LIST
的值为add.c ...
add_executable(app ${SRC_LIST})
:取变量值用${}
c++
版本: c++11
、c++14
、c++17
默认是c++98
g++ *.cpp -std=c++11 -o app
CMakelist.txt
文件中指定 ,加入set(CMAKE_CXX_STANDARD 11)
set(HOME /home/fyq/...)
set(EXECUTABLE_OUTPUT PATH ${HOME}/bin)
set
命令需要找到所有的文件,仍然很麻烦,因此有搜索文件命令
aux_source_directory
${PROJECT_SOURSE_DIR}:CMakelist.txt所在目录路径
aux_source_directory(${PROJECT_SOURSE_DIR} SRC_LIST)
:找到源文件目录下的所有文件,并赋值给SRC_LIST
add_executable(app ${SRC_LIST})
file命令
${CMAKE_CURRENT_SOURSE_DIR}:CMakelist.txt所在目录路径
file(GLOB/GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURSE_DIR}/*.cpp)
:递归搜索某目录文件搜索所有.cpp
文件,将值赋给SRC
变量指定头文件所在路径
include_directories(${CMAKE_CURRENT_SOURSE_DIR}/include)
:head.h
在/include
目录下动态库和静态库
add_exectable()
命令前运行,但是动态库不会被加,因此需要在生成可执行文件后执行,一般就是放在文件最末尾lib_xxx.xxx
组成,第二个是xxx
是后缀
windows
:lib_xxx.dll
linux
:lib_xxx.so
windows
:lib_xxx.lib
linux
:lib_xxx.a
add.c div.c ...
不需要main.c
add_library(库名称 STATIC 源文件1 源文件2...)
:add_library(calc STATIC ${SRC})
add_library(库名称 SHARED 源文件1 源文件2...)
:``add_library(calc SHARED ${SRC})`set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURSE_DIR}/lib)
有了静态库和动态库之后,之前的div.c add.c...
就不需要了,只需要使用库文件就行
link_libraries(静态库名字1 名字2...)
:link_libraries(calc)
link_directories(path)
:link_directories(${CMAKE_CURRENT_SOURSE_DIR}/lib)
target_link_libraries(动态库名称)
:target_link_libraries(app calc)
app是可执行文件,表示app要链接动态库,后面的calc是被链接的动态库名称日志
message(重要程度 消息)
:message(STATUS "message status")
默认重要
STATUS
:非重要WARNING
:警告,继续执行SEND_ERROR
:继续执行,但是跳过所有生成步骤FATAL_ERROR
:cmake错误,终止所有变量操作
list(APPEND 变量名 [子字符串])
:list(APPEND ${SRC} ${TEMP})
将TEMP
的值追加到SRC
中set(变量名 字符串1 字符串2 ..)
:set(tmp ${tmp1} ${tmp2})
将tmp1
和tmp2
的内容拼接,放到tmp
中list(REMOVE_ITEM 变量名 [子字符串])
:list(REMOVE_ITEM ${SRC} main.cpp)
list
其他功能 list
底层存储了很多的字符串,每个字符串通过;
相隔
list(LENGTH 列表名字 输出变量)
list(GET 列表名字 索引位置)
-1
表示最后一个元素list(JOIN 列表名字 指定连接字符串 输出变量)
list(FINO 列表名字 搜索元素 输出变量)
list(INSERT 列表名字 索引 插入元素1 插入元素2...)
list(POP_BACK 列表名字 存储弹出元素的变量:可省略)
list(REMOVE_AT 列表名字 索引)
list(REMOVE_DUPLICATED 列表名字)
list(REVERSE 列表名字)
list(SORT 列表名字 COMPARE:... CASE:... ORDER:...)
COMPARE
:指定排序方法
STRING
:字母顺序,默认FILE_BASENAME
:若是一系列路径名,会使用basename
排序NATURAL
:使用自然数顺序排序CASE
:是否大小写敏感
SENSITIVE
:大小写敏感,默认INSENSITIVE
:大小写不敏感ORDER
:指定排序顺序
ASCENDING
:升序排列,默认DESCENDING
:降序排序自定义宏 用来控制日志是否输出
add_definitions(-D宏名称)
:add_definitions(-DDEBUG)
定义了一个DEBUG宏Cmake
嵌套
子节点可以使用父节点的变量值
$ tree
.
├── build
├── calc
│ ├── add.cpp
│ ├── CMakeLists.txt
│ ├── div.cpp
│ ├── mult.cpp
│ └── sub.cpp
├── CMakeLists.txt
├── include
│ ├── calc.h
│ └── sort.h
├── sort
│ ├── CMakeLists.txt
│ ├── insert.cpp
│ └── select.cpp
├── test1
│ ├── calc.cpp
│ └── CMakeLists.txt
└── test2
├── CMakeLists.txt
└── sort.cpp
假如目录结构如上图所示,其中
include
是头文件目录calc
对应加减乘除sort
对应两种排序test1
和test2
是计算器和排序的测试程序为了让test1
和test2
能使用计算器和排序,因此需要将calc
和sort
里的内容生成库文件,若源文件多,则生成动态库,否则生成静态库,因为生成静态库会将库文件放在输出的文件夹中
添加子目录
add_subdirectory(子目录名)
:add_subdirectory(calc)
示例
根目录CMakelist.txt
:
# 最小版本
cmake_minimum_required(VERSION 3.0)
# 可执行文件名
peoject(test)
# 静态库输出路径
set(LIBPATH ${CMAKE_CURRENT_SOURSE_DIR}/lib)
# 头文件目录路径
set(HEADPATH ${CMAKE_CURRENT_SOURSE_DIR}/lib)
# 生成库文件名称
set(CALCLIB calc)
set(SORTLIB sort)
# 可执行文件程序名
set(APPNAME1 app1)
set(APPNAME2 app2)
# 给当前目录添加子节点
add_subdirectory(calc)
add_subdirectory(sort)
add_subdirectory(test1)
add_subdirectory(test2)
calc
目录CMakelist.txt
sort
目录下的同理
# 最小版本
cmake_minimum_required(VERSION 3.0)
# 可执行文件名
peoject(calc)
# 搜索源文件 在./下搜索所有文件,放到SRC中
aux_sourse_directory(./ SRC)
# 添加头文件 因为calc用到了calc.h
include_directories(${HEADPATH}) # 子节点可以使用父节点的变量
# 设置库文件输出位置 LIBRARY_OUTPUT_PATH是系统定义的宏
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
# 生成静态库文件
add_library(${CALCLIB} STATIC ${SRC})
test1
目录CMakelist.txt
test2
目录同理
# 最小版本
cmake_minimum_required(VERSION 3.0)
# 可执行文件名
peoject(test1)
# 搜索文件
aux_sourse_directory(./ SRC)
# 添加头文件
include_directories(${HEADPATH})
# 指定静态库文件地址
link_directories(${LIBPATH})
# 链接静态库
link_libraries(CALCLIB)
# 设置可执行文件生成路径 EXECUTABLE_OUTPUT_PATH是系统定义的宏
set(EXECUTABLE_OUTPUT_PATH ${EXECPATH})
# 生成可执行文件
add_executable(${APPNAME1} ${SRC})
在静态库中链接静态库
link_directories
和link_libraries
find_package()
:查找依赖包