make与Makefile,cmake与CMakeLists.txt
make
用来编译c++项目,make
命令根据Makefile
中配置的编译链接关系;由于Makefile
文件的制作是个大工程,因此出现了cmake工具
,cmake
根据CMakeLists.txt
来执行cmake命令;
使用CMake编写跨平台工程的流程如下:
(1)编写源文件
(2)编写CMakeLists.txt
(3)由CMake根据CMakeLists.txt来生成相应的makefile文件
(4)使用make并根据makefile调用gcc来生成相应的可执行文件
CMake是一个可以跨平台的编译工具,可以用简单的语句来描述所有平台的编译过程。他能够输出各种各样的 makefile 或者工程文件。和make与makefile类似,我们在使用CMake时同样也需要一个文件来提供规则,这个文件就是CMakeLists
CMakeLists.txt
编写CMakeLists.txt最常用的功能就是调用其他的.h头文件和.so/.a库文件,将.cpp/.c/.cc文件编译成可执行文件或者新的库文件。
cmake_minimun_version(VERSION 3.4.1)
project(xxx)
aux_source_directory(路径 变量)
set(变量 文件名/路径/...)
add_definitions(编译选项)
message(消息)
add_subdirectory(子文件夹名称)
add_executable(可执行文件名称 文件)
add_library(myCommonLib STATIC util.cpp)
add_library(myCommonLib SHARED util.cpp)
include_directories(路径)
link_directories(路径)
target_link_libraries(库文件名称/可执行文件名称 链接的库文件名称)
如何设置DGB调试模式请看这里
CMakeLists设置源文件的方法
1.明确制定包含的源文件
add_library(demo demo.cpp test.cpp util.cpp)
2.搜索所有cpp文件
# 发现一个目录下所有的源代码文件,并将列表存储再一个变量中(不会递归遍历目录)
aux_source_directory(. SRC_LIST)
add_library(demo ${SRC_LIST})
3.自定义搜索规则
file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})
#或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
#或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST) ${SRC_PROTOCOL_LIST)
添加编译选项
功能1
add_definitions
的功能和C/C++中的#define
是一样的
add_definitions(-DTEST_DEBUG)
于是cpp代码中,就可以使用TEST_DEBUG
这个宏了
#ifdef TEST_DEBUG
...
#else
...
#endif
问题是,由谁来驱动定义这个宏呢?通过结合options指令可以实现
# 设置一个宏选项默认值ON,
# option选项 不会影响到cpp代码(不会添加#define宏)
option(TEST_DEBUG "test" ON)
if(TEST_DEBUG )
message("itis" ${TEST_IT_CMAKE})
add_definitions(-DTEST_DEBUG )
endif()
最后,在执行cmake时,就可以设置该选项了,并传递该值下去;
cmake .. -DTEST_DEBUG=1
通过cmake-gui也可以很方便的配置选项,如下:
功能2
add_definitions("-Wall -g")
gcc -c main.c -o test
gcc -g -Wall -c main.c -o tes
CMakeLists 查找so库的方法
#在指定目录下搜索一个库, 保存在变量MY_LIB中
find_library(MY_LIB "usr/lib/libmylib.so" )
#链接这个库
target_link_libraries(${PROJECT_NAME} ${MY_LIB})
- 常用的预定义变量
变量 | 说明 |
---|
PROJECT_SOURCE_DIR | 工程根目录 |
PROJECT_BINARY_DIR | 运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build |
PROJECT_NAME | 返回通过project命令定义的项目名称 |
CMAKE_CURRENT_SOURCE_DIR | 当前处理的CMakeLists.txt所在的路径 |
CMAKE_CURRENT_BINARY_DIR | target 编译目录 |
CMAKE_CURRENT_LIST_DIR | CMakeLists.txt的完整路径 |
CMAKE_CURRENT_LIST_LINE | 当前所在的行 |
CMAKE_MODULE_PATH | 定义自己cmake模块所在的路径。SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块 |
EXECUTABLE_OUTPUT_PATH | 重新定义目标二进制可执行文件的存放位置 |
LIBRARY_OUTPUT_PATH | 重新定义目标链接库的存放位置 |
-
环境变量
- 使用环境变量
$ENV{name}
- 写入环境变量
set(ENV{name} value)
-
cmake
命令的常用参数
Cmake命令行使用:
-G 指明生成的Makefile格式
-D 添加参数
-S 指明源码位置
-B 指明输出路径
例如:
cmake -G “MinGW Makefiles” -S “源码路径” -B “输出路径”
或者
cmake -G “MinGW Makefiles” -D CMAKE_TOOLCHAIN_FILE=“编译工具链路径” -S “源码路径” -B “输出路径”
注意:Cmake是不支持中文的,无论是GUI还是命令行,都严禁出现中文字符.
- 一个项目框架文件目录组织
- project
- .gitignore
- README.md
- LICENCE.md
- CMakeLists.txt
- cmake
- FindSomeLib.cmake
- something_else.cmake
- include
- project
- lib.hpp
- src
- CMakeLists.txt
- lib.cpp
- apps
- CMakeLists.txt
- app.cpp
- tests
- CMakeLists.txt
- testlib.cpp
- docs
- CMakeLists.txt
- extern
- googletest
- scripts
- helper.py
- Do’s and Don’ts
不好的 CMake 的用法
不要使用全局函数,例如 link_directories,include_libraries,add_definitions 等,请你忘记它们
不要滥用 PUBLIC,除非有依赖传递,否则请你使用 PRIVATE 替换 PUBLIC
不要使用 GLOB 来添加文件
不要直接链接文件,而是链接目标
链接时千万不要跳过 PUBLIC/PRIVATE,这会导致未来的链接都没有关键字
良好的 CMake 用法
把 CMake 视作代码,保持它的整洁和可读性
围绕 target 构建你的 CMake。将需要的信息打包在 target 里,然后链接那个目标
导出你的接口
写 Config.cmake 文件,这是一个库作者应该做的,可以方便别人使用你的库
使用 ALAS 目标,以保持使用一致性
将常用的功能提取成函数或者宏,通常函数更好
使用小写的函数名,全大写是变量
使用 cmake_policy 或者 range of versions
如何使用CMakeLists.txt 完成一次编译过程
创建如下目录结构
- /myCpp
- CMakeLists.txt
- /build
- /src
- myHello.cpp
myHello.cpp
#include <iostream>
int main() {
std::cout<<"Hello world!"<<std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(Hello)
MESSAGE(STATUS"This is BINARY_dir" ${PROJECT_BINARY_DIR})
MESSAGE(STATUS"This is SOURCE_dir"${PROJECT_SOURCE_DIR})
aux_source_directory(./src DIR_SRCS)
add_executable(${PROJECT_NAME} ${DIR_SRCS})
编译过程
$ cd build
$ cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
STATUS"This is BINARY_dir"/home/bing/bingCpp/myDemo/build
STATUS"This is SOURCE_dir"/home/bing/bingCpp/myDemo
-- Configuring done
-- Generating done
-- Build files have been written to: /home/bing/bingCpp/myDemo/build
$ make
Scanning dependencies of target Hello
[ 50%] Building CXX object CMakeFiles/Hello.dir/src/main.cpp.o
[100%] Linking CXX executable Hello
[100%] Built target Hello
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)