根据当前操作系统 (Windows/Linux),将本机库复制到 Visual Studio 或 MonoDevelop 中每个构建的输出目录
Copy Native Libraries to Output directory on every Build in Visual Studio or MonoDevelop based on current Operating System (Windows/Linux)
我正在开发一个目前正在 VS 2017 中开发的 C# WinForms 项目,不过,它将部署在 Linux 机器上 Ubuntu 16.04 LTS 使用 Mono 框架(MonoRuntime
).
我在我的项目中引用了 EmguCV v3.2
和 SQLite
。这两个都是 .NET 托管程序集,依赖于它们自己的本机库(EmguCV
使用 cvextern.dll
,SQLite
使用 SQLite.Interop.dll
)。
由于这个应用程序将部署在 Linux 机器上,我已经为它们编译并构建了 .so
库文件(libcvextern.so
和 libSQLite.Interop.so
准确地说)成功。
为了让我的应用程序在 Windows 上运行,2 个 .so
文件是多余的,而当我的应用程序在 Linux 下的 Mono 下运行时它们是必需的(并且它们必须是始终在执行目录中!)。
我的问题是,我想让 Visual Studio 2017 或 MonoDevelop 明白如果我在 Windows(或者 Debug/Release)上构建,我需要 .dll
要复制到输出目录 (OR) 的文件类似于 .so
文件,如果在 Linux 上。你如何处理这个问题?
那么,我如何正确设置一个 Post-Build 事件,VS 2017 和 MonoDevelop 都尊重它们在构建时识别底层当前操作系统并将相应的 lib 文件复制到输出目录?
对于任何英语语法问题,我深表歉意,我不是母语人士。
不胜感激!
好的,我已经通过 3 个步骤解决了这个问题(搜索了几个小时之后)。
如上所述,如果项目是在 Windows 上构建的(Debug/Release),我的要求是将 .dll
文件复制到输出目录,并复制 .so
对应的文件如果项目是在 Linux 上使用 MonoDevelop 构建的 (Debug/Release),则为 libs。
- 我将库复制到项目文件夹中的一个目录(安全的地方),然后在 VS 2017 中使用
Add Existing Item
--> 选择所需的 lib 文件 --> 使用 Add as Link
而不是Open
(找到这个 from here)。
- 我需要将它们复制到输出目录,而没有从我将它们添加到项目时继承的文件夹结构,所以我遵循了 accepted answer to this question 并且能够指示它在每个构建中复制到输出目录.
- 现在对于最终要求,即根据底层操作系统复制特定文件,我在
.csproj
文件的 ItemPropertyGroup
中使用了 Condition
属性。这是我所做的:
如果基础 OS 是 Windows,我有 1 个 .dll
要包含,如果是 linux,我有 2 个 .so
文件,这是我对它们的配置在 .csproj
文件中修改。
<ContentWithTargetPath Include="references\libDependencies\linux64\libcvextern.so" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libcvextern.so</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="references\libDependencies\linux64\libSQLite.Interop.so" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libSQLite.Interop.so</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="references\libDependencies\win64\cvextern.dll" Condition=" '$(OS)' == 'Windows_NT' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>cvextern.dll</TargetPath>
</ContentWithTargetPath>
不出所料,从现在开始,每次构建(Debug/Release)时,相应的库都会被复制到输出目录。就这些了,希望对大家有帮助。
我正在开发一个目前正在 VS 2017 中开发的 C# WinForms 项目,不过,它将部署在 Linux 机器上 Ubuntu 16.04 LTS 使用 Mono 框架(MonoRuntime
).
我在我的项目中引用了 EmguCV v3.2
和 SQLite
。这两个都是 .NET 托管程序集,依赖于它们自己的本机库(EmguCV
使用 cvextern.dll
,SQLite
使用 SQLite.Interop.dll
)。
由于这个应用程序将部署在 Linux 机器上,我已经为它们编译并构建了 .so
库文件(libcvextern.so
和 libSQLite.Interop.so
准确地说)成功。
为了让我的应用程序在 Windows 上运行,2 个 .so
文件是多余的,而当我的应用程序在 Linux 下的 Mono 下运行时它们是必需的(并且它们必须是始终在执行目录中!)。
我的问题是,我想让 Visual Studio 2017 或 MonoDevelop 明白如果我在 Windows(或者 Debug/Release)上构建,我需要 .dll
要复制到输出目录 (OR) 的文件类似于 .so
文件,如果在 Linux 上。你如何处理这个问题?
那么,我如何正确设置一个 Post-Build 事件,VS 2017 和 MonoDevelop 都尊重它们在构建时识别底层当前操作系统并将相应的 lib 文件复制到输出目录?
对于任何英语语法问题,我深表歉意,我不是母语人士。
不胜感激!
好的,我已经通过 3 个步骤解决了这个问题(搜索了几个小时之后)。
如上所述,如果项目是在 Windows 上构建的(Debug/Release),我的要求是将 .dll
文件复制到输出目录,并复制 .so
对应的文件如果项目是在 Linux 上使用 MonoDevelop 构建的 (Debug/Release),则为 libs。
- 我将库复制到项目文件夹中的一个目录(安全的地方),然后在 VS 2017 中使用
Add Existing Item
--> 选择所需的 lib 文件 --> 使用Add as Link
而不是Open
(找到这个 from here)。 - 我需要将它们复制到输出目录,而没有从我将它们添加到项目时继承的文件夹结构,所以我遵循了 accepted answer to this question 并且能够指示它在每个构建中复制到输出目录.
- 现在对于最终要求,即根据底层操作系统复制特定文件,我在
.csproj
文件的ItemPropertyGroup
中使用了Condition
属性。这是我所做的:
如果基础 OS 是 Windows,我有 1 个 .dll
要包含,如果是 linux,我有 2 个 .so
文件,这是我对它们的配置在 .csproj
文件中修改。
<ContentWithTargetPath Include="references\libDependencies\linux64\libcvextern.so" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libcvextern.so</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="references\libDependencies\linux64\libSQLite.Interop.so" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libSQLite.Interop.so</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="references\libDependencies\win64\cvextern.dll" Condition=" '$(OS)' == 'Windows_NT' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>cvextern.dll</TargetPath>
</ContentWithTargetPath>
不出所料,从现在开始,每次构建(Debug/Release)时,相应的库都会被复制到输出目录。就这些了,希望对大家有帮助。