CMake教程及使用案例

转载:https://www.hahack.com/codes/cmake

为什么需要CMake

如果你一直在windows平台上开发,使用最多的可能就是VS的开发环境,它已经集成了全套的开发环境包括构建编译等。你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作。

CMake就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到"Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。一些使用 CMake 作为项目架构系统的知名开源项目有 VTKITKKDEOpenCVOSG 等。

这里先给出CMake的官方教程

Linux 下安装CMake

1、安装gcc等必备程序包(已安装则略过此步)

yum install -y gcc gcc-c++ make automake 

2、安装wget (已安装则略过此步)

yum install -y wget

3、安装OpenSSL

yum install openssl
yum install openssl-devel

4、获取CMake源码包

wget https://cmake.org/files/v3.19/cmake-3.19.0-rc1.tar.gz

5、解压CMake源码包

tar -zxvf cmake-3.19.0-rc1.tar.gz

6、进入cmark的源码目录

cd cmake-3.19.0-rc1

7、运行当前目录下的一个文件

./bootstrap

8、运行gmake命令(这步时间有点长),如果安装了make却提示找不到gmake,只需要使用sudo ln -s /usr/bin/make /usr/bin/gmake,然后

gmake

9、进行安装

sudo gmake install

10、 安装完成,查看cmake版本号,如果输出版本号,则安装成功。

cmake --version

入门:单个源文件

简单的项目,只需要单个源文件就可以。如果现在有一个main.cpp,内容如下:

#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    cout << "Hello CMake!" << endl;
    return 0;
}

我们在同级目录下新建一个CMakeList.txt,其内容如下:

# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.19)
# 项目名称
project(demo1)
# 指定生成目标,将main.cpp生成一个名为demo1的可以执行文件
add_executable(demo1 main.cpp)

需要注意的是,CMake是不区分大小写的;# 开头该行会被视为注释;命令由命令名称、小括号、参数组成;参数之间用空格间隔。

CMake编译运行

现在我们在当前目录中使用cmake .执行,可以观察到多了几个和CMake相关的文件,如下:

CMakeCache.txt  CMakeFiles  CMakelists.txt  Makefile  cmake_install.cmake  demo1  main.cpp

其中有一个文件是Makefile,再用make命令编译就得到demo1可执行文件。

  • 直接生成二进制文件

还可以直接调用CMake构建系统以实际编译/链接项目

cmake --build .

可以看到生成了可执行二进制文件。

同目录多个源文件

实际项目中在一个目录中会有很多个源文件,现在开始编写一个目录中,多个源文件情况:

├── CMakelists.txt
├── MyMath.cpp
├── MyMath.h
└── main.cpp

MyMath.h文件内容如下:

#pragma once
int my_add(int a, int b);

MyMath.cpp文件内容如下:

#include "MyMath.h"
int my_add(int a, int b)
{
    return a + b;
}

main.cpp文件内容如下:

#include <iostream>
#include "MyMath.h"
using namespace std;
int main(int argc, char **argv)
{
    cout << my_add(1, 2) << endl;
    return 0;
}

CMakelists.txt文件内容如下:

# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.19)
# 项目名称
project(demo2)
# 指定生成目标,将main.cpp,MyMath.cpp生成一个名为demo2的可以执行文件
add_executable(demo2 main.cpp MyMath.cpp)

和单个文件类似,仅仅只在add_executable中添加了一个MyMath.cpp源文件,虽然这样写没有问题,但是当源文件很多时,把所有的源文件加入是很繁琐的工作。

我们可以使用aux_source_directory命令,该命令会查找指定目录下所有的源文件,并将结果存在指定的变量名中,如下:

aux_source_directory(<dir> <variable>)

因此,修改CMakeList为如下:

# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.19)
# 项目名称
project(demo2)
# 将当前目录所有源文件保存在变量DIR_SRCS中
aux_source_directory(. DIR_SRCS)
# 指定生成目标,将DIR_SRCS变量的所有源文件生成一个名为demo2的可以执行文件
add_executable(demo2 ${DIR_SRCS})

