web-dev-qa-db-ja.com

コンパイル時にファイルを読み取ることは可能ですか?

C++ 11/14では、コンパイル時に実際にファイルを読み取ることができるかどうか疑問に思っています。たとえば、次のコードは、ファイルを正常に読み取ることができる場合にのみコンパイルされます。

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

これは可能だと思いますか?

アプリケーションを構築するときに、カスタムツールを使用してこれを実行できることを知っています。

31
Maik Klein

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++);
}
18
Ben Voigt
#define STR(x) #x

const char* a =
{ 
#include "foo.glsl" 
};

foo.glslはその内容をSTR(...)で囲む必要があります

upd。これはコンマを適切に処理します

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

私はこのようなことをしました。これがあなたが望むものを与えるかどうか見てください。

入力ファイルの存在と有効性をチェックするプログラムにコマンドラインオプションを追加します。
このオプションは、ファイルが存在しないか無効な場合、エラーコードを表示してプログラムを終了する必要があります。

Makeファイルに、最終的なビルドステップとして、プログラムへの呼び出し(そのコマンドラインオプションを使用)を追加します。

これで、プログラムをビルドするときに、適切なファイルが使用できないか無効な場合、エラーが発生します。

1
Louis Newstrom