LINUX.ORG.RU

include в строку

 


0

5

Можно ли как-то, не особо костыльно, запихнуть файл в char[] во время компиляции?

const char[] str = TOSTRINGPLEASE(
#include "file"
);
★★★

Последнее исправление: Kuzy (всего исправлений: 1)

Ответ на: комментарий от Kuzy

Лень сейчас делать пример, но делается это примерно так. Нужен файл, который будет конфигурироваться CMake (через configure_file), в нем макрос вида #define FILECONTENT «${FILE_CONTENT}»

А в CMakeLists.txt считываешь содержимое файла в переменную FILE_CONTENT (погугли как это сделать, а то я уже засыпаю). Правда как экранировать контент я не знаю. Что в файле?

flareguner
()

Можешь воспользоваться утилитой file2c (конвертит файл в c'шный массив) - к cmake прикручивается легко через ADD_CUSTOM_COMMAND. Тут стоит вопрос доступности утилиты - честно говоря не знаю она она file2c распространена в linux'ах, но во FreeBSD она в базовой системе. Кажется где-то я видел что её исходник клали в репозиторий (благо один файл на несколько десятков строк кода).

Хотел найти пример использования, и обнаружил что аналог уже написали на чистом cmake:

https://github.com/search?l=cmake&q=file2c&ref=cmdform&type=Code

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

не знаю она она file2c распространена в linux'ах

ftp://ftp.sunet.se/pub/OpenBSD/src/usr.bin/file2c/

/*	$OpenBSD: file2c.c,v 1.3 2003/06/26 21:41:37 deraadt Exp $	*/
/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 * ----------------------------------------------------------------------------
 *
 * $FreeBSD: file2c.c,v 1.1 1995/01/29 00:49:57 phk Exp $
 *
 */

#include <stdio.h>

int
main(int argc, char *argv[])
{
	int i, j, k;

	if (argc > 1)
		printf("%s\n",argv[1]);
	k = 0;
	j = 0;
	while((i = getchar()) != EOF) {
		if(k++) {
			putchar(',');
			j++;
		}
		if (j > 70) {
			putchar('\n');
			j = 0;
		}

		printf("%d", i);

		if (i > 99)
			j += 3;
		else if (i > 9)
			j += 2;
		else
			j++;
	}
	putchar('\n');
	if (argc > 2)
		printf("%s\n", argv[2]);
	return 0;
}

что тут «распространять»-то???

emulek
()

Вот скрипт на CMake:

cmake_minimum_required (VERSION 2.8 FATAL_ERROR)

if(NOT DEFINED INPUT OR NOT DEFINED OUTPUT OR NOT DEFINED MACRONAME)
    message (FATAL_ERROR "Please set -DINPUT, -DOUTPUT, -DMACRONAME")
endif()
file(READ "${INPUT}" hexdata HEX)
string(LENGTH "${hexdata}" inputlen)
math(EXPR rem "${inputlen} % (8 * 2)")
math(EXPR pos2 "${inputlen} - ${rem}")
string(SUBSTRING ${hexdata} "0" "${pos2}" hexdata_start)
string(SUBSTRING ${hexdata} "${pos2}" "${rem}" hexdata_rem)
string(REGEX REPLACE "(..)(..)(..)(..)(..)(..)(..)(..)"
    "    0x\\1, 0x\\2, 0x\\3, 0x\\4, 0x\\5, 0x\\6, 0x\\7, 0x\\8, \\\\\\n"
    hdata1 "${hexdata_start}")
string(REGEX REPLACE "(..)"
    "0x\\1, "
    hdata2 "${hexdata_rem}")
if(APPEND_NULL)
    set(hdata2 "${hdata2}0x00 ")
endif()
set(hdata2 "    ${hdata2}\\\n")
get_filename_component(fname "${INPUT}" NAME)
file(WRITE "${OUTPUT}"
    "#ifndef ${MACRONAME}\n"
    "#define ${MACRONAME} { \\\n"
    "${hdata1}${hdata2}"
    "}\n"
    "#endif /* ${MACRONAME} */\n")

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

С утра туплю, неправильно ТСа понял

anonymous
()
Ответ на: комментарий от arturpub

Переносимее в том смысле, что для сборки достаточно posix-окружения. Кроме того, вставка в код программы вместо #include магических символов типа _binary_objfile_start больше похожа на грязный хак, чем на нормальный код. Но это дело вкуса, наверное.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Переносимее в том смысле, что для сборки достаточно posix-окружения.

Не так выразился. Достаточно не только posix-окружения, но вообще любого окружения, где есть компилятор.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Метод преобразования файла в объектник ОЧЕНЬ старый.. Помню как-то так предлагалась линковать графические драйвера BGI (Borland Graphic Interface) с программой еще где-то в 1990 году. С тех пор так и живет.. Еще есть способ преобразовать файл в строку из uint8 при помощи утилиты hexdump и включать уже вывод этой утилиты. Я пользуюсь таким методом

cat [file] | hexdump -e ' 1/1 "0x%02X, "' -v

vromanov ★★★
()
Ответ на: комментарий от vromanov

Таких преобразовалок много. Vim'овский xxd, например. Но т.к. автор использует cmake, то логично выбрать преобразовалку прямо на нём, без доп.зависимостей.

Sorcerer ★★★★★
()
Ответ на: комментарий от vromanov

Плохо, конечно. Он и для 3,5Мб выжирает 65Мб памяти и работает 15 секунд. Но для файлов в пределах 100Кб работает приемлемо.

Sorcerer ★★★★★
()
Ответ на: комментарий от slovazap

Спасибо, вариант с file2c на CMake вроде самый нормальный.

Kuzy ★★★
() автор топика

Лет 20 назад написал утилиту bin2hpp и она до сих пор работает.

andreyu ★★★★★
()
17 февраля 2014 г.
Ответ на: комментарий от Sorcerer

Просто оставлю здесь. Для posix-окружения:

od -v -An -t x1 /path/to/input_file |sed 's/ \(.\{2\}\)/ \1,/g'|(printf '#ifndef TEST\n#define TEST {\\\n' && sed 's/$/\\/' && printf '}\n#endif\n'

Sorcerer ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.