静态编译libmagic(c/c++文件类型检测)

Posted

技术标签:

【中文标题】静态编译libmagic(c/c++文件类型检测)【英文标题】:Compiling libmagic statically (c/c++ file type detection) 【发布时间】:2011-01-08 15:30:28 【问题描述】:

感谢帮助我处理我的previous question 的人(链接仅供参考)。

我可以将文件fileTypeTest.cpplibmagic.amagic放在一个目录中,我可以用g++ -lmagic fileTypeTest.cpp fileTypeTest进行编译。稍后,我将测试它是否可以在使用 MinGW 编译的 Windows 中运行。

我计划在一个小型 GUI 应用程序中使用libmagic,我想静态编译它以进行分发。我的问题是libmagic 似乎需要外部文件magic。 (我实际上使用的是我自己的缩短和编译版本,magic_short.mgc,但我跑题了。)

一个 hacky 解决方案是将文件编码到应用程序中,根据需要创建(和删除)外部文件。我怎样才能避免这种情况?

为清楚起见添加:

magic 是一个描述不同文件类型属性的文本文件。当被要求识别文件时,libmagic 搜索 magic。有一个编译版本,magic.mgc,运行速度更快。我的应用程序只需要在决定如何处理它们之前识别少数文件类型,所以我将使用我自己的magic_short 文件来创建magic_short.mgc

【问题讨论】:

【参考方案1】:

我可以告诉你如何静态编译一个库——你只需在你的 g++ 命令末尾传递 .a 文件的路径——.a 文件只是编译对象 (.o) 的档案。使用“ldd fileTypeTest”将显示动态链接库 - $libdir/libmagic.so 不应该在其中。

至于链接外部数据文件...我不知道 - 你能不打包应用程序(.deb|.rpm|.tar.bz2)吗?在 Windows 上,我会使用 NSIS 编写安装程序。

【讨论】:

【参考方案2】:

过去我建立了自解压档案。基本上它是一个 .exe 文件,包含一个 .zip 存档和解压缩它的代码。下载.exe,运行它,然后噗!您可以拥有任意数量的文件。

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

【讨论】:

【参考方案3】:

这很棘手,我想你可以这样做...顺便说一句,我已经下载了 libmagic 源并查看了它...

minifile.c 中有一个名为magic_read_entries 的函数(这是我从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)' 将负责加载条目,你应该没问题。

如果您需要进一步的帮助,请告诉我,

编辑: 我使用了 sourceforge.net 中的旧的“libmagic”,这就是我所做的:

    将下载的存档解压缩到我的主目录中,解压缩/解压缩存档将创建一个名为 libmagic 的文件夹。 在 libmagic 中创建一个文件夹并将其命名为 Test 将原ma​​gic.cminifile.c复制到Test 使用封闭的差异输出突出显示差异,将其应用到 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)) > 如果 (ftell(fp) != MAGIC_DATA_OFFSET) 返回 0; > 其他 > 返回 0; > > 然后发出 make magic 文件(我在 Slackware Linux 12.2 下从 /etc 复制)连接到 libmagic.a 文件,即cat magic >> libmagic.a。魔法的 SHA 校验和是(4abf536f2ada050ce945fbba796564342d6c9a61 魔法), 这是魔术的确切数据 (-rw-r--r-- 1 root root 474443 2007-06-03 00:52 /etc/file/magic) 在我的系统上找到。 这是 minifile.c 源的差异,应用它并通过再次运行 make 来重建 minifile 可执行文件。 40c40 /*magic_read_entries(mh,"magic");*/

那么它应该可以工作。如果没有,您将需要通过修改 MAGIC_DATA_OFFSET 来调整库中的偏移量以供读取。如果您愿意,我可以将魔术数据文件粘贴到 pastebin 中。告诉我。

希望这会有所帮助, 最好的祝福, 汤姆。

【讨论】:

我也考虑过使用/修改 libmagic 的源代码,所以我也发现了 sourceforge 版本,但我怀疑它们与 ubuntu repo 中的 libmagic-dev 不同。如果您执行man libmagic 或检查linux.die.net/include/magic.h,则时间戳为2003。来自SF 的时间戳为2000 (sourceforge.net/projects/libmagic/files)。否则,我想这将是一个很好的解决方案,我可以开始弄清楚如何解决它。 看起来较新的 libmagic 5.03 中的 magic 条目与旧的 libmagic alpha 不兼容。看起来 libmagic 5.03 包含在 file-5.03 中(来自man file,ftp.astron.com/pub/file/file-5.04.tar.gz),所以我会尝试解决这个问题。如果我到了那一点,我想我可能会在尝试执行附加和指针偏移的事情时遇到困难。 无论哪种方式,如果您需要我的帮助,请随时回复! ;) 尽我所能,我无法解耦file 的libmagic 部分,也找不到独立的libmagic 源。我想我只是让我的应用程序通过其扩展名来识别文件,并在它以错误的文件类型结束时抛出。 @Kache4:最新版本的 libmagic/file 的来源在哪里?会调查并试一试...

以上是关于静态编译libmagic(c/c++文件类型检测)的主要内容,如果未能解决你的问题,请参考以下文章

编译与解释的区别

如何编译C/Fortran动态/静态链接库

编译型与解释型动态语言与静态语言强类型语言与弱类型语言的区别

python——静态语言动态语言强类型语言弱类型语言脚本语言解释型语言编译型语言

linux下intel的mkl编程代码,怎么样编译。C++和C语言代码

找出文件类型