Можно ли прочитать файл во время компиляции?
Мне интересно, возможно ли в С++ 11/14 фактически читать файлы во время компиляции. Например, следующий код будет компилироваться только в том случае, если он может успешно прочитать файл.
constexpr std::string shader_source = load("~/foo.glsl");
Считаете ли вы, что это возможно?
Я знаю, что я мог бы сделать это с помощью какого-то настраиваемого инструмента при создании моего приложения.
Ответы
Ответ 1
Основываясь на идее teivaz, я задаюсь вопросом, будет ли обычным трюк "stringize after expansion":
#define STRINGIZE(...) #__VA_ARGS__
#define EXPAND_AND_STRINGIZE(...) STRINGIZE(__VA_ARGS__)
constexpr std::string shader_source = EXPAND_AND_STRINGIZE(
#include "~/.foo.glsl"
);
Забастовкa >
Тем не менее, я бы пошел на стандартное объявление extern const char[]
, разрешенное компоновщиком. В статье "Вложение файла в исполняемый файл, aka 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++);
}
Ответ 2
Я сделал что-то вроде этого. Посмотрите, даст ли это вам то, что вы хотите.
Добавьте параметр командной строки в программу, которая проверяет наличие и достоверность входного файла.
Эта опция должна выйти из программы с кодом ошибки, если файл не существует или недействителен.
В своем файле make добавьте вызов программы (используя эту опцию командной строки) в качестве конечного этапа сборки.
Теперь, когда вы создаете программу, вы получите сообщение об ошибке, если соответствующие файлы недоступны или не действительны.
Ответ 3
#define STR(x) #x
const char* a =
{
#include "foo.glsl"
};
и foo.glsl должны заключить его содержимое в STR ( ... )
обн. Это будет правильно обрабатывать запятые
#define STRINGIFY(...) #__VA_ARGS__
#define STR(...) STRINGIFY(__VA_ARGS__)