как включить текстовый файл в виде строки во время компиляции без добавления префикса и суффикса строкового литерала c ++ 11 в текстовый файл - PullRequest
0 голосов
/ 21 сентября 2018

Мне известно о многих похожих вопросах на этом сайте.Мне очень нравится упоминание решения в следующей ссылке:

https://stackoverflow.com/a/25021520/884553

с некоторыми изменениями, вы можете включить текстовый файл во время компиляции, например:

constexpr const char* s = 
#include "file.txt"

НО, чтобы это работало, вы должны добавить префикс и суффикс строкового литерала в ваш исходный файл, например:

R"(
This is the original content,
and I don't want this file to be modified. but i
 don't know how to do it.
)";

Мой вопрос: есть ли способ заставить эту работу работать, но не изменять file.txt?

(Я знаю, что могу использовать инструменты командной строки для создания копии, добавления и добавления к копии, удаления копии после компиляции. Я ищу более элегантное решение, чем это. Надеюсь, другие не нужныинструменты)

Вот что я пробовал (но не работает):

#include <iostream>

int main() {
  constexpr const char* s =
#include "bra.txt"  // R"(
#include "file.txt" //original file without R"( and )";
#include "ket.txt"  // )";
  std::cout << s << "\n";
  return 0;
}

/opt/gcc8/bin/g++ -std=c++1z a.cpp
In file included from a.cpp:5:
bra.txt:1:1: error: unterminated raw string
 R"(
 ^
a.cpp: In function ‘int main()’:
a.cpp:4:27: error: expected primary-expression at end of input
   constexpr const char* s =
                           ^
a.cpp:4:27: error: expected ‘}’ at end of input
a.cpp:3:12: note: to match this ‘{’
 int main() {
            ^

1 Ответ

0 голосов
/ 21 сентября 2018

Нет, это невозможно сделать.

Существует предложение , разрешающее включение таких ресурсов во время компиляции, которое называется std :: embed .

Мотивирующая часть предложения p1040r1:

Мотивация

Каждый программист на C и C ++ - в какой-то момент - пытается #include больших кусковне-C ++ данных в их код.Конечно, #include ожидает, что формат данных будет исходным кодом, и, следовательно, программа завершается с ошибками лексера.Таким образом, многие различные инструменты и методы были адаптированы для этого, еще в 1995 году с помощью инструмента xxd.Многие отрасли нуждаются в такой функциональности, включая (но вряд ли ограниченные):

  • Финансовое развитие

    • , представляющее коэффициенты и числовые константы для алгоритмов, критичных к производительности;
  • Разработка игр

    • активы, которые не изменяются во время выполнения, такие как значки, фиксированные текстуры и другие данные

    • Код шейдера и сценариев;

  • Embedded Development

    • хранение больших кусков двоичного файла, напримерв качестве прошивки, в хорошо сжатом формате

    • размещение данных в памяти на чипах и системах, не имеющих операционной системы или файловой системы;

  • Разработка приложений

    • сжатые двоичные двоичные объекты, представляющие данные

    • код сценария не-C ++, который не изменяется во время выполнения;и

  • Разработка сервера

    • параметры конфигурации, которые известны во время сборки и запекаются для установки пределов и обеспечения компиляции.информация о времени для настройки производительности при определенных нагрузках

Сертификаты SSL / TLS жестко запрограммированы в вашем исполняемом файле (требуется перестройка и потенциальная авторизация перед развертыванием новых сертификатов).

В достижении этой цели эти инструменты доказали свою несостоятельность и вносят незначительный вклад в цикл разработки C ++, так как он продолжает расширяться для более крупных и качественных бюджетных устройств и высокопроизводительных машин, из-за чего разработчики теряют надежду.задач и попыток скрыть неутешительные различия между платформами.

MongoDB был достаточно любезен, чтобы поделиться некоторыми их кодами ниже.У других компаний был приведен пример кода, анонимный или просто не включенный из позора за то, что им нужно сделать для поддержки своих рабочих процессов.Автор благодарит MongoDB за их смелость и поддержку std::embed.

Запрос на какую-либо форму #include_string или аналогичную давно встречается, с одним из самых старых заданных вопросов о переполнении стека.-ответили об этом примерно 10 лет назад.Предшественник даже этого - множество сообщений в списках рассылки и сообщениях на форуме, спрашивающих, как получить код сценария и другие вещи, которые вряд ли могут быть преобразованы в двоичный файл.

В этой статье предлагается <embed>, чтобы сделать этот процесс намного болееэффективный, портативный и оптимизированный.Вот пример идеала:

#include <embed>

int main (int, char*[]) {
  constexpr std::span<const std::byte> fxaa_binary = std::embed( "fxaa.spirv" );

  // assert this is a SPIRV file, compile-time  
  static_assert( fxaa_binary[0] == 0x03 && fxaa_binary[1] == 0x02
    && fxaa_binary[2] == 0x23 && fxaa_binary[3] == 0x07
    , "given wrong SPIRV data, check rebuild or check the binaries!" )

  auto context = make_vulkan_context();

  // data kept around and made available for binary
  // to use at runtime
  auto fxaa_shader = make_shader( context, fxaa_binary );

  for (;;) {
    // ...
    // and we’re off!
    // ...
  }

  return 0;
}
...