Статическая компиляция libmagic (определение типа файла c/ C++)
Спасибо ребятам, которые помогли мне с моим предыдущим вопросом (ссылка только для справки).
Я могу разместить файлы fileTypeTest.cpp
, libmagic.a
, а также magic
в каталоге, и я могу скомпилировать с g++ -lmagic fileTypeTest.cpp fileTypeTest
, Позже я буду тестировать, чтобы увидеть, работает ли он в Windows, скомпилированной с MinGW.
Я планирую использовать libmagic в небольшом приложении с графическим интерфейсом, и я хотел бы скомпилировать его статически для распространения. Моя проблема в том что libmagic
кажется, требует внешнего файла, magic
, (На самом деле я использую свою сокращенную и скомпилированную версию magic_short.mgc, но я отвлекся.)
Хакерским решением было бы закодировать файл в приложение, создав (и удалив) внешний файл по мере необходимости. Как я могу избежать этого?
добавлено для ясности:
magic
текстовый файл, описывающий свойства разных типов файлов Когда его попросят идентифицировать файл, libmagic
ищет через magic
, Есть скомпилированная версия, magic.mgc
это работает быстрее. Моему приложению нужно только определить несколько типов файлов, прежде чем решить, что с ними делать, поэтому я буду использовать свой собственный magic_short
файл для создания magic_short.mgc
,
3 ответа
Это сложно, я полагаю, вы могли бы сделать это таким образом... кстати, я скачал источник libmagic и смотрю на него...
Там есть функция под названием magic_read_entries
в пределах minifile.c
(это чистый ванильный источник, который я скачал из sourceforge, где он читает из внешнего файла.
Вы можете добавить magic
файл (который находится в каталоге /etc) до конца кода библиотеки, например cat magic >> libmagic.a
, В моей системе magic
474443 байт, libmagic.a
38588 байт.
в magic.c
файл, вам нужно будет изменить magichandle_t* magic_init(unsigned flags)
функция, в конце функции, добавьте строку magic_read_entries
и измените саму функцию для чтения по смещению самой библиотеки, чтобы получить данные, обработать ее как указатель на указатель на char (char **) и использовать его вместо чтения из файла. Поскольку вы знаете, где находится смещение данных библиотеки для чтения, это не должно быть сложным.
Теперь функция magic_read_entries
больше не будет использоваться, так как больше не будет считываться из файла. Функция `magichandle_t* magic_init(unsigned flags)'позаботится о загрузке записей, и с вами все будет в порядке.
Если вам нужна дополнительная помощь, дайте мне знать,
Редактировать: я использовал старый 'libmagic' с sourceforge.net и вот что я сделал:
- Извлеките загруженный архив в мой домашний каталог, разархивировав / распаковав архив создаст папку с именем libmagic.
- Создайте папку в libmagic и назовите ее Test
- Скопируйте оригинальный magic.c и minifile.c в Test
- Используя вложенный вывод diff, подчеркивающий разницу, примените его к источнику magic.c.
48a49,51> #define MAGIC_DATA_OFFSET 0x971C> #define MAGIC_STAT_LIB_NAME "libmagic.a"> 125a129,130> / * magic_read_entries устарел... */ > magic_read_entries(mh, MAGIC_STAT_LIB_NAME); 251c256,262 <--->> if (! Fseek(fp, MAGIC_DATA_OFFSET, SEEK_SET)){ > if (ftell(fp)!= MAGIC_DATA_OFFSET) вернуть 0; > }else{ > return 0; > } >
- Тогда выпустите марку
- Волшебный файл (который я скопировал из /etc под Slackware Linux 12.2) объединяется с файлом libmagic.a, т.е.
cat magic >> libmagic.a
, Контрольная сумма SHA для магии (4abf536f2ada050ce945fbba796564342d6c9a61 magic), вот точные данные для магии (-rw-r -r-- 1 корневой корень 474443 2007-06-03 00:52 /etc/file/magic), найденные на моем система. - Вот diff для источника minifile.c, примените его и пересоберите исполняемый файл minifile, снова запустив make.
40c40/*magic_read_entries(mh,"magic");*/
Это должно работать тогда. Если нет, вам нужно будет скорректировать смещение в библиотеке для чтения, изменив MAGIC_DATA_OFFSET. Если хочешь, я могу вставить волшебный файл данных в pastebin. Дай мне знать.
Надеюсь, это поможет, С наилучшими пожеланиями, Том.
Я могу рассказать вам, как скомпилировать библиотеку статически - вы просто передаете путь к файлу.a в конце вашей команды g++ - файлы.a являются просто архивами скомпилированных объектов (.o). Использование "ldd fileTypeTest" покажет вам динамически связанные библиотеки - ${libdir}/libmagic.so не должно быть в нем.
Что касается связывания во внешнем файле данных... Я не знаю - Вы не можете упаковать приложение (.deb|.rpm|.tar.bz2)? На окнах я бы написал установщик с помощью NSIS.
В прошлом я создавал самораспаковывающиеся архивы. По сути, это файл.exe, состоящий из архива.zip и кода для его распаковки. скачайте.exe, запустите его и poof! Вы можете иметь столько файлов, сколько хотите.