在 [GitHub]: CristiFati/Prebuilt-Binaries - (master) Prebuilt-Binaries/LibJPEG 上发布的构建(静态/动态)。
与当今几乎所有的软件一样,libjpeg 也托管在 [GitHub]: winlibs/libjpeg - libjpeg-9b 上。我从这两个地方下载了它,做了一个比较,只有很少的细微差别(源代码中没有)弹出。我将在 GitHub 版本上进行解释。不幸的是,没有这方面的演练,所以我不得不查看一些文件以找出必须做什么。以下是步骤列表:
1。准备地面
1st 事情是将压缩的(zip / tar.gz)文件内容解压到一个文件夹中(并有一个cmd 控制台在那里打开)。该文件夹包含一堆文件。我们需要的第一个st 是makefile.vc。顾名思义,它是一个 Makefile,由一系列通常用于构建东西的规则/指令组成。
作为评论,我正在使用 VStudio (Community) 2015 (14.0) 来完成这项任务(但应该没有区别对于较新的版本)。
处理Makefiles 的工具是nmake ([MS.Docs]: NMAKE reference)。我们需要针对该文件调用它。 nmake 位于“%VSTUDIO_INSTALL_DIR%\VC\bin\nmake.exe”(env var 并不存在,它只是一个路径占位符);通常是 "%SystemDrive%\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\nmake.exe" (例如在我的机器上它是 "C:\Install\x86 \Microsoft\Visual Studio Community\2015\VC\bin\nmake.exe”)。
请注意,在处理 VStudio 命令行工具时,最好是:
- 使用 vcvarsall(这是一个 (batch) 工具,可以设置一些环境变量,例如 %PATH%), %INCLUDE%, %LIB%, ...),所以所有 VStudio 工具都可以在没有完整路径的情况下使用。但由于它也位于“%VSTUDIO_INSTALL_DIR%\VC\vcvarsall.bat”中,因此不值得努力定位/调用它
- 使用开始菜单中的VS2015工具命令提示符(基本上调用vcvarsall)
-
[MS.Docs]: Building on the Command Line 包含有关此主题的更多详细信息
现在我们知道了 nmake 的位置,让我们运行:
"%VSTUDIO_INSTALL_DIR%\VC\bin\nmake.exe" /f makefile.vc setup-v10
(不要忘记将 nmake 的路径包含在 dblquotes(") 中,尤其是如果它包含 SPACEs)。
如果遇到问题,Google 可能会提供解决方案:
setup-v10 是一个 Makefile 目标,它只是简单地重命名文件夹中的一些文件(坦率地说,我不知道为什么这些文件不像已在第 1st 位置重命名)。
在文件夹中运行命令后,应该有2个VStudio解决方案文件:
-
jpeg.sln - 包含一个项目:
-
jpeg.vcxproj - 这是负责构建库的项目
-
apps.sln - 包含一堆项目(我不知道/不在乎他们在做什么):
-
djpeg.vcxproj - 这是我要提到的唯一一个,因为我将使用它来测试构建的库
2。构建 jpeg 库
要注意的第一个st 是在上一节中生成的解决方案/项目文件是针对VStudio 2010 的。但这不是问题,因为 VStudio 2015 能够处理它们(加载它们时,它会进行所有必要的转换以使它们保持最新状态)。
打开 jpeg.sln,会发现一些关于解决方案(和项目)的(不愉快的)内容:
- 只有Win32 (32bit or x86) 平台
- 正如您已经提到的,它构建了一个静态库
无论如何,解决方案应该构建OOTB。完成后,您会注意到一个 Release 文件夹,其中应该包含(除了一堆中间 - .obj 文件),4+ MB jpeg.lib 文件,它是静态库。知道代码(和项目相关文件)都OK了,我们继续下一步。
2.1 构建jpeg DLL
为了避免破坏现有功能,我们应该创建一个新的配置(请注意,为您的项目创建一个新的平台的过程(几乎)相同):
- 从菜单中选择构建 -> 配置管理器...
- 在弹出的对话框中,向上点击Release组合框并选择
- 在 New Solution Configuration 对话框中,为新配置选择一个名称:我选择了 Release-DLL(从现在开始我将依赖这个名字)
- 确保在从组合框中复制设置中选择发布
- 检查创建新项目配置
按下OK后,新的Release-DLL配置将与Release相同。下一步是对其进行必要的更改,以实现我们的目标。在Solution Explorer(在VStudio窗口的左侧)中RClickjpeg项目,然后选择属性:
在上图中,有 jpeg 项目设置窗口,显示了它们最后的样子。我突出显示(使用颜色)不同的兴趣点:
全部保存并构建。构建成功后,会出现一个新的文件夹Win32-Release-DLL,和上一个一样,里面会包含一堆文件加上 jpeg.dll 。有人可能认为它已经完成了,但事实并非如此。所有的代码都在 .dll 中编译/构建,但它没有导出,所以 .dll 是几乎无法使用。您可以使用Dependency Walker 打开许多.dll(或.exe)属性。您可以查看来自[SO]: Excel VBA, Can't Find DLL Entry Point from a DLL file (@CristiFati's answer) 的屏幕截图 - 在我们的示例中,导出区域将为空。
最后一点:如果您认为将来需要为其他平台(x64,甚至 ARM ),并且你还需要做一些调试(添加一个 Debug 配置),在 Win32 平台下添加 Debug 配置首先,然后然后从Win32创建新平台,否则您需要为每个平台添加Debug配置在将 Debug 配置添加到 Win32 之前创建。
2.2 从DLL导出数据
请注意:除了 __declspec(dllexport) 方法外,还有 2 个方法(在处理来自 Win 的导出时 .dlls):
但是,由于我们不知道代码并且可能有很多符号要导出,因此这 3 个中没有一个是可扩展的(它们可能需要大量的研究/工作)。无论如何,我们将坚持原来的方法:
-
保存以下代码:
#pragma once
#if defined(_WIN32)
# if defined(LIBJPEG_STATIC)
# define LIBJPEG_EXPORT_API
# else
# if defined(LIBJPEG_EXPORTS)
# define LIBJPEG_EXPORT_API __declspec(dllexport)
# else
# define LIBJPEG_EXPORT_API __declspec(dllimport)
# endif
# endif
#else
# define LIBJPEG_EXPORT_API
#endif
在 libjpeg 源文件夹中名为 jexport.h 的文件中。这是一个非常标准的 header 文件,用于处理 .dll 导出。
接下来,将其添加到项目中:在 Solution Explorer 中,RClick on Header Files -> Add -> Existing Item...
-
利用新文件
--- jmorecfg.h.orig 2016-03-30 09:38:56.000000000 +0300
+++ jmorecfg.h 2017-06-09 21:04:33.762535400 +0300
@@ -30,6 +30,8 @@
* in all cases (see below).
*/
+#include "jexport.h"
+
#define BITS_IN_JSAMPLE 8 /* use 8, 9, 10, 11, or 12 */
@@ -245,7 +247,8 @@
/* a function referenced thru EXTERNs: */
#define GLOBAL(type) type
/* a reference to a GLOBAL function: */
-#define EXTERN(type) extern type
+
+#define EXTERN(type) extern LIBJPEG_EXPORT_API type
/* This macro is used to declare a "method", that is, a function pointer.
以上是一个差异。请参阅[SO]: Run/Debug a Django application's UnitTests from the mouse right click context menu in PyCharm Community Edition? (@CristiFati's answer)(Patching utrunner 部分)了解如何在 Win 上应用补丁(基本上,每一行都以 one " 开头+" 符号进入,以 一个 "-" 符号开头的每一行都退出)。但是,由于更改是微不足道的,因此也可以手动完成。需要更改的文件是jmorecfg.h(需要2个东西):
- 在开头包含新文件 (
#include "jexport.h")
- 修改第251行(将
#define EXTERN(type) extern type替换为#define EXTERN(type) extern LIBJPEG_EXPORT_API type)
我认为这一步是一种解决方法(gainarie),但正如我所说,“真正的东西”只需要太多的工作(和时间)。
-
告诉编译器考虑我们的更改
编辑项目设置(再次小心Platform / Configuration),选择Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions 并将旧值(在我的例子中:WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS)替换为 WIN32;LIBJPEG_EXPORTS;_CRT_SECURE_NO_WARNINGS;NDEBUG。我所做的是:
-
正在删除 _LIB
-
添加 LIBJPEG_EXPORTS
- 有些变化
[MS.Docs]: /D (Preprocessor Definitions) 可能包含一些有用的信息。
作为旁注,在进行上述更改后,原始(或“正常”)行为(发布配置)将不会OK (它会生成一堆警告,但这在技术上是不正确的)。那是因为我不想依赖 _LIB 宏来区分静态/动态库构建。为了解决问题,在 Preprocessor Definitions 中添加 LIBJPEG_STATIC 以进行 Release 配置(遵循与上述相同的过程) .
全部保存并构建。构建成功后,jpeg.dll被覆盖,更重要的是:会创建一个新文件jpeg.lib;这告诉我们 jpeg.dll 导出了一些东西。您可以使用 Dependency Walker 再次检查它。
3。测试 DLL
- 这是可选的,我这样做是为了确保我到目前为止所做的一切没有白费
- 通过测试,我只指构建和运行,这意味着我不进行任何功能测试(从 .dll 导出的函数实际上会做任何事情'应该)
加载 apps.sln 解决方案,最好在新的 VStudio 实例中。正如我所说,我只关心 djpeg 项目。
-
1st 要做的事情,就是为现有的Release 配置构建它。但是,由于对 jpeg 库所做的更改,它不会构建 OOTB(会有 linker 错误)。为了摆脱它们,编辑其设置,预处理器定义(就像在上一步中一样),并添加 LIBJPEG_STATIC(不要忘记分隔符(;))。
构建应该成功并且在djpeg\Release文件夹下应该有一个djpeg.exe文件。尝试运行它,会成功(这是我唯一关心的事情)。
-
使用我们的 .dll 构建一个新的可执行文件:
- 就像 jpeg 库的情况一样,创建一个新配置:Release-DLL(确保完成所有步骤,但不要更改它)李>
- 只需要进行一项更改:让 链接器 知道我们在哪里构建 .lib 文件。进入项目设置,Configuration Properties -> Linker -> Input -> Additional Dependencies:第 1st 是 Release\jpeg.lib。显然路径不正确,所以我们需要将Release替换为Win32-Release-DLL(当然你可以使用VStudio宏(对于平台 / 配置))。可能会检查[MS.Docs]: .Lib Files as Linker Input。
全部保存并构建。构建成功后,在djpeg\Release-DLL下,应该有一个djpeg.exe文件。尝试运行它会失败,因为它找不到 jpeg.dll。通过将 jpeg.dll 复制到(检查[MS.Docs]: Dynamic-Link Library Search Order 的语义)来解决这个问题:
-
djpeg.exe 的文件夹
-
%PATH% 环境变量中的一个文件夹(或相反,将 jpeg.dll 文件夹附加到 %PATH%)
再次,您可以使用 Dependency Walker 检查 2 个可执行文件(但大小差异足以说明:2nddjpeg.exe 是明显更小),查看哪个依赖于 jpeg.dll。无论如何,这是我计算机上的输出(是的,Dependency Walker 也可以充当 cmdline :)):
e:\Work\Dev\StackOverflow\q044450813\src\libjpeg-libjpeg-9b>"c:\Install\x86\Depends\Dependency Walker-politist-texan\AllVers\depends.exe" /c /ot:static.txt djpeg\Release\djpeg.exe
e:\Work\Dev\StackOverflow\q044450813\src\libjpeg-libjpeg-9b>"c:\Install\x86\Depends\Dependency Walker-politist-texan\AllVers\depends.exe" /c /ot:dynamic.txt djpeg\Release-DLL\djpeg.exe
e:\Work\Dev\StackOverflow\q044450813\src\libjpeg-libjpeg-9b>type static.txt | findstr -i "jpeg.dll"
e:\Work\Dev\StackOverflow\q044450813\src\libjpeg-libjpeg-9b>type dynamic.txt | findstr -i "jpeg.dll"
[ ] e:\work\dev\stackoverflow\q044450813\src\libjpeg-libjpeg-9b\djpeg\release-dll\JPEG.DLL
[ ] e:\work\dev\stackoverflow\q044450813\src\libjpeg-libjpeg-9b\djpeg\release-dll\JPEG.DLL 2017-06-09 21:16 2017-06-09 21:16 237,056 A 0x00000000 0x0003ECC8 x86 GUI CV,Unknown 0x10000000 Unknown 0x0003E000 Not Loaded N/A N/A 0.0 14.0 6.0 6.0
更新#0
我也有: