1. cmake概述及例子
CMake快速入门
cmake、qmake、cl之间关系
1.1 各种cmake
cmake根据CMakeLists.txt生成makefile,make根据makefile行编译。
1.1.1 最简cmake:生成可执行程序(一个文件)
#CMakeLists.txt
cmake_minimum_required(VERSION 2.8.9) #指定cmake最低版本
project (hello) #指定项目名称
add_executable(hello helloworld.cpp) #指定编译一个可执行文件
mkdir build
cd build
cmake .. 或 ccmake .. #生成Makefile文件
make -j8 #根据Makefile编译
make install #安装
1.1.2 生成可执行程序(带目录)
cmake_minimum_required(VERSION 2.8.9)
project(directory_test)
include_directories(include) #添加头文件搜索路径
#set(SOURCES src/mainapp.cpp src/Student.cpp) #手动添加源文件
file(GLOB SOURCES "src/*.cpp") #添加源文件
add_executable(testStudent ${SOURCES}) #生成可执行文件
1.1.3 生成动态库(带目录)
project(directory_test)
set(CMAKE_BUILD_TYPE Release)
include_directories(include) #添加头文件搜索目录
file(GLOB SOURCES "src/*.cpp") #添加源文件
add_library(testStudent SHARED ${SOURCES}) #生成库文件(动态库)
install(TARGETS testStudent DESTINATION /usr/lib) #安装库文件
1.1.4 生成静态库(带目录)
cmake_minimum_required(VERSION 2.8.9)
project(directory_test)
set(CMAKE_BUILD_TYPE Release)
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_library(testStudent STATIC ${SOURCES}) #生成静态库
install(TARGETS testStudent DESTINATION /usr/lib) #安装静态库
1.1.5 生成可执行程序(使用共享库)
#include"Student.h"
int main(int argc, char *argv[])
{
Student s("Joe");
s.display();
return 0;
}
cmake_minimum_required(VERSION 2.8.9)
project (TestLibrary)
set ( PROJECT_LINK_LIBS libtestStudent.so )
link_directories( ~/exploringBB/extras/cmake/studentlib_shared/build ) #添加库搜索路径
include_directories(~/exploringBB/extras/cmake/studentlib_shared/include) #添加头文件搜索路径
add_executable(libtest libtest.cpp)
target_link_libraries(libtest ${PROJECT_LINK_LIBS} ) #插入共享库,必须在add_executable之后
1.1.6 综合示例
1.2 cmake与qmake
cmake和qmake对比
cmke转qmake例子
qmake转cmake(lib)
cmake与qmake例子如下:
cmake:
cmake_minimum_required(VERSION 3.10)
project(osganimate)
include_directories("xx/osg/build/include")
link_directories("xx/osg/build/lib")
file(GLOB OSG_LIBS "xx/osg/build/lib/libosg*")
add_executable(${PROJECT_NAME} osganimate.cpp)
target_link_libraries(${PROJECT_NAME} -lOpenThreads ${OSG_LIBS})
qmake:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = osg_qt_test
SOURCES += \
osganimate.cpp
OSG_LIBS_PATH = xx/osg/build/lib/
DEPENDPATH += xx/osg/build/lib/
INCLUDEPATH += xx/osg/build/include
LIBS += \
-L $$OSG_LIBS_PATH -losgAnimation \
-L $$OSG_LIBS_PATH -losgDB \
-L $$OSG_LIBS_PATH -losgFX \
-L $$OSG_LIBS_PATH -losgGA \
-L $$OSG_LIBS_PATH -losgManipulator \
-L $$OSG_LIBS_PATH -losgParticle \
-L $$OSG_LIBS_PATH -losgPresentation\
-L $$OSG_LIBS_PATH -losgShadow \
-L $$OSG_LIBS_PATH -losgSim \
-L $$OSG_LIBS_PATH -losg \
-L $$OSG_LIBS_PATH -losgTerrain \
-L $$OSG_LIBS_PATH -losgText \
-L $$OSG_LIBS_PATH -losgUI \
-L $$OSG_LIBS_PATH -losgUtil \
-L $$OSG_LIBS_PATH -losgViewer \
-L $$OSG_LIBS_PATH -losgVolume \
-L $$OSG_LIBS_PATH -losgWidget \
-L $$OSG_LIBS_PATH -lOpenThreads
QMake 和 CMake 的思路是类似的,无非是添加头文件路径和库路径,然后链接指定的库,QT 的 Pro 文件(qmake)貌似不太支持通配符的写法。
2. cmake语法
2.1 常用命令
指令 | 意义 |
---|---|
CMAKE_MINIMUM_REQUIRED | cmake最低版本要求 |
PROJECT | |
SET | 设置变量: set(SRC_LIST main.cpp test.cpp) |
MESSAGE | |
ADD_EXECUTABLE | 生成可执行文件 |
ADD_LIBRARY | 生成库文件 |
ADD_SUBDIRECTORY | 添加源文件子目录 |
INCLUDE_DIRECTORIES | 添加头文件搜索路径 |
LINK_DIRECTORIES | 添加库搜索目录 |
TARGET_LINK_LIBRARIES | 插入共享库 |
INSTALL | 安装二进制、动态库、静态库、文件、目录、脚本等 |
SUBDIRS | |
add_compile_options | 增加源文件的编译选项: -fPIC, -fpic, -fpie, -fPIE |
ADD_DEFINITIONS | 为源文件的编译添加由-D定义的标志: add_definitions(-DFOO -DBAR …) |
ADD_DEPENDENCIES | 添加依赖 |
ADD_TEST | |
ENABLE_TESTING | |
AUX_SOURCE_DIRECTORY | 将dir目录下所有源文件名字保存在变量varialble中:aux_source_directory(. DIR_SRCS) |
EXEC_PROGRAM | |
FILE | |
INCLUDE | |
FIND_FILE | |
FIND_LIBRARY | |
FIND_PATH | |
FIND_PROGRAM | |
FIND_PACKAGE | 查找依赖包:find_package(Protobuf REQUIRED) |
list | 追加或者删除变量的值: list(APPEND SRC_LIST test.cpp) list(REMOVE_ITEM SRC_LIST main.cpp) |
install(TARGETS xx libxx.so libxx.a
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
INSTALL_DIR DESTINATION ${CMAKE_INSTALL_LIBDIR})
安装路径可以通过CMAKE_INSTALL_PREFIX设置
#目录拷贝
install(DIRECTORY xx/cofnig DESTINATION ${CMAKE_INSTALL_PREFIX}/)
#文件拷贝
install(FILES xx DESTINATION ${CMAKE_INSTALL_PREFIX}/)
files(GLOB dep_libs "xx/xx/*.so*)
install(FILES dep_libs DESTINATION ${CMAKE_INSTALL_PREFIX}/)
#编译过程中执行命令(非cmake时执行)
install(CODE "messge(\”xxxx\"))
install(CODE "execute_process(COMMAND bash -c \"cp xx/*.so ${dst} -rf\") ")
,
2.2 常用变量
SET(SRC_LIST main.cpp) #定义变量
${SRC_LIST} #引用变量
变量 | 意义 |
---|---|
CMAKE_BINARY_DIR PROJECT_BINARY_DIR <projectname>_BINARY_DIR | 这三个变量指代的内容是一致的,如果是 in source 编译,指得就是工程顶层目录,如果是 out-of-source 编译,指的是工程编译发生的目录。 |
CMAKE_SOURCE_DIR PROJECT_SOURCE_DIR <projectname>_SOURCE_DIR | 这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。 也就是在 in source 编译时,他跟 CMAKE_BINARY_DIR 等变量一致。 |
CMAKE_CURRENT_SOURCE_DIR | 指的是当前处理的 CMakeLists.txt 所在的路径,比如上面我们提到的 src 子目录。 |
CMAKE_CURRRENT_BINARY_DIR | 如果是 in-source 编译,它跟 CMAKE_CURRENT_SOURCE_DIR 一致, 如果是 out-of-source 编译,他指的是 target 编译目录。 使用我们上面提到的 ADD_SUBDIRECTORY(src bin)可以更改这个变量的值。 使用 SET(EXECUTABLE_OUTPUT_PATH <新路径>)并不会对这个变量造成影响,它仅仅修改了最终目标文件存放的路径。 |
CMAKE_CURRENT_LIST_FILE | 输出调用这个变量的 CMakeLists.txt 的完整路径 |
CMAKE_CURRENT_LIST_LINE | 输出这个变量所在的行 |
CMAKE_MODULE_PATH | 这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块,这些 cmake 模块是随你的工程发布的,为了让 cmake 在处理CMakeLists.txt 时找到这些模块,你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。 比如 SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 这时候你就可以通过 INCLUDE 指令来调用自己的模块了。 |
EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH | 分别用来重新定义最终结果的存放目录,前面我们已经提到了这两个变量。 |
PROJECT_NAME | 返回通过 PROJECT 指令定义的项目名称。 |
CMAKE_CXX_STANDARD | SET(CMAKE_CXX_STANDARD 14):设置c++版本 |
CMAKE_BUILD_TYPE | SET( CMAKE_BUILD_TYPE Release):设置编译方式 |
#指定编译选项
CMAKE_C_FLAGS : 指定gcc编译选项,如-02 ,-g,当然也可用通过add_definitions设置。
CMAKE_CXX_FLAGS: 指定g++编译选项。
CMAKE_C_FLAGS_DEBUG: 指定debug版本编译选项
#指定链接选项
CMAKE_EXE_LINKER_FLAGS
CMAKE_MODILE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS
#指定编译器
CMAKE_C_COMPILER: 指定C编译器,如gcc
CMAKE_CXX_COMPILER: 指定C++编译器,如g++
BUILD_SHARED_LIBS: 指定默认生成库文件类型,on:动态库,off 静态
CMAKE_BUILD_TYPE: 设置编译类型,如Debug、Release
#指定RPATH相关选项,如果为true,则关闭rpath功能
CMAKE_SKIP_RPATH; 构建和安装期间
CMAKE_SKIP_BUILD_RPATH: 构建期间
CMKAE_INSTALL_RPATH: 安装期间
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../map_common/lib) #module库
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../map_common/lib) #静态库
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin) #可执行
2.3 系统变量
$ENV{NAME} #引用系统环境变量
MESSAGE(STATUS "HOME dir: $ENV{HOME}")
变量 | 意义 |
---|---|
CMAKE_INCLUDE_CURRENT_DIR | 自动添加 CMAKE_CURRENT_BINARY_DIR 和 CMAKE_CURRENT_SOURCE_DIR 到当前处理的 CMakeLists.txt。相当于在每个 CMakeLists.txt 加入: INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) |
CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE | 将工程提供的头文件目录始终至于系统头文件目录的前面,当你定义的头文件确实跟系统发生冲突时可以提供一些帮助。 |
CMAKE_INCLUDE_PATH CMAKE_LIBRARY_PATH | 我们在上一节已经提及。 |