将 OpenSSL 静态库添加到 Visual Studio 2017 项目
Add OpenSSL static lib to Visual Studio 2017 project
NuGets 添加到项目时是否修改包含和链接路径?
我的背景是使用 CMake,但我现在在一家从头开始构建解决方案文件的公司工作,我不确定如何将静态 OpenSSL 库正确添加到我的项目中。我发布问题是为了确保我不会重复某些内容或以其他方式弄乱它。
当我将 openssl-vc141-static-x86_64 添加到我的项目时,它会构建 .lib
文件和所有内容,但不会修改包含或链接器路径。
我可以手动添加链接器路径,但是因为给我的项目没有典型的 Release
/Debug
配置,所以我无法使用 $(Configuration)
指向目标库的宏 - 所以我结束时只指向 Release
。虽然构建有效。
我看到有一个 .targets
文件,但它似乎没有任何作用。
(更新)
具体来说,我基本上是在构建 boost 的 http_server_async.cpp。我得到的链接器错误是:
Error LNK2019 unresolved external symbol _BIO_free referenced in function "public: __thiscall boost::asio::ssl::context::bio_cleanup::~bio_cleanup(void)" (??1bio_cleanup@context@ssl@asio@boost@@QAE@XZ) ESOIPDataScope C:\gitrepo\ALIDB\ESOIPDataScope\DataHandler.obj
Error LNK2001 unresolved external symbol _BIO_free ESOIPDataScope C:\gitrepo\ALIDB\ESOIPDataScope\Listener.obj
... (48 more like this)
当我手动添加 $(SolutionDir)packages\openssl-vc141-static-x86_64.1.1.0\build\native\lib\Win32\static\Release\libcrypto.lib
和
$(SolutionDir)packages\openssl-vc141-static-x86_64.1.1.0\build\native\lib\Win32\static\Release\libssl.lib
作为项目编译的附加依赖项时。
(/更新)
为了对比,我添加了一个 freeglut NuGet,并注意到它给了我更多的配置选项(配置属性 → 引用项目),而且,boost 似乎已经将它的链接器目录添加到我的项目中(虽然我只看到在 MSBuild 输出中,而不是在配置属性->链接器->命令行中)
有没有合适的方法来添加我缺少的这些项目?或者使用 targets
文件的正确方法?或者也许 OpenSSL 静态 NuGet 只是遗漏了什么?或者我应该看看 vcpkg?
Do NuGets modify the include and linking paths when added to a
project?
当然。我可以明确地告诉你,nuget 通过 <package_id>.targets
或 <package_id>.props
文件将额外的属性导入到项目中,而不是再次手动添加包含路径。
这是nuget打包的一种机制,在安装nuget包的过程中直接给项目添加库路径等额外的项目属性。更多信息可以参考this link.
<package_id>.targets
是在打包nuget包的过程中创建的。
也就是说,这个方法是nuget包的作者设计的。在我这边,文件 openssl-vc141-static-x86_64.targets
存在于这个路径中:
C:\Users\Admin\source\repos\ConsoleApplication25\packages\openssl-vc141-static-x86_64.1.1.0\build\native
also, boost seems to have added its linker directories to my project
(though I only see that in MSBuild output, not in Configuration
Properties->Linker->Command Line)
我认为这个问题与 <package_id>.targets
和 <package_id>.props
之间的差异有关。虽然using <package_id>.targets
没有出现在属性 UI上,但它仍然适用于整个项目。
更详细
当您将 nuget 包安装到项目中时,这些文件会自动执行。 <target_id>.props
文件被添加到文件的顶部,而 .targets 被添加到底部。
初始化xxx.vcxproj
文件时,由于<package_id> .props
在文件头部,属性UI可以捕获文件中的属性,<package_id> .targets
在最后,所以无法捕获初始化但仍在项目中。对于 nuget,它使用 openssl-vc141-static-x86_64.targets
.
在openssl-vc141-static-x86_64.targets
文件中,你可以看到这个:
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include\;%
(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAS_LIBTHRIFT;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
</ClCompile>
并且我已将输出日志设置为 Diagnostic
并构建项目并发现:
库路径已由openssl-vc141-static-x86_64.targets
文件自动添加到AdditionalIncludeDirectories
中。所以你不用担心。
Is there a proper way to add these projects that I'm missing? Or a
proper way to use the targets file? Or maybe the OpenSSL static NuGet
just missing something? Or maybe I should just look into vcpkg?
您不必担心,不要将包含路径添加到项目中 属性。这是多余的,当你完成安装这个 nuget 包后,直接在 cpp 文件中使用它。
此外,
对于nuget安装的c++包,不需要在工程中添加任何路径属性。
更新 1
问题与您的项目有关,与 nuget 包无关。正是因为你当前的项目没有$(Configuration)
,所以在openssl-vc141-static-x86_64.targets
中,你可以看到这些:
<ItemDefinitionGroup Label="Win32 and vc141 and Debug" Condition="'$(Platform)' == 'Win32' And ( $(PlatformToolset.IndexOf('v141')) > -1 Or '$(PlatformToolset)' == 'WindowsKernelModeDriver8.0' Or '$(PlatformToolset)' == 'WindowsApplicationForDrivers8.0' Or '$(PlatformToolset)' == 'WindowsUserModeDriver8.0' ) And '$(Configuration)' == 'Debug'">
<Link>
<AdditionalLibraryDirectories>$(MSBuildThisFileDirectory)lib\Win32\static\Debug\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libssl.lib;libcrypto.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /Y "$(MSBuildThisFileDirectory)\lib\Win32\dynamic\*-1_1.dll" "$(OutDir)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
这是将特定的libssl.lib
和libcrypto.Lib
导入AdditionalDependencies
节点的操作。但是你可以发现有一个判断条件And '$(Configuration)' == 'Debug'
,因为你没有$(Configuration)
,所以,它总是returns false和这些无法将库自动导入 AdditionalDependencies
。
作为解决方法,您应该按照您所说的手动添加这些库路径。
并且我确信如果您使用包含 $(Configuration)
(调试或发布)的项目,您将不会遇到此问题。大多数C++ nuget包可以直接在包含Configuration
节点的项目中使用。
我确信如果你在你的项目中使用 $(Configuration)
然后重新安装这个包(请 clean the nuget cache 然后再安装),你将不会遇到这个错误。
Also, your screen shot, where did you get that? I don't see anything
like that in the VS output console, or when I run msbuild on the
command line. Is there some way I might have accidentally broken the
default behaviour?
可以通过Tools
-->Options
-->Projects and Solutions
-->Build and Run
将MSBuild project build output verbosity
设置为Diagnostic
。
构建项目时,输出Window显示整个构建过程并记录所有信息,然后您可以通过[=搜索关键字段97=]搜索框 输出 Window.
NuGets 添加到项目时是否修改包含和链接路径?
我的背景是使用 CMake,但我现在在一家从头开始构建解决方案文件的公司工作,我不确定如何将静态 OpenSSL 库正确添加到我的项目中。我发布问题是为了确保我不会重复某些内容或以其他方式弄乱它。
当我将 openssl-vc141-static-x86_64 添加到我的项目时,它会构建 .lib
文件和所有内容,但不会修改包含或链接器路径。
我可以手动添加链接器路径,但是因为给我的项目没有典型的 Release
/Debug
配置,所以我无法使用 $(Configuration)
指向目标库的宏 - 所以我结束时只指向 Release
。虽然构建有效。
我看到有一个 .targets
文件,但它似乎没有任何作用。
(更新)
具体来说,我基本上是在构建 boost 的 http_server_async.cpp。我得到的链接器错误是:
Error LNK2019 unresolved external symbol _BIO_free referenced in function "public: __thiscall boost::asio::ssl::context::bio_cleanup::~bio_cleanup(void)" (??1bio_cleanup@context@ssl@asio@boost@@QAE@XZ) ESOIPDataScope C:\gitrepo\ALIDB\ESOIPDataScope\DataHandler.obj
Error LNK2001 unresolved external symbol _BIO_free ESOIPDataScope C:\gitrepo\ALIDB\ESOIPDataScope\Listener.obj
... (48 more like this)
当我手动添加 $(SolutionDir)packages\openssl-vc141-static-x86_64.1.1.0\build\native\lib\Win32\static\Release\libcrypto.lib
和
$(SolutionDir)packages\openssl-vc141-static-x86_64.1.1.0\build\native\lib\Win32\static\Release\libssl.lib
作为项目编译的附加依赖项时。
(/更新)
为了对比,我添加了一个 freeglut NuGet,并注意到它给了我更多的配置选项(配置属性 → 引用项目),而且,boost 似乎已经将它的链接器目录添加到我的项目中(虽然我只看到在 MSBuild 输出中,而不是在配置属性->链接器->命令行中)
有没有合适的方法来添加我缺少的这些项目?或者使用 targets
文件的正确方法?或者也许 OpenSSL 静态 NuGet 只是遗漏了什么?或者我应该看看 vcpkg?
Do NuGets modify the include and linking paths when added to a project?
当然。我可以明确地告诉你,nuget 通过 <package_id>.targets
或 <package_id>.props
文件将额外的属性导入到项目中,而不是再次手动添加包含路径。
这是nuget打包的一种机制,在安装nuget包的过程中直接给项目添加库路径等额外的项目属性。更多信息可以参考this link.
<package_id>.targets
是在打包nuget包的过程中创建的。
也就是说,这个方法是nuget包的作者设计的。在我这边,文件 openssl-vc141-static-x86_64.targets
存在于这个路径中:
C:\Users\Admin\source\repos\ConsoleApplication25\packages\openssl-vc141-static-x86_64.1.1.0\build\native
also, boost seems to have added its linker directories to my project (though I only see that in MSBuild output, not in Configuration Properties->Linker->Command Line)
我认为这个问题与 <package_id>.targets
和 <package_id>.props
之间的差异有关。虽然using <package_id>.targets
没有出现在属性 UI上,但它仍然适用于整个项目。
更详细
当您将 nuget 包安装到项目中时,这些文件会自动执行。 <target_id>.props
文件被添加到文件的顶部,而 .targets 被添加到底部。
初始化xxx.vcxproj
文件时,由于<package_id> .props
在文件头部,属性UI可以捕获文件中的属性,<package_id> .targets
在最后,所以无法捕获初始化但仍在项目中。对于 nuget,它使用 openssl-vc141-static-x86_64.targets
.
在openssl-vc141-static-x86_64.targets
文件中,你可以看到这个:
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include\;%
(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAS_LIBTHRIFT;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
</ClCompile>
并且我已将输出日志设置为 Diagnostic
并构建项目并发现:
库路径已由openssl-vc141-static-x86_64.targets
文件自动添加到AdditionalIncludeDirectories
中。所以你不用担心。
Is there a proper way to add these projects that I'm missing? Or a proper way to use the targets file? Or maybe the OpenSSL static NuGet just missing something? Or maybe I should just look into vcpkg?
您不必担心,不要将包含路径添加到项目中 属性。这是多余的,当你完成安装这个 nuget 包后,直接在 cpp 文件中使用它。
此外,
对于nuget安装的c++包,不需要在工程中添加任何路径属性。
更新 1
问题与您的项目有关,与 nuget 包无关。正是因为你当前的项目没有$(Configuration)
,所以在openssl-vc141-static-x86_64.targets
中,你可以看到这些:
<ItemDefinitionGroup Label="Win32 and vc141 and Debug" Condition="'$(Platform)' == 'Win32' And ( $(PlatformToolset.IndexOf('v141')) > -1 Or '$(PlatformToolset)' == 'WindowsKernelModeDriver8.0' Or '$(PlatformToolset)' == 'WindowsApplicationForDrivers8.0' Or '$(PlatformToolset)' == 'WindowsUserModeDriver8.0' ) And '$(Configuration)' == 'Debug'">
<Link>
<AdditionalLibraryDirectories>$(MSBuildThisFileDirectory)lib\Win32\static\Debug\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libssl.lib;libcrypto.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /Y "$(MSBuildThisFileDirectory)\lib\Win32\dynamic\*-1_1.dll" "$(OutDir)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
这是将特定的libssl.lib
和libcrypto.Lib
导入AdditionalDependencies
节点的操作。但是你可以发现有一个判断条件And '$(Configuration)' == 'Debug'
,因为你没有$(Configuration)
,所以,它总是returns false和这些无法将库自动导入 AdditionalDependencies
。
作为解决方法,您应该按照您所说的手动添加这些库路径。
并且我确信如果您使用包含 $(Configuration)
(调试或发布)的项目,您将不会遇到此问题。大多数C++ nuget包可以直接在包含Configuration
节点的项目中使用。
我确信如果你在你的项目中使用 $(Configuration)
然后重新安装这个包(请 clean the nuget cache 然后再安装),你将不会遇到这个错误。
Also, your screen shot, where did you get that? I don't see anything like that in the VS output console, or when I run msbuild on the command line. Is there some way I might have accidentally broken the default behaviour?
可以通过Tools
-->Options
-->Projects and Solutions
-->Build and Run
将MSBuild project build output verbosity
设置为Diagnostic
。
构建项目时,输出Window显示整个构建过程并记录所有信息,然后您可以通过[=搜索关键字段97=]搜索框 输出 Window.