Preprocessor tomfoolery (restringindo um #include)

Nota: Esta questão não tem nada a ver com o OpenCL em si ... verifique o último parágrafo para obter uma declaração sucinta da minha pergunta. Mas, para fornecer alguns antecedentes:

Estou escrevendo algum código C ++ que utiliza o OpenCL. Eu gosto de manter a fonte dos meus kernels OpenCL em seus próprios arquivos, para facilitar a codificação e a manutenção (em vez de incorporar as fontes diretamente como constantes de string no código C ++ associado). Isso inevitavelmente leva à questão de como carregá-los no tempo de execução do OpenCL quando chegar a hora de distribuir os binários --- idealmente, a fonte do OpenCL é incluída no binário, para que o binário não precise estar em um local específico em alguma estrutura de diretório para saber onde está o código-fonte do OpenC

Gostaria de incluir os arquivos OpenCL como constantes de string em algum lugar e, de preferência, sem o uso de etapas adicionais de compilação ou ferramentas externas (para facilidade de uso entre compiladores / plataformas) ... ou seja, não paraxxd e similar). Eu pensei que tinha tropeçado em uma técnica baseada na segunda resposta emist thread, assim:

#define STRINGIFY(src) #src

inline const char* Kernels() {
  static const char* kernels = STRINGIFY(
    #include "kernels/util.cl"
    #include "kernels/basic.cl"
  );
  return kernels;
}

Observe que eu preferiria não incorporar oSTRINGIFY macro no meu código OpenCL, se possível (como foi feito na pergunta SO mencionada acima). Agora, isso funciona maravilhosamente no compilador Clang / LLVM, mas o GCC sofre uma morte horrível ("Lista de argumentos não terminada invocando a macro STRINGIFY" e vários "erros" de sintaxe relacionados ao conteúdo dos arquivos .cl são exibidos). Então, claramente, essa técnica exata não é utilizável em compiladores (ainda não tentei o MSVC, mas também gostaria que funcionasse lá) ... Como eu poderia massageá-lo minimamente para que ele funcionasse em compiladores?

Em resumo, eu gostaria de uma técnica compatível com os padrões para incluir o conteúdo de um arquivo como uma constante de string C / C ++ sem chamar ferramentas externas ou poluir os arquivos com código estranho. Ideias?

EDITA: Como apontou Potatoswatter, o comportamento acima é indefinido; portanto, uma técnica de pré-processador verdadeiramente compilador cruzado que não envolve o toque nos arquivos a serem especificados, provavelmente não é possível (a primeira pessoa a descobrir um hediondo hackear issofa work para a maioria / todos os compiladores obtém os pontos de resposta). Para os curiosos, acabei fazendo o que foi sugerido na segunda respostaAqu ... isto é, adicionei oSTRINGIFY macro diretamente para os arquivos OpenCL que eu estava incluindo:

Emsomefile.cl:

STRINGIFY(
  ... // Lots of OpenCL code
)

Emsomefile.cpp:

#define STRINGIFY(src) #src

inline const char* Kernels() {
  static const char* kernels =
    #include "somefile.cl"
    ;
  return kernels;
}

Isso funciona nos compiladores em que eu experimentei (Clang e GCC também, já que não possui diretivas de pré-processador dentro da macro) e não é um fardo muito grande, pelo menos no meu contexto (ou seja, não interfere com a sintaxe destacando / editando os arquivos OpenCL). Um recurso das abordagens de pré-processador como este é que, como as seqüências adjacentes são concatenadas, você pode escrever

inline const char* Kernels() {
  static const char* kernels =
    #include "utility_functions.cl"
    #include "somefile.cl"
    ;
  return kernels;
}

e contanto que a macro STRINGIFY esteja em ambos.cl, as strings são concatenadas, permitindo modularizar seu código OpenC

questionAnswers(4)

yourAnswerToTheQuestion