多目录&多源文件

现在我们的项目中不仅有多个源文件,还有一些其他的库目录,比如我们要使用一个自己的math目录,其文件结构如下:

├── CMakelists.txt
├── MyPrint.cpp
├── MyPrint.h
├── main.cpp
└── math
    ├── CMakelists.txt
    ├── MyMath.cpp
    └── MyMath.h
  • 子目录math下文件内容

MyPrint.h的文件内容:

#pragma once
int my_add(int a, int b);

MyPrint.cpp的文件内容:

#include "MyMath.h"
int my_add(int a, int b)
{
    return a + b;
}

CMakelists.txt的文件内容:

# 将当前目录所有源文件保存在变量DIR_LIB_SRCS中
aux_source_directory(. DIR_LIB_SRCS)
# 将DIR_LIB_SRCS变量中的所有源文件编译成静态链接库,链接库名为MyMath
add_library (MyMath ${DIR_LIB_SRCS})
  • 主目录下文件内容

MyPrint.h的文件内容:

#pragma once
void my_print(int a);

MyPrint.cpp的文件内容:

#include "MyPrint.h"
#include <stdio.h>
void my_print(int a)
{
    printf("%d", a);
}

main.cpp的文件内容:

#include "math/MyMath.h"
#include "MyPrint.h"
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    my_print(my_add(1, 2));
    return 0;
}

CMakelists.txt的文件内容:

# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.19)
# 项目名称
project(demo3)
# 将当前目录所有源文件保存在变量DIR_SRCS中
aux_source_directory(. DIR_SRCS)
# 添加子目录
add_subdirectory(math)
# 指定生成目标,将DIR_SRCS变量的所有源文件生成一个名为demo2的可以执行文件
add_executable(demo3 ${DIR_SRCS})
# 添加链接库,MyMath是子目录中的链接库名
target_link_libraries(demo3 MyMath)

add_subdirectory指明本项目包含一个子目录math,这样math下的CMakelists.txt文件和源代码也会被处理。

target_link_libraries指明可执行文件 demo3需要链接一个名为MyMath的链接库。

add_library将某个目录中的源文件编译为静态链接库。

自定义编译选项

CMake可以为项目增加编译选项,从而可以根据用户的环境和需求选择最合适的编译方案。

例如,可以将MyMath库设计为一个可选库,如果该选项为ON,就是用该库中定义的数学函数来进行宏运算。否则就调用标准库中的数学函数库。

现在用abs函数来举例,在MyMath库中重新定义一个my_abs函数,当前文件目录如下:

├── CMakelists.txt
├── config.h.in
├── main.cpp
└── math
    ├── CMakelists.txt
    ├── MyMath.cpp
    └── MyMath.h
  • 子目录math下文件内容

MyMath.h的文件内容:

#pragma once
int my_abs(int a);

MyMath.cpp的文件内容:

#include "MyMath.h"
int my_abs(int a)
{
    return a >= 0 ? a : -a;
}

CMakelists.txt的文件内容:

# 将当前目录所有源文件保存在变量DIR_LIB_SRCS中
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库名为MyMath
add_library (MyMath ${DIR_LIB_SRCS})
  • 主目录下文件内容

config.h.in的文件内容:

#cmakedefine USE_MYMATH

main.cpp的文件内容:

#include "math/MyMath.h"
#include "config.h"
#include <stdio.h>

#ifdef USE_MYMATH
#include "math/MyMath.h"
#else
#include "math.h"
#endif

int main(int argc, char **argv)
{
#ifdef USE_MYMATH
    printf("my abs: %d", my_abs(-1));
#else
    printf("std abs: %d", abs(-1));
#endif
    return 0;
}

CMakelists.txt的文件内容:

# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.19)
# 项目名称
project(demo4)

