Статическая компиляция libmagic (определение типа файла c / c ++) - PullRequest
3 голосов
/ 24 января 2010

Спасибо ребятам, которые помогли мне с моим предыдущим вопросом (ссылка только для справки).

Я могу поместить файлы 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 ]

5 голосов
/ 24 января 2010

Это сложно, я полагаю, вы могли бы сделать это таким образом ... кстати, я скачал исходный код 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)' позаботится о загрузке записей, и с вами все будет в порядке.

Если вам нужна дополнительная помощь, дайте мне знать,

Edit: Я использовал старый 'libmagic' с sourceforge.net и вот что я сделал:

  1. Извлеките загруженный архив в мой домашний каталог, распакуйте / распакуйте архив и создайте папку с именем libmagic .
  2. Создайте папку в libmagic и назовите ее Test
  3. Скопируйте оригинал magic.c и minifile.c в Тест
  4. Используя прилагаемый вывод diff, подчеркивающий разницу, примените его к источнику magic.c .
48a49,51
> #define MAGIC_DATA_OFFSET     0x971C
> #define MAGIC_STAT_LIB_NAME "libmagic.a"
>
125a129,130
>       /* magic_read_entries is obsolete... */
>       magic_read_entries(mh, MAGIC_STAT_LIB_NAME);
251c256,262
<
---
>
>       if (!fseek(fp, MAGIC_DATA_OFFSET, SEEK_SET)){
>               if (ftell(fp) != MAGIC_DATA_OFFSET) return 0;
>       }else{
>               return 0;
>       }
>
  • Тогда выдайте make
  • Волшебный файл (который я скопировал из / 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), найденный в моей системе.
  • Вот разница для источника minifile.c , примените его и пересоберите исполняемый файл минифила, снова запустив make .
40c40
<       magic_read_entries(mh,"magic");
---
>       /*magic_read_entries(mh,"magic");*/

Тогда должно сработать. Если нет, вам нужно будет настроить смещение в библиотеке для чтения, изменив MAGIC_DATA_OFFSET. Если хочешь, я могу вставить волшебный файл данных в pastebin. Дайте мне знать.

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

1 голос
/ 24 января 2010

Я могу рассказать вам, как статически скомпилировать библиотеку - вы просто передаете путь к файлу .a в конце вашей команды g ++ - файлы .a являются просто архивами скомпилированных объектов (.o). Использование «ldd fileTypeTest» покажет вам динамически связанные библиотеки - $ {libdir} /libmagic.so не должно быть в нем.

Что касается связывания во внешнем файле данных ... Я не знаю - не можете ли вы упаковать приложение (.deb | .rpm | .tar.bz2)? На окнах я бы написал установщик с помощью NSIS.

0 голосов
/ 24 января 2010

В прошлом я создавал самораспаковывающиеся архивы. По сути это файл .exe, состоящий из архива .zip и кода для его распаковки. скачайте .exe, запустите его и poof! Вы можете иметь столько файлов, сколько хотите.

http://en.wikipedia.org/wiki/Self-extracting_archive

...