文章目录
CMake简介
跨平台管理C/C++项目,不依赖于os
基本语法规则
-
变量:${变量名}
-
指令{参数1 参数2 …} 参数之间用空格分开
注:指令和大小写无关,参数和变量大小写相关。但推荐指令和变量都大写
eg:ADD_EXECUTABLE(hello main.cpp func.cpp)
- 当文件名或或者路径中有空格要加引号
- 文件后缀可以不写,他会自动去找.c和.cpp,最好不要这样写,可能会有这两个文件main.cpp和main
外部构建
构建一个build目录,cmake产生的临时文件都放在build目录里,不会对其他文件产生影响
CMake一个Hello Wrold工程
1.Hello World工程的建立-cmake01
//目录树结构
.
├── CMakeLists.txt
├── COPYRIGHT
├── README
├── build
├── doc
├── runhello.sh
└── src
2.CMakeLists.txt
PROJECT(HELLO) #创建一个名为HELLO的工程
ADD_SUBDIRECTORY(src bin) #添加子目录,并指定编译输出路径为bin
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/) #安装文件COPYRIGHT和RENAME
INSTALL(PROGRAMS runhello.sh DESTINATION bin/) #安装脚本runhello.sh
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/) #安装目录
-
PROJECT关键字
PROJECT() :指定项目名称
-
ADD_SUBDIRECTORY关键字
ADD_SUBDIRECTORY(src bin)
如果不进行 bin 目录的指定,那么编译结果(包括中间结果)都将存放在build/src 目录,如下图所示
-
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)
FILES:文件
DESTINATION:
- 绝对路径
- 相对路径:实际路径为 ${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径
CMAKE_INSTALL_PREFIX 默认是在 /usr/local/(mac的也是),可以在cmake时指定CMAKE_INSTALL_PREFIX路径
eg:cmake -D CMAKE_INSALL=/usr
-
INSTALL(PROGRAMS runhello.sh DESTINATION bin/)
PROGRAMS:非目标文件的可执行程序安装(比如脚本)
-
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/)
DIRECTORY:目录
注:abc 是将目录abc安装到指令路径;abc/ 是将目录abc下的内容安装到指定路径
3. src/CMakeLists.txt
ADD_EXECUTABLE(hello main.cpp) #创建名为hello的可执行文件(基于main.cpp)
-
ADD_EXECUTABLE指令
ADD_EXECUTABLE(name S R C L I S T ) :基于源文件 {SRC_LIST}):基于源文件 SRCLIST):基于源文件{SRC_LIST},创建可执行名为name的可执行文件
4.main.cpp
#include<iostream>
int main(){
std::cout<<"hello world"<<std::endl;
}
5.进行cmake…
- 在build目录下执行cmake …
- 继续执行make、make install
静态库和动态库的构建
1.静态库和动态库区别
静态库:扩展名一般为 .a 或 .lib,在编译时直接整合到程序中,编译后得到的可执行文件可独立运行
动态库:扩展名为 .so 或 .dll,编译时不会整合到程序中 ,编译后得到的可执行文件不能独立运行
2.构建实例-cmake02
//目录树结构
.
├── build
├── CMakeLists.txt
└── lib
├── CMakeLists.txt
├── hello.cpp
└── hello.h
-
CMakeLists.txt
PROJECT(HELLO) ADD_SUBDIRECTORY(lib bin)
-
lib/CMakeLists.txt
SET(LIBHELLO_SRC hello.cpp) #设置变量LIBHELLO_SRC,代表hello.cpp #添加名为hello_static的静态库(STATIC代表静态库),指向变量LIBHELLO_SRC里的内容 ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) #将hello_static重命名为hello SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") #cmake在构建一个新的target时,会尝试清理掉其他使用相同名字的库。要是不加底下这句,就会清理掉libhello.a SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) #添加名为hell的动态库(SHARED代表动态库),指向变量LIBHELLO_SRC里的内容 ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello") SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRCT_OUTPUT 1) #安装头文件和共享库 #二进制、静态库、动态库安装都用TARGETS #ARCHIVE特指静态库 LIRBRARY特指动态库 RUNTIME特指可执行目标二进制 INSTALL(FILES hello.h DESTINATION include/hello) INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
注:生成静态库或动态库时,库的名字会自动加上lib
-
lib/hello.h 和 lib/hello.cpp
#ifndef HELLO_H #define Hello_H void HelloFunc(); #endif
#include "hello.h" #include<iostream> void HelloFunc(){ std::cout<<"Hello World"<<std::endl; }
-
执行cmake…
cmake -D CMAKE_INSTALL_PREFIX=/Usres/xxx
make
make install
3.使用外部共享库和文件-cmake03
//目录树
.
├── build
├── CMakeLists.txt
└── src
├── CMakeLists.txt
└── main.cpp
-
CMakeLists.txt
PROJECT(HELLO) ADD_SUBDIRECTORY(src bin)
-
src/CMakeLists.txt
#指定头文件的搜索路径 INCLUDE_DIRECTORIES(/Users/xxx/include/hello) #找到引用函数 LINK_LIBRARIES(/Users/xxx/lib/libhello.dylib) #生成可执行文件main.cpp的可执行文件hello ADD_EXECUTABLE(hello main.cpp)
-
添加共享库-即找到引用函数
-
法1:LINK_LIBRARYS 添加非标准的共享库搜索路径(并不推荐使用)
LINK_LIBRARIES(/Users/xxx/lib/libhello.dylib) 写在ADD_EXECUTABLE之前
注: 在macos下使用法1,cmake…后仍会报错,这时执行
mv /Users/xxx/lib/libhello.dylib /usr/local/lib
法2: TARGET_LINK_LIBRARIES 添加需要链接的共享库
TARGET_LINK_LIBRARIES(hello libhello.dylib) 写在ADD_EXECUTABLE之后
注:指定头文件和共享库的非标准搜索路径也可以用环境变量CMAKE_INCLUDE_PATH 和 CMAKE_LIBRARY_PATH
但这两个变量是linux的环境变量不是cmake变量,需要在linux的bash中设置
emport CMAKE_INCLUDE_PATH=/Users/xxx/include/hello
emprot CMKAE_LIABRARY_PATH=//Users/xxx/lib
- 在build/bin下执行 ./hello,最后输出hello
补充知识
-
生成可执行文件的debug版本
cmake … -DCMAKE_BUILD_TYPE=debug