是否可以在编译时读取文件

Is it possible to read a file at compile time?

本文关键字:读取 文件 编译 是否      更新时间:2023-10-16

我想知道在C++11/14中是否有可能在编译时实际读取文件。例如,以下代码只有在能够成功读取文件的情况下才会编译。

constexpr std::string shader_source = load("~/foo.glsl");

你认为这可能吗?

我知道在构建应用程序时,我可以使用一些自定义工具来实现这一点

基于teivaz的想法,我想知道通常的"扩展后字符串化"技巧是否有效:

#define STRINGIZE(...) #__VA_ARGS__
#define EXPAND_AND_STRINGIZE(...) STRINGIZE(__VA_ARGS__)
constexpr std::string shader_source = EXPAND_AND_STRINGIZE(
#include "~/.foo.glsl"
);


尽管如此,我还是会选择由链接器解析为内容的传统extern const char[]声明。文章"在可执行文件中嵌入文件,又名Hello World,5967版"有一个例子:

# objcopy --input binary 
          --output elf32-i386 
          --binary-architecture i386 data.txt data.o

当然,您应该更改--output--binary-architecture命令以匹配您的平台。对象文件的文件名以符号名结尾,因此您可以这样使用它:

#include <stdio.h>
/* here "data" comes from the filename data.o */
extern "C" char _binary_data_txt_start;
extern "C" char _binary_data_txt_end;
main()
{
    char*  p = &_binary_data_txt_start;
    while ( p != &_binary_data_txt_end ) putchar(*p++);
}
#define STR(x) #x
const char* a =
{ 
#include "foo.glsl" 
};

并且foo.glsl应该将其内容包含在STR(。。。)

upd。这将正确处理逗号

#define STRINGIFY(...) #__VA_ARGS__
#define STR(...) STRINGIFY(__VA_ARGS__)

我做过这样的事情。看看这是否会给你想要的。

在程序中添加一个命令行选项,用于检查输入文件的存在性和有效性
如果文件不存在或无效,则该选项应退出程序并返回错误代码。

在make文件中,添加对程序的调用(使用该命令行选项),作为最后的构建步骤。

现在,当你构建程序时,如果正确的文件不可用或无效,你会得到一个错误。

这是我的C解决方案,但对于C++来说是一样的。Stringify#define不适用于现代编译器中的#include,因此您可以在编译时使用文件中的原始字符串文字将内容嵌入字符串中。

test.c:

#include <stdio.h>
const char *text = {
#include "test.dat"
};
int main() {
    printf("%sn", text);
}

test.dat:

R"(This is a line.
This is another line...)"