# 加入一个配置头文件,用于处理CMake对源码的设置
configure_file(
    "${PROJECT_SOURCE_DIR}/config.h.in"
    "${PROJECT_BINARY_DIR}/config.h"
)
# 加入一个配置头文件,用于处理CMake对源码的设置
configure_file(
    "${PROJECT_SOURCE_DIR}/config.h.in"
    "${PROJECT_BINARY_DIR}/config.h"
)
# 是否使用自己的MyMath库
option(USE_MYMATH "Use MyMath" ON)
# 是否加入MyMath库
if(USE_MYMATH)
    include_directories ("${PROJECT_SOURCE_DIR}/math")
    add_subdirectory (math)  
    list(APPEND EXTRA_LIBS MyMath)
    list(APPEND EXTRA_INCLUDE "${PROJECT_SOURCE_DIR}/math")
endif(USE_MYMATH)

# 将当前目录所有源文件保存在变量DIR_SRCS中
aux_source_directory(. DIR_SRCS)
# 指定生成目标,将DIR_SRCS变量的所有源文件生成一个名为demo2的可以执行文件
add_executable(demo4 ${DIR_SRCS})

# 添加链接库,MyMath是子目录中的库的名字
target_link_libraries(demo4 PUBLIC ${EXTRA_LIBS})
# 添加二进制树到头文件搜索路径,才能发现config.h
target_include_directories(demo4 PUBLIC "${PROJECT_BINARY_DIR}" ${EXTRA_INCLUDE})

其中configure_file命令将config.h.in生成config.h文件,通过这种机制,可以通过预定义一些参数和变量来控制代码的生成。

option命令添加了一个USE_MYMATH选项,并且设置为ON

根据 USE_MYMATH 变量的值来决定是否使用我们自己编写的MyMath库。

main.cpp中,主函数根据USE_MYMATH的预定义值决定使用标准库还是MyMath库。

主函数中引入头文件#include "config.h",我们并不直接编写这个文件,而是从CMakeList.txt中配置的config.h.in文件来生成它,我们只需要编写config.h.in文件,其内容如上面代码所示,如果option的USE_MYMATH为ON,生成的config.h中定义的内容是#define USE_MYMATH,如果为OFF,生成的config.h中定义的内容是/* #undef USE_MYMATH */

还可以交互式的选择该变量的值,使用ccmake命令,也可以使用 cmake -i 命令,该命令会提供一个会话式的交互式配置界面,从中可以找到定义的 USE_MYMATH 选项,按键盘的方向键可以在不同的选项窗口间跳转,按下 enter 键可以修改该选项。修改完成后可以按下 c 选项完成配置,之后再按 g 键确认生成 Makefile 。ccmake 的其他操作可以参考其窗口下方给出的指令提示。

定制安装规则&测试

CMake可以指定安装规则,以及添加测试。这两个功能分别可以通过在产生Makefile后使用make install来执行。在以前的GNU Makefile中,你可能需要为此编写installtest两个伪目标和相应的规则,但是在CMake里,这样的工作同样只需要几条命令。

为工程定制安装规则

还是使用上面demo4例子,首先在math/CMakelists.txt文件末尾添加下面几行:

# 指定MyMath库的安装路径
install(TARGETS MyMath DESTINATION bin)
install(FILES MyMath.h DESTINATION include)

用来指明MyMath库的安装路径。然后再修改根目录的CMakelists.txt文件,在末尾添加下面几行:

# 指定安装路径
install(TARGETS demo4 DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)

通过上卖弄的定制,生成的Demo文件和MyMath函数库libMyMath.a文件会被复制到/usr/local/bin 中,而MyMath.h和生成的config.h文件则会被复制到/usr/local/include中。我们可以验证一下(注意:这里的/usr/local/是默认安装到的根目录,可以通过修改CMAKE_INSTALL_PREFIX变量的值来指定这些文件应该拷贝到哪个根目录)

[crazyang@zt demo4]$ sudo make install
[ 50%] Built target MyMath
[100%] Built target demo4
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/libMyMath.a
-- Installing: /usr/local/include/MyMath.h
-- Installing: /usr/local/bin/demo4
-- Installing: /usr/local/include/config.h
[crazyang@zt demo4]$ ls /usr/local/bin/
demo4  libMyMath.a
[crazyang@zt demo4]$ ls /usr/local/include/
MyMath.h  config.h

