文章目录
- 构建工具
- cmake安装与使用
- CMakeLists.txt编写
- 使用案例
构建工具
cmake, Cross Platform Make, (对C++)跨平台编译工具,将CMakeLists.txt
文件编译为对应的文件,如linux下的 Makefile,然后使用make命令对Makefile编译,得到二进制可执行文件。
下载cmake工具
下载地址:https://github.com/Kitware/CMake/releases
cmake安装与使用
这里以CentOS 8.5 为例,进行说明,下载cmake-3.29.6-linux-x86_64.sh;
- 将下载的cmake-xx.sh拷贝到linux系统下
# scp 基于ssh
scp -r .\cmake-3.29.6-linux-x86_64.sh laufing@192.168.0.109:/home/laufing
出现以上问题,将known_hosts删除即可;也可以重新配置ssh的免密登录。
- linux下安装cmake
# 执行sh脚本,进行安装
sh cmake-3.29.6-linux-x86_64.sh
# 一路输入 y
# 创建软连接
ln -s /home/laufing/cmake-3.29.6-linux-x86_64/bin/cmake /bin/cmake # 权限不够加sudo
# 测试
[laufing@centos ~]$ cmake
Usage
cmake [options] <path-to-source>
cmake [options] <path-to-existing-build>
cmake [options] -S <path-to-source> -B <path-to-build>
Specify a source directory to (re-)generate a build system for it in the
current working directory. Specify an existing build directory to
re-generate its build system.
Run 'cmake --help' for more information.
CMakeLists.txt编写
- 官方文档参考
- 命令大小写均可;
- C++项目构建目录结构
- projectDir
- build
- CMakeLists.txt
- include
- src
- lib
- build
- projectDir
- 如下 CMakeLists.txt常用命令:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
# 指定项目名称
project(appName)
# 头文件目录
include_directories(/home/user/include) # 也可以指定多个,空格分割
include_directories(${PROJECT_BINARY_DIR}/../include) # 多次指定
# 将src下的源码 放入指定变量中
aux_source_directory(${PROJECT_BINARY_DIR}/../src SRCS) # 可多次指定
# 设置环境变量
set(SRC_PATH ${SRCS}) # 将SRCS变量中的源码 放入SRC_PATH环境变量中
# unset(VAR SRC_PATH) 取消变量
# 添加可执行文件
add_executable(app ${SRCS}) # 将SRCS变量中的源码 编译为app可执行文件 ,也可单独指定xx.cpp
# add_executable(app ${SRCS} ${HDRS} ${PROJECT_UIS_H})
# 链接库
target_link_libraries(app dl protobuf) # app可执行文件 需要连接的库文件(空格分割或换行)
# 默认到 /lib; /usr/lib; /usr/local/lib下搜索库名 (libdl.so、libprotobuf.so)
# 将 指定源码 编译为 动态库/静态库
add_library(libName SHARED ${SRCS}) # SHARED 动态库 STATIC 静态库
# windows
# lauf.lib 静态库 链接时需要放入项目代码中(项目较大)
# lauf.dll 动态库 链接时,在项目代码仅加入库的指向,执行时再按照指向搜索动态库
# linux下
# liblauf.a 静态库 lauf为库名称
# liblauf.so 动态库
# 连接so动态库时,若库文件为liblauf.so.0.0.0 , 则需要创建软连接liblauf.so , 然后链入软连接的库名
# ln -s /xx/liblauf.so.0.0.0 liblauf.so
# 查找路径
find_path(MY_PATH /home/user/dir1 /home/user/dir2) # 将查找路径存入MY_PATH变量中
# 查找库
find_library(MY_LIB pthread /lib /usr/lib /usr/local/lib) # 在指定路径下查找pthread库,存入MY_LIB变量中
# 查找包
find_package(MY_PKG p1 /xx/xx)
# 文件查找
file(GLOB_RECURSE SRCS ${PROJECT_BINARY_DIR}/../src/*.cpp) # 查找*.cpp 存入SRCS变量中
# 添加编译选项
add_compile_options(-std=c++11 -Wall)
#输出信息
message("xxx")
# 关闭控制台
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
更多参考
-
cmake的系统变量
- ${PROJECT_BINARY_DIR} 是执行cmake的目录,即build目录;同PROJECT_SOURCE_DIR
- ${PROJECT_NAME} 项目名称,即project() 指定的
- ${LIBRARY_OUTPUT_PATH} 库文件的输出目录
- ${EXECUTABLE_OUTPUT_PATH} 可执行文件的输出目录
-
cmake官网教程
使用案例
对如下项目,使用cmake编译。
- 创建多个目录
arr=('build' 'include' 'src' 'lib')
for i in ${arr[*]}
do
mkdir $i
done
- 编写cpp代码
// tool.h
#ifndef TOOL_H
#define TOOL_H
#endif
using namespace std;
// declare
const string func(const string& name); // 字符串的引用 const传参表示函数内部无法通过引用修改变量的值
// tool.cpp
#include <iostream>
#include <string>
using namespace std;
const string func(const string& name){ //
cout << "func run:" << name << endl;
return name;
}
// main.cpp
#include <iostream>
#include "tool.h"
using namespace std;
int main(){
const string name = "jack";
func(name);
return 0;
}
- 编写CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(app)
include_directories(${PROJECT_BINARY_DIR}/../include)
aux_source_directory(${PROJECT_BINARY_DIR}/../src SRCS)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
add_executable(app ${SRCS})
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../lib)
add_library(appA SHARED ${SRCS})
message(${PROJECT_SOURCE_DIR})
message(${PROJECT_NAME})
- 开始编译
# 进入build目录
cd build
cmake .
make
日志如下:
[laufing@centos build]$ cmake .
-- The C compiler identification is GNU 8.5.0
-- The CXX compiler identification is GNU 8.5.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
/home/laufing/projectDir/build
app
-- Configuring done (0.3s)
-- Generating done (0.0s)
-- Build files have been written to: /home/laufing/projectDir/build
[laufing@centos build]$ make
[ 16%] Building CXX object CMakeFiles/app.dir/home/laufing/projectDir/src/main.cpp.o
[ 33%] Building CXX object CMakeFiles/app.dir/home/laufing/projectDir/src/tool.cpp.o
[ 50%] Linking CXX executable app
[ 50%] Built target app
[ 66%] Building CXX object CMakeFiles/appA.dir/home/laufing/projectDir/src/main.cpp.o
[ 83%] Building CXX object CMakeFiles/appA.dir/home/laufing/projectDir/src/tool.cpp.o
[100%] Linking CXX shared library /home/laufing/projectDir/lib/libappA.so
[100%] Built target appA
- 测试可执行文件
# 执行
[laufing@centos build]$ ./app
func run:jack
同时在build/lib目录下生成动态库
[laufing@centos projectDir]$ cd lib
[laufing@centos lib]$ ls
libappA.so