CMake:
你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作。
CMake 就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeLists.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等 [1]。
总结一句话:CMake主要为了生成 Makefile,无需关注系统平台
CMake 常用命令:
cmake_minimum_required(VERSION 3.10)
:指定运行 CMakeLists.txt 所需要最低 cmake 版本(3.10)
project(demo1)
:参数为 demo1, 该命令表示该项目的名称为 demo1
add_executable(demo1 main.cpp)
:第一个参数为生成可执行的程序名称(demo1),main.cpp 为源文件
aux_source_directory(. DIR_SRCS)
:查找当前目录下的所有源文件,将名称保存到 DIR_SRCS 变量中
- 变量使用方式:
add_executable(demo2 ${DIR_SRCS})
:生成 demo2 可执行文件所需要的所有源文件
add_library(MyAdd ${DIR_LIB_SRCS})
:添加链接库,链接库的名称为 MyAdd
- 链接库的使用:
target_link_libraries(demo3 MyAdd)
:生成 demo3 可执行程序时,要链接 MyAdd 库
add_subdirectory(math)
:添加子目录,该子目录放有自己的 CMakeLists.txt 用来生成子目录的要提供的链接库
set(LIBRARY_OUTPUT_NAME ${PROJECT_BINARY_DIR}/lib)
:设置依赖库的输出目录
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
:设置可执行文件的输出目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/mylib)
:设置头文件的路径
PROJECT_SOURCE_DIR
:项目根目录PROJECT_BINARY_DIR
:build 根目录- 设置了头文件的路径,在使用头文件时无需指定头文件路径(无需:#include “…/lib/add.h”)
CMake 用例:
目录结构:
.
├── build
├── CMakeLists.txt
├── lib
│ ├── add.c
│ ├── add.h
│ └── CMakeLists.txt
└── src
├── CMakeLists.txt
└── main.c
根目录 ./CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(demo4)
add_subdirectory(lib)
add_subdirectory(src)
lib 目录中的 add.h
#ifndef _H_ADD_H_
#define _H_ADD_H_
int Add(int a, int b);
#endif
lib 目录中的 add.c
#include "add.h"
int Add(int a, int b)
{
return a + b;
}
lib 目录中的 CMakeLists.txt
aux_source_directory(. DIR_LIB_SRCS)
set(LIBRARY_OUTPUT_NAME ${PROJECT_BINARY_DIR}/lib)
add_library(MyAdd ${DIR_LIB_SRCS})
src 目录中的 main.c
#include <stdio.h>
#include "add.h"
int main()
{
int a = 1;
int b = 2;
int addResult = Add(a, b);
printf("%d + %d = %d\n", a, b, addResult);
return 0;
}
src 目录中的 CMakeLists.txt
include_directories(${PROJECT_SOURCE_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
aux_source_directory(. DIR_SRCS)
add_executable(demo4 ${DIR_SRCS})
target_link_libraries(demo4 MyAdd)
CMake 用例运行(demo4 为项目根目录)
mrs@mrs-virtual-machine:~/Desktop/CMake/demo4$ cd build/
mrs@mrs-virtual-machine:~/Desktop/CMake/demo4/build$ cmake ..
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/mrs/Desktop/CMake/demo4/build
mrs@mrs-virtual-machine:~/Desktop/CMake/demo4/build$ make
Scanning dependencies of target MyAdd
[ 25%] Building C object lib/CMakeFiles/MyAdd.dir/add.c.o
[ 50%] Linking C static library libMyAdd.a
[ 50%] Built target MyAdd
Scanning dependencies of target demo4
[ 75%] Building C object src/CMakeFiles/demo4.dir/main.c.o
[100%] Linking C executable ../bin/demo4
[100%] Built target demo4
mrs@mrs-virtual-machine:~/Desktop/CMake/demo4/build$ ./bin/demo4
1 + 2 = 3
mrs@mrs-virtual-machine:~/Desktop/CMake/demo4/build$