cmake:configure_file的作用

1060 篇文章 300 订阅

引言

此文为:轻松入门cmake系列教程

指令

语法

configure_file(<input> <output>
               [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
                FILE_PERMISSIONS <permissions>...]
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])

作用

官方解释:

  • 将文件复制到另一个位置并修改其内容。
  • 当然,这里的修改其内容也不是任意地修改,也是遵循一定的规则:将input文件复制到output文件,并将输入文件内容中的变量,替换引用为@VAR@或${VAR}的变量值。每个变量引用将替换为该变量的当前值,如果未定义该变量,则为空字符串。

可能有些绕头,再浅显一点:configure_file,复制一份输入文件到输出文件,替换输入文件中被@VAR@或者${VAR}引用的变量值。也就是说,让普通文件,也能使用CMake中的变量。例如:

  • 比如在CMakeLists.txt中定义了如下的变量:
set(BUILD_Version 1)
  • 输入文件中为:
#define BUILD_Version @BUILD_Version@
  • 那么,在输出文件中就会被转化为:
#define BUILD_Version 1

参数

  • < input>
    • 输入文件的路径。
    • 相对路径是根据CMAKE_CURRENT_SOURCE_DIR的值处理的。
    • 输入路径必须是文件,而不是目录。
  • < output >
    • 输出文件或目录的路径。
    • 相对路径是根据CMAKE_CURRENT_BINARY_DIR的值来处理的。
    • 如果路径命名为一个现有的目录,输出文件将以与输入文件相同的文件名放置在该目录中。

通常情况下,输入文件以.h.in为后缀,输出文件以.h为后缀

  • NO_SOURCE_PERMISSIONS:
    • 3.19新版功能。
    • 不要将输入文件的权限转移到输出文件。复制的文件权限默认为标准644值(-rw-r–r--).
  • USE_SOURCE_PERMISSIONS
    • 3.20新版功能。
    • 将输入文件的权限转移到输出文件。如果没有给出三个与权限相关的关键字(NO_SOURCE_PERMISSIONS、USE_SOURCE_PERMISSIONS或FILE_PERMISSIONS),则这已经是默认行为。USE_SOURCE_PERMISSIONS关键字主要用于使调用站点的预期行为更加清晰。
  • FILE_PERMISSIONS < permissions>…
    • 3.20新版功能。
    • 忽略输入文件的权限,并为输出文件使用指定的< permissions >。

常用

  • COPYONLY

    • 仅拷贝 < input> 文件里面的内容到 < output> 文件, 不进行变量的替换
  • ESCAPE_QUOTES

    • 用反斜杠转义任何替换的引号(c风格)。
  • @ONLY

    • 限制替换, 仅仅替换 @VAR@ 变量, 不替换 ${VAR} 变量
  • NEWLINE_STYLE style

    • 指定输入文件的新行格式, 例如:Unix 中使用的是 \n, windows 中使用的 \r\n

注意 : COPYONLY 和 NEWLINE_STYLE 是冲突的,不能同时使用;

示例

示例一

当前cmake版本: cmake version 3.17.3

结构

.
├── CMakeLists.txt
├── tutorialConfig.h.in
└── tutorial.cpp


内容

  1. CMakeLists.txt
# 这里是最基本的
cmake_minimum_required (VERSION 2.6)
project (Tutorial)

# 设置版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# configure_file 可以复制一个文件到另一个地方,并对内容进行修改
# 这里把PROJECT_SOURCE_DIR中的TutorialConfig.h.in复制到PROJECT_BINARY_DIR
# 并变成TutorialConfig.h
configure_file (
        "${PROJECT_SOURCE_DIR}/tutorialConfig.h.in"
        "${PROJECT_BINARY_DIR}/tutorialConfig.h"
)

# 将项目二进制构建路径添加到头文件的搜索路径中
# 然后我们可以在二进制构建路径找到TutorialConfig.h
# 这个二进制构建路径也就是存放一些make过程中产生的文件以及可执行文件的路径
# 我在build文件夹中cmake ../ build文件夹的路径就是PROJECT_BINARY_DIR
# PROJECT_SOURCE_DIR就是 build的上一级路径
include_directories("${PROJECT_BINARY_DIR}")

# 添加可执行文件(可执行文件名 [配置] 源文件)
add_executable(Tutorial tutorial.cpp)
  1. tutorialConfig.h.in
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
// #define Tutorial_VERSION_MINOR ${Tutorial_VERSION_MINOR}
  1. tutorial.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "tutorialConfig.h"

int main (int argc, char *argv[])
{
    if (argc < 2)
    {
        fprintf(stdout,"%s Version %d.%d\n",
                argv[0],
                Tutorial_VERSION_MAJOR,
                Tutorial_VERSION_MINOR);
        fprintf(stdout,"Usage: %s number\n",argv[0]);
        return 1;
    }
    double inputValue = atof(argv[1]);
    double outputValue = sqrt(inputValue);
    fprintf(stdout,"The square root of %g is %g\n",inputValue, outputValue);
    return 0;
}

运行

$ mkdir build
$ cd build
$ cmake ..
$ make
$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  Tutorial  tutorialConfig.h

从上面ls可以看出,自动生成了tutorialConfig.h头文件,我们来看看内容

//
// Created by oceanstar on 2021/6/29.
//

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR 1
#define Tutorial_VERSION_MINOR 0

在这里插入图片描述

在这里插入图片描述

示例二

考虑一个包含foo.h.in文件的源代码树:

#cmakedefine FOO_ENABLE
#cmakedefine FOO_STRING "@FOO_STRING@"

相邻的CMakeLists.txt可以使用configure_file来配置头文件:

option(FOO_ENABLE "Enable Foo" ON)
if(FOO_ENABLE)
  set(FOO_STRING "foo")
endif()
configure_file(foo.h.in foo.h @ONLY)

这将在与此源目录对应的构建目录中创建一个foo.h。如果FOO_ENABLE选项是打开的,配置文件将包含:

#define FOO_ENABLE
#define FOO_STRING "foo"

否则将为:

/* #undef FOO_ENABLE */
/* #undef FOO_STRING */

然后可以使用include_directories()命令将输出目录指定为包含目录:

include_directories(${CMAKE_CURRENT_BINARY_DIR})

因此,源代码可以包含头文件,如#include < foo.h >。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值