为工程添加测试

添加测试也比较简单。CMake提供了一个称为CTest的测试工具。我们要做的只是在项目根目录的CMakelists文件中调用一系列的add_test命令。

还是使用demo4举例子,但是为了方便演示,将demo4的主函数修改一下,使用传入的参数:

#include "math/MyMath.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>

#ifdef USE_MYMATH
#include "math/MyMath.h"
#else
#include "math.h"
#endif

int main(int argc, char **argv)
{
    if (argc < 2)
    {
        printf(Usage:);
        return 1;
    }
#ifdef USE_MYMATH
    printf("my abs: %d", my_abs(atoi(argv[1])));
#else
    printf("std abs: %d", abs(atoi(argv[1])));
#endif
    return 0;
}

在根目录的CMakelists.txt文件,在末尾添加下面几行:

# 启用测试
enable_testing()

# 测试程序是否成功运行
add_test(test_run demo4 -1)
# 测试帮助信息是否可以正常提示
add_test (test_usage demo4)
set_tests_properties (test_usage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*")

# 测试-2的绝对值
add_test(test_-2 demo4 -2)
set_tests_properties (test_-2 PROPERTIES PASS_REGULAR_EXPRESSION "2")
# 测试5的绝对值
add_test(test_5 demo4 5)
set_tests_properties (test_5 PROPERTIES PASS_REGULAR_EXPRESSION "5")

上面的CMake包含了3个测试,test_run用来测试程序是否成功并返回0值,括号中分别是测试名,二进制运行文件名,主函数传入的参数。剩下的两个测试分别用来测试-2的绝对值、5的绝对值是否能得到正确的结果。其中PASS_REGULAR_EXPRESSION用来测试输出是否包含后面跟着的字符串。

测试的结果如下:

[crazyang@zt-2013412:/mnt/d/CODE/demo4]$ make test
Running tests...
Test project /mnt/d/CODE/demo4
    Start 1: test_run
1/4 Test #1: test_run .........................   Passed    0.04 sec
    Start 2: test_usage
2/4 Test #2: test_usage .......................   Passed    0.05 sec
    Start 3: test_1
3/4 Test #3: test_1 ...........................   Passed    0.04 sec
    Start 4: test_2
4/4 Test #4: test_2 ...........................   Passed    0.04 sec

100% tests passed, 0 tests failed out of 4

Total Test time (real) =   0.17 sec

如果测试太多数据,按上面那么写会非常繁琐。这是可以通过编写宏来实现:

# 定义一个宏,用来简化测试工作
macro(do_test arg1 result)
    add_test(test_${arg1} demo4 ${arg1})
    set_tests_properties(test_${arg1} PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro(do_test arg1 result)

# 使用该宏进行一系列的数据测试
do_test(-1 "1")
do_test(-5 "5")
do_test(10 "10")

关于CTest的更详细文档可以用过命令man 1 ctest 参考CTest的文档。

支持gdb调试

使CMake支持gdb设置也很容易,只需要指定Debug模式下开启-g选项:

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

之后可以直接对生成的程序使用 gdb 来调试。

添加环境检查

有时候我们需要对系统环境做检查,例如要使用一个平台相关的特性的时候。在还是继续使用demo4,我们需要检查系统是否自带abs函数。如果系统带有abs函数,就使用它,否则使用我们自定义的my_abs函数。

添加CheckFunctionExists宏

首先在项目目录下的CMakelists.txt文件中添加CheckFunctionExists.cmake宏,并调用check_function_exists命令测试连接器能否在链接阶段找到abs函数。

# 检查系统是否支持abs函数
include(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists(abs HAVE_ABS)

注意:这段代码必须放在configure_file命令前面,并且删除上面的demo4的CMakelists.txt中的option(USE_MYMATH "Use MyMath" ON),并将条件判断变量修改成HAVE_ABS,如下所示:

# 检查系统是否支持abs函数
include(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists(abs HAVE_ABS)

# 加入一个配置头文件,用于处理CMake对源码的设置
configure_file(
    "${PROJECT_SOURCE_DIR}/config.h.in"
    "${PROJECT_BINARY_DIR}/config.h"
)
# 是否加入MyMath库
if(HAVE_ABS)
    include_directories ("${PROJECT_SOURCE_DIR}/math")
    add_subdirectory (math)  
    list(APPEND EXTRA_LIBS MyMath)
    list(APPEND EXTRA_INCLUDE "${PROJECT_SOURCE_DIR}/math")
endif(HAVE_ABS)

预定于相关宏变量

现在修改config.h.in文件,预定义相关的宏变量。

#cmakedefine HAVE_ABS

在代码中使用宏和函数

最后一步是修改main.cpp,在代码中使用宏和函数,主要代码如下:

#ifdef HAVE_ABS
#include "math.h"
#else
#include "math/MyMath.h"
#endif

int main(int argc, char **argv)
{
    if (argc < 2)
    {
        printf("Usage:%s", argv[0]);
        return 1;
    }

#ifdef HAVE_ABS
    printf("Use StdLib. \n");
    printf("std abs: %d", abs(atoi(argv[1])));
#else
    printf("Use MyLib. \n");
    printf("my abs: %d", my_abs(atoi(argv[1])));
#endif
    return 0;
}

添加版本号

给项目添加和维护版本号是一个好的习惯,这样有利于了解每个版本的维护情况,并及时了解当前所用的版本号是否过时,或是否可能出现不兼容的情况。

首先修改顶层CMakelists文件,在project命令之后加入下面两行:

# 项目版本号
set(DEMO4_VERSION_MAJOR 1) # 指定主版本号
set(DEMO4_VERSION_MINOR 0) # 指定副版本号

用于分别指定当前项目中的主版本号和副版本号。

之后,我们可以在代码中获得版本号的信息,先修改config.h.in文件,添加两个预定义变量:

#define DEMO4_VERSION_MAJOR @DEMO4_VERSION_MAJOR@
#define DEMO4_VERSION_MINOR @DEMO4_VERSION_MINOR@

这样就可以直接在代码中打印版本信息了:

#include "math/MyMath.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>

#ifdef HAVE_ABS
#include "math.h"
#else
#include "math/MyMath.h"
#endif

int main(int argc, char **argv)
{
    if (argc < 2)
    {
        printf("%s Version %d.%d\n", argv[0], DEMO4_VERSION_MAJOR, DEMO4_VERSION_MINOR);
        printf("Usage:%s", argv[0]);
        return 1;
    }

#ifdef HAVE_ABS
    printf("Use StdLib. \n");
    printf("std abs: %d", abs(atoi(argv[1])));
#else
    printf("Use MyLib. \n");
    printf("my abs: %d", my_abs(atoi(argv[1])));
#endif
    return 0;
}

运行的结果:

[crazyang@zt-2013412:/mnt/d/CODE/demo4]$ ./demo4 
./demo4 Version 1.0

生成安装包

我们可以配置生成各种平台上的安装包,包括二进制安装包和源码安装包。为了完成这个任务,我们需要用到CPack,它同样也是由CMake提供的一个工具,专门用于打包。

首先顶层的CMakelists.txt文件末尾添加下面几行:

# 构建一个 CPack 安装包
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE
  "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${DEMO4_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${DEMO4_VERSION_MINOR}")
include (CPack)

这几行代码的工作如下:

  1. 导入InstallRequiredSystemLibraries模块,以便之后导入CPack模块
  2. 设置些CPack相关变量,包括版权信息和版本信息,其中版本信息用了上一节定义的版本号
  3. 导入CPack模块

然后我们在顶层创建一个License.txt文件,主要是一些版权信息相关的,因为没有此文件会有如下报错。

CMake Error at /usr/local/share/cmake-3.19/Modules/CPack.cmake:580 (message):CPack license resource file:"/mnt/d/CODE/demo4/License.txt" could notbe found.

接下来仍然使用cmake .构建工程,然后执行cpack相关命令:

  • 生成二进制安装包:

    cpack -C CPackConfig.cmake
    
  • 生成源码安装包:

    cpack -C CPackSourceConfig.cmake
    

在项目生成后,我们执行cpack -C CPackConfig.cmake命令:

[crazyang@zt-2013412:/mnt/d/CODE/demo4]$ cpack -C CPackConfig.cmake
CPack: Create package using STGZ
CPack: Install projects
CPack: - Run preinstall target for: demo4
CPack: - Install project: demo4 [CPackConfig.cmake]
CPack: Create package
CPack: - package: /mnt/d/CODE/demo4/demo4-1.0.1-Linux.sh generated.
CPack: Create package using TGZ
CPack: Install projects
CPack: - Run preinstall target for: demo4
CPack: - Install project: demo4 [CPackConfig.cmake]
CPack: Create package
CPack: - package: /mnt/d/CODE/demo4/demo4-1.0.1-Linux.tar.gz generated.
CPack: Create package using TZ
CPack: Install projects
CPack: - Run preinstall target for: demo4
CPack: - Install project: demo4 [CPackConfig.cmake]
CPack: Create package
CPack: - package: /mnt/d/CODE/demo4/demo4-1.0.1-Linux.tar.Z generated.

此时在该项目下创建3个不同格式的二进制文件:

[crazyang@zt-2013412:/mnt/d/CODE/demo4]$ ls demo4-*
demo4-1.0.1-Linux.sh  demo4-1.0.1-Linux.tar.Z  demo4-1.0.1-Linux.tar.gz

这 3 个二进制包文件所包含的内容是完全相同的,我们可以执行其中一个,此时会出现一个由 CPack 自动生成的交互式安装界面:

[crazyang@zt-2013412:/mnt/d/CODE/demo4]$ sh demo4-1.0.1-Linux.sh 
demo4 Installer Version: 1.0.1, Copyright (c) Humanity
This is a self-extracting archive.
The archive will be extracted to: /mnt/d/WPS云文档/WindSun的云文档/CODE/demo4

If you want to stop extracting, please press <ctrl-C>.
This is a cmake test file. #这是License.txt文件中的内容


Do you accept the license? [yn]: 
Y
By default the demo4 will be installed in:
  "/mnt/d/CODE/demo4/demo4-1.0.1-Linux"
Do you want to include the subdirectory demo4-1.0.1-Linux?
Saying no will install in: "/mnt/d/CODE/demo4" [Yn]: 
Y

Using target directory: /mnt/d/CODE/demo4/demo4-1.0.1-Linux
Extracting, please wait...

Unpacking finished successfully

安装后提示安装到了demo4-1.0.1-Linux子目录中,我们可以去执行该程序:

[crazyang@zt-2013412:/mnt/d/CODE/demo4]$ ./demo4-1.0.1-Linux/bin/demo4 -1
Use StdLib. 
std abs: 1

关于 CPack 的更详细的用法可以通过 man 1 cpack 参考 CPack 的文档。

将其他平台的项目迁移到CMake

CMake 可以很轻松地构建出在适合各个平台执行的工程环境。而如果当前的工程环境不是 CMake ,而是基于某个特定的平台,是否可以迁移到 CMake 呢?答案是可能的。下面针对几个常用的平台,列出了它们对应的迁移方案。

autotools

qmake

Visual Studio

  • vcproj2cmake.rb 可以根据 Visual Studio 的工程文件(后缀名是 .vcproj 或 .vcxproj)生成 CMakeLists.txt 文件。
  • vcproj2cmake.ps1 vcproj2cmake 的 PowerShell 版本。
  • folders4cmake 根据 Visual Studio 项目文件生成相应的 “source_group” 信息,这些信息可以很方便的在 CMake 脚本中使用。支持 Visual Studio 9/10 工程文件。

CMakeLists.txt 自动推导

  • gencmake 根据现有文件推导 CMakeLists.txt 文件。
  • CMakeListGenerator 应用一套文件和目录分析创建出完整的 CMakeLists.txt 文件。仅支持 Win32 平台。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值