enable nuget packaging in local builds (#4884)

* enable building nuget packages

* add nuget creation from build.py

* add documentation

* fix flake8 errors

* fix nuget package version

* enable csharp tests

* update csharp tests

* copy nuget packges to nuget-artifacts

* add libmklml_gnu

* plus review updates

* fix references for release builds
This commit is contained in:
Ashwini Khade 2020-08-26 12:33:48 -07:00 committed by GitHub
parent 0a2848d3a0
commit 0d3bbfdd0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 393 additions and 72 deletions

View file

@ -124,7 +124,8 @@ GCC 4.x and below are not supported.
|API|Command|Additional details|
|-----------|-----------|-----------|
|**Python**|--build_wheel||
|**C# and C packages**|--build_csharp||
|**C# and C packages**|--build_nuget|Builds C# bindings and creates nuget package. Currently supported on Windows and Linux only. Implies `--build_shared_lib` <br>
Requires [dotnet](https://dotnet.microsoft.com/download) for building csharp bindings and [nuget.exe](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools#nugetexe-cli) for creating nuget package.|
|**WindowsML**|--use_winml<br>--use_dml<br>--build_shared_lib|WindowsML depends on DirectML and the OnnxRuntime shared library|
|**Java**|--build_java|Creates an onnxruntime4j.jar in the build directory, implies `--build_shared_lib`<br>Compiling the Java API requires [gradle](https://gradle.org) v6.1+ to be installed in addition to the usual requirements.|
|**Node.js**|--build_nodejs|Build Node.js binding. Implies `--build_shared_lib`|

View file

@ -17,14 +17,27 @@ CMake creates a target to this project
<TargetArchitecture Condition=" '$(TargetArchitecture)' == '' ">x64</TargetArchitecture>
<IsReleaseBuild Condition=" '$(IsReleaseBuild)' == '' ">false</IsReleaseBuild>
<IsLinuxBuild Condition=" '$(IsLinuxBuild)' == '' ">false</IsLinuxBuild>
<ExecutionProvider Condition=" '$(ExecutionProvider)' == '' ">None</ExecutionProvider>
<!--internal build related properties-->
<OnnxRuntimeSourceDirectory Condition="'$(OnnxRuntimeSourceDirectory)'==''">..</OnnxRuntimeSourceDirectory>
<GenerateNuspecScript>..\tools\nuget\generate_nuspec_for_native_nuget.py</GenerateNuspecScript>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='true'">
<!--internal build related properties for Linux -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">..\build\Linux</OnnxRuntimeBuildDirectory>
<OnnxRuntimePackagesDirectory Condition="'$(OnnxRuntimePackagesDirectory)'==''">$(OnnxRuntimeBuildDirectory)\packages</OnnxRuntimePackagesDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='false'">
<!--internal build related properties for Windows -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">..\build\Windows</OnnxRuntimeBuildDirectory>
<OnnxRuntimePackagesDirectory Condition="'$(OnnxRuntimePackagesDirectory)'==''">$(OnnxRuntimeBuildDirectory)\packages</OnnxRuntimePackagesDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="RestoreProjects" BeforeTargets="Build">
@ -110,9 +123,9 @@ CMake creates a target to this project
<MSBuild Projects="src\Microsoft.ML.OnnxRuntime\Microsoft.ML.OnnxRuntime.csproj"
Targets="CopyMiscFiles;Pack"
Properties="NoBuild=true;Platform=AnyCPU;PackageVersion=$(PackageVersion);OrtPackageId=$(OrtPackageId)"/>
<Message Importance="High" Text="Generating nuspec for the native Nuget package ..." />
<Exec ContinueOnError="False" Command="python ..\tools\nuget\generate_nuspec_for_native_nuget.py --package_version $(PackageVersion) --package_name $(OrtPackageId) --target_architecture $(TargetArchitecture) --build_config $(Configuration) --native_build_path $(NativeBuildOutputDirAbs) --packages_path $(OnnxRuntimePackagesDirectoryAbs) --ort_build_path $(OnnxRuntimeBuildDirectoryAbs) --sources_path $(OnnxRuntimeSourceDirectoryAbs) --commit_id $(GitCommitHash) --is_release_build $(IsReleaseBuild) --is_linux_build $(IsLinuxBuild)" ConsoleToMSBuild="true">
<Exec ContinueOnError="False" Command="python $(GenerateNuspecScript) --package_version $(PackageVersion) --package_name $(OrtPackageId) --target_architecture $(TargetArchitecture) --build_config $(Configuration) --native_build_path $(NativeBuildOutputDirAbs) --packages_path $(OnnxRuntimePackagesDirectoryAbs) --ort_build_path $(OnnxRuntimeBuildDirectoryAbs) --sources_path $(OnnxRuntimeSourceDirectoryAbs) --commit_id $(GitCommitHash) --is_release_build $(IsReleaseBuild) --execution_provider $(ExecutionProvider)" ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="GenerateNuspecOutput" />
</Exec>
@ -120,6 +133,11 @@ CMake creates a target to this project
<Exec ContinueOnError="False" Command="$(NugetExe) pack NativeNuget.nuspec" ConsoleToMSBuild="true" WorkingDirectory="$(NativeBuildOutputDirAbs)">
<Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
</Exec>
<Copy
SourceFiles="$(NativeBuildOutputDirAbs)\$(OrtPackageId).$(PackageVersion).nupkg"
DestinationFolder="$(NativeBuildOutputDirAbs)\nuget-artifacts"
/>
</Target>
<ItemGroup>

View file

@ -5,17 +5,32 @@
<TargetFramework>netcoreapp2.1</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
<OnnxRuntimeCsharpRoot>..\..</OnnxRuntimeCsharpRoot>
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
<Configurations>Debug;Release;RelWithDebInfo</Configurations>
<IsLinuxBuild Condition="'$(IsLinuxBuild)' == ''">false</IsLinuxBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='true'">
<!--internal build related properties for Linux -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Linux</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='false'">
<!--internal build related properties for Windows -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<ItemGroup>
<None Include="$(NativeBuildOutputDir)\onnxruntime.dll">
<None Include="$(NativeBuildOutputDir)\libonnxruntime.so" Condition="'$(IsLinuxBuild)'=='true'">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\onnxruntime.pdb" Condition="Exists('$(NativeBuildOutputDir)\onnxruntime.pdb')">
<None Include="$(NativeBuildOutputDir)\onnxruntime.dll" Condition="'$(IsLinuxBuild)'=='false'">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\onnxruntime.pdb" Condition="'$(IsLinuxBuild)'=='false'And Exists('$(NativeBuildOutputDir)\onnxruntime.pdb')">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
@ -23,10 +38,22 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\libdnnl.so.1" Condition="Exists('$(NativeBuildOutputDir)\libdnnl.so.1')">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\mklml.dll" Condition="Exists('$(NativeBuildOutputDir)\mklml.dll')">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\libmklml_intel.so" Condition="Exists('$(NativeBuildOutputDir)\libmklml_intel.so')">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\libmklml_gnu.so" Condition="Exists('$(NativeBuildOutputDir)\libmklml_gnu.so')">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(OnnxRuntimeCSharpRoot)\testdata\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>

View file

@ -12,8 +12,6 @@
<!--internal build related properties-->
<OnnxRuntimeRoot>..\..\..</OnnxRuntimeRoot>
<OnnxRuntimeCsharpRoot>$(OnnxRuntimeRoot)\csharp</OnnxRuntimeCsharpRoot>
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
<TargetArchitecture Condition=" '$(TargetArchitecture)' == '' ">x64</TargetArchitecture>
<!--- packaging properties -->
@ -45,6 +43,18 @@
<Configurations>Debug;Release;RelWithDebInfo</Configurations>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='true'">
<!--internal build related properties for Linux -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Linux</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='false'">
<!--internal build related properties for Windows -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<!--TODO: this works for single platform only. Need separate packaging scripts for multi-target packaging -->
<!--TODO: Find a way to bundle the native symbol files properly -->
@ -75,13 +85,22 @@
CopyToOutputDirectory="Never"
Visible="false"
/>
<None Include="$(NativeBuildOutputDir)\libonnxruntime.so"
Condition="Exists('$(NativeBuildOutputDir)\libonnxruntime.so')"
PackagePath="\runtimes\linux-$(TargetArchitecture)\native"
Pack="false"
CopyToOutputDirectory="Never"
Visible="false"
/>
<None Include="$(NativeBuildOutputDir)\onnxruntime.lib"
Condition="Exists('$(NativeBuildOutputDir)\onnxruntime.lib')"
PackagePath="\runtimes\win-$(TargetArchitecture)\native"
Pack="false"
CopyToOutputDirectory="Never"
Visible="false"
/>
<None Include="$(NativeBuildOutputDir)\onnxruntime.dll"
Condition="Exists('$(NativeBuildOutputDir)\onnxruntime.dll')"
PackagePath="\runtimes\win-$(TargetArchitecture)\native"
Pack="false"
CopyToOutputDirectory="Always"
@ -171,13 +190,18 @@
<Target Name="CopyMiscFiles" BeforeTargets="Pack">
<Copy SourceFiles="@(LicenseFile)" DestinationFiles="@(LicenseFile->'$(OnnxRuntimeCsharpRoot)\..\%(Filename).txt')" />
<Copy SourceFiles="@(TargetsFile)" DestinationFiles="@(TargetsFile->'$(OnnxRuntimeCsharpRoot)\src\\Microsoft.ML.OnnxRuntime\$(PackageId).targets')" />
</Target>
<Target Name="CopyPackage" AfterTargets="Pack">
<Copy
SourceFiles="$(OutputPath)..\$(PackageId).$(PackageVersion).nupkg"
DestinationFolder="$(NativeBuildOutputDir)\nuget-artifacts"
/>
</Target>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="System.Memory" Version="4.5.3" />
</ItemGroup>
</Project>
</Project>

View file

@ -5,12 +5,22 @@
<OnnxRuntimeCsharpRoot>$(MSBuildThisFileDirectory)..\..</OnnxRuntimeCsharpRoot>
<Platform>AnyCPU</Platform>
<OutputPath>bin\$(Configuration)\</OutputPath>
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<ProtocDirectory>$(OnnxRuntimeBuildDirectory)\$(Configuration)\external\protobuf\cmake\$(Configuration)</ProtocDirectory>
<ProtoSrc>$(OnnxRuntimeCsharpRoot)\..\cmake\external\onnx\onnx</ProtoSrc>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
<PackageName Condition="'$(PackageName)' == ''">Microsoft.ML.OnnxRuntime</PackageName>
<IsLinuxBuild Condition="'$(IsLinuxBuild)' == ''">false</IsLinuxBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='true'">
<!--internal build related properties for Linux -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Linux</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='false'">
<!--internal build related properties for Windows -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.11.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
@ -22,10 +32,16 @@
<Compile Include="$(MSBuildThisFileDirectory)..\Microsoft.ML.OnnxRuntime.Tests\InferenceTest.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)..\Microsoft.ML.OnnxRuntime.Tests\OnnxMl.cs"/>
<!-- Works in CI builds-->
<None Include="$(OnnxRuntimeBuildDirectory)\testdata\testdata\custom_op*.dll;$(OnnxRuntimeBuildDirectory)\testdata\testdata\custom_op*.pdb;$(OnnxRuntimeBuildDirectory)\testdata\testdata\libcustom*.so;$(OnnxRuntimeBuildDirectory)\testdata\testdata\libcustom*.dylib">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<!-- Works for local builds-->
<None Include="$(NativeBuildOutputDir)\custom_op*.dll;$(NativeBuildOutputDir)\custom_op*.pdb;$(NativeBuildOutputDir)\libcustom*.so;$(NativeBuildOutputDir)\libcustom*.dylib">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(OnnxRuntimeCSharpRoot)\testdata\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
@ -37,7 +53,7 @@
<None Include="$(OnnxRuntimeCSharpRoot)\..\onnxruntime\test\testdata\capi_symbolic_dims.onnx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
</None>
<None Include="$(OnnxRuntimeCSharpRoot)\..\onnxruntime\test\testdata\custom_op_library\custom_op_test.onnx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>

View file

@ -6,10 +6,8 @@
<OnnxRuntimeCsharpRoot>..\..</OnnxRuntimeCsharpRoot>
<Platforms>AnyCPU;x86</Platforms>
<OutputPath>bin\$(Configuration)\</OutputPath>
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<ProtocDirectory Condition="'$(ProtocDirectory)'==''">$(OnnxRuntimeBuildDirectory)\$(Configuration)\external\protobuf\cmake\$(Configuration)</ProtocDirectory>
<IsLinuxBuild Condition="'$(IsLinuxBuild)' == ''">false</IsLinuxBuild>
<ProtoSrc>$(OnnxRuntimeCsharpRoot)\..\onnxruntime\core\protobuf</ProtoSrc>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
<!-- following attributes were necessary for the migrated Tensor tests -->
<LangVersion>7.2</LangVersion>
@ -21,6 +19,22 @@
<!-- end -->
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='true'">
<!--internal build related properties for Linux -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Linux</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)</NativeBuildOutputDir>
<ProtocDirectory Condition="'$(ProtocDirectory)'==''">$(OnnxRuntimeBuildDirectory)\$(Configuration)\external\protobuf\cmake</ProtocDirectory>
<ProtocExe>$(ProtocDirectory)\protoc</ProtocExe>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='false'">
<!--internal build related properties for Windows -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
<ProtocDirectory Condition="'$(ProtocDirectory)'==''">$(OnnxRuntimeBuildDirectory)\$(Configuration)\external\protobuf\cmake\$(Configuration)</ProtocDirectory>
<ProtocExe>$(ProtocDirectory)\protoc.exe</ProtocExe>
</PropertyGroup>
<ItemGroup>
<Compile Update="Tensors\TensorArithmetic.cs">
<AutoGen>True</AutoGen>
@ -59,7 +73,7 @@
</ItemGroup>
<Target Name="ProtoGen" BeforeTargets="Build">
<Exec Command="$(ProtocDirectory)\protoc.exe -I=$(ProtoSrc) --csharp_out=. $(ProtoSrc)\onnx-ml.proto3" ContinueOnError="false"></Exec>
<Exec Command="$(ProtocExe) -I=$(ProtoSrc) --csharp_out=. $(ProtoSrc)\onnx-ml.proto3" ContinueOnError="false"></Exec>
</Target>
<ItemGroup>

View file

@ -5,18 +5,33 @@
<Platforms>AnyCPU;x86</Platforms>
<TargetFramework>netcoreapp2.1</TargetFramework>
<OnnxRuntimeCsharpRoot>..\..</OnnxRuntimeCsharpRoot>
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
<SignAssembly>false</SignAssembly>
<Configurations>Debug;Release;RelWithDebInfo</Configurations>
<IsLinuxBuild Condition="'$(IsLinuxBuild)' == ''">false</IsLinuxBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='true'">
<!--internal build related properties for Linux -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Linux</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinuxBuild)'=='false'">
<!--internal build related properties for Windows -->
<OnnxRuntimeBuildDirectory Condition="'$(OnnxRuntimeBuildDirectory)'==''">$(OnnxRuntimeCsharpRoot)\..\build\Windows</OnnxRuntimeBuildDirectory>
<NativeBuildOutputDir>$(OnnxRuntimeBuildDirectory)\$(Configuration)\$(Configuration)</NativeBuildOutputDir>
</PropertyGroup>
<ItemGroup>
<None Include="$(NativeBuildOutputDir)\onnxruntime.dll">
<None Include="$(NativeBuildOutputDir)\libonnxruntime.so" Condition="'$(IsLinuxBuild)'=='true'">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\onnxruntime.pdb" Condition="Exists('$(NativeBuildOutputDir)\onnxruntime.pdb')">
<None Include="$(NativeBuildOutputDir)\onnxruntime.dll" Condition="'$(IsLinuxBuild)'=='false'">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\onnxruntime.pdb" Condition="'$(IsLinuxBuild)'=='false'And Exists('$(NativeBuildOutputDir)\onnxruntime.pdb')">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
@ -24,6 +39,10 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(NativeBuildOutputDir)\libdnnl.so.1" Condition="Exists('$(NativeBuildOutputDir)\libdnnl.so.1')">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
<None Include="$(OnnxRuntimeCSharpRoot)\testdata\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>

View file

@ -149,7 +149,13 @@ def parse_arguments():
# C-Sharp bindings
parser.add_argument(
"--build_csharp", action='store_true',
help="Build C#.Net DLL and NuGet package")
help="Build C#.Net DLL and NuGet package. This should be only used in CI pipelines. "
"For building C# bindings and packaging them into nuget package use --build_nuget arg.")
parser.add_argument(
"--build_nuget", action='store_true',
help="Build C#.Net DLL and NuGet package on the local machine. "
"Currently only Windows and Linux platforms are supported.")
# Java bindings
parser.add_argument(
@ -375,6 +381,10 @@ def is_macOS():
return sys.platform.startswith("darwin")
def is_linux():
return sys.platform.startswith("linux")
def get_linux_distro():
try:
with open('/etc/os-release', 'r') as f:
@ -1388,6 +1398,93 @@ def build_python_wheel(
run_subprocess(args, cwd=cwd)
def derive_linux_build_property():
if is_windows():
return "/p:IsLinuxBuild=\"false\""
else:
return "/p:IsLinuxBuild=\"true\""
def build_nuget_package(configs, use_cuda, use_openvino, use_tensorrt, use_dnnl, use_mklml):
if not (is_windows() or is_linux()):
raise BuildError(
'Currently csharp builds and nuget package creation is only supportted '
'on Windows and Linux platforms.')
build_dir = os.path.join(os.getcwd(), 'csharp')
is_linux_build = derive_linux_build_property()
# derive package name and execution provider based on the build args
execution_provider = "/p:ExecutionProvider=\"None\""
package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime\""
if use_openvino:
execution_provider = "/p:ExecutionProvider=\"openvino\""
package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.OpenVino\""
elif use_tensorrt:
execution_provider = "/p:ExecutionProvider=\"tensorrt\""
package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.TensorRT\""
elif use_dnnl:
execution_provider = "/p:ExecutionProvider=\"dnnl\""
package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.DNNL\""
elif use_cuda:
package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.Gpu\""
elif use_mklml:
package_name = "/p:OrtPackageId=\"Microsoft.ML.OnnxRuntime.MKLML\""
else:
pass
# dotnet restore
cmd_args = ["dotnet", "restore", "OnnxRuntime.CSharp.sln", "--configfile", "Nuget.CSharp.config"]
run_subprocess(cmd_args, cwd=build_dir)
# build csharp bindings and create nuget package for each config
for config in configs:
if is_linux():
native_build_dir = os.path.join(os.getcwd(), 'build//Linux//', config)
cmd_args = ["make", "install", "DESTDIR=.//nuget-staging"]
run_subprocess(cmd_args, cwd=native_build_dir)
configuration = "/p:Configuration=\"" + config + "\""
cmd_args = ["dotnet", "msbuild", "OnnxRuntime.CSharp.sln", configuration, package_name, is_linux_build]
run_subprocess(cmd_args, cwd=build_dir)
cmd_args = [
"dotnet", "msbuild", "OnnxRuntime.CSharp.proj", "/t:CreatePackage",
package_name, configuration, execution_provider, is_linux_build]
run_subprocess(cmd_args, cwd=build_dir)
def run_csharp_tests(use_cuda, use_openvino, use_tensorrt, use_dnnl):
# Currently only running tests on windows.
if not is_windows():
return
build_dir = os.path.join(os.getcwd(), 'csharp')
is_linux_build = derive_linux_build_property()
# define macros based on build args
macros = ""
if use_openvino:
macros += "USE_OPENVINO;"
if use_tensorrt:
macros += "USE_TENSORRT;"
if use_dnnl:
macros += "USE_DNNL;"
if use_cuda:
macros += "USE_CUDA;"
define_constants = ""
if macros != "":
define_constants = "/p:DefineConstants=\"" + macros + "\""
# Skip pretrained models test. Only run unit tests as part of the build
# "/property:DefineConstants=\"USE_CUDA;USE_OPENVINO\"",
cmd_args = ["dotnet", "test", "test\\Microsoft.ML.OnnxRuntime.Tests\\Microsoft.ML.OnnxRuntime.Tests.csproj",
"--filter", "FullyQualifiedName!=Microsoft.ML.OnnxRuntime.Tests.InferenceTest.TestPreTrainedModels",
is_linux_build, define_constants, "--verbosity", "detailed"]
run_subprocess(cmd_args, cwd=build_dir)
def build_protoc_for_host(cmake_path, source_dir, build_dir, args):
if (args.arm or args.arm64) and (not is_windows() and not args.ios):
raise BuildError(
@ -1531,9 +1628,13 @@ def main():
if args.build_wheel or args.gen_doc:
args.enable_pybind = True
if args.build_csharp or args.build_java or args.build_nodejs:
if args.build_csharp or args.build_nuget or args.build_java or args.build_nodejs:
args.build_shared_lib = True
if args.build_nuget and cross_compiling:
raise BuildError(
'Currently nuget package creation is not supported while cross-compiling')
# Disabling unit tests for VAD-F as FPGA only supports
# models with NCHW layout
if args.use_openvino == "VAD-F_FP32":
@ -1695,6 +1796,22 @@ def main():
featurizers_build=args.use_featurizers,
use_ninja=(args.cmake_generator == 'Ninja')
)
if args.build_nuget:
build_nuget_package(
configs,
args.use_cuda,
args.use_openvino,
args.use_tensorrt,
args.use_dnnl,
args.use_mklml
)
if args.test and args.build_nuget:
run_csharp_tests(
args.use_cuda,
args.use_openvino,
args.use_tensorrt,
args.use_dnnl)
if args.gen_doc and (args.build or args.test):
generate_documentation(source_dir, build_dir, configs)

View file

@ -22,9 +22,9 @@ def parse_arguments():
parser.add_argument("--commit_id", required=True, help="The last commit id included in this package.")
parser.add_argument("--is_release_build", required=False, default=None, type=str,
help="Flag indicating if the build is a release build. Accepted values: true/false.")
parser.add_argument("--is_linux_build", required=False, default='false', type=str,
help="Flag indicating if we are building a Nuget for Linux. This will look for " +
"`libonnxruntime.so`. Accepted values: true/false.")
parser.add_argument("--execution_provider", required=False, default='None', type=str,
choices=['dnnl', 'openvino', 'tensorrt', 'None'],
help="The selected execution provider for this build.")
return parser.parse_args()
@ -163,7 +163,6 @@ def generate_files(list, args):
is_cpu_package = args.package_name == 'Microsoft.ML.OnnxRuntime'
is_mklml_package = args.package_name == 'Microsoft.ML.OnnxRuntime.MKLML'
is_cuda_gpu_package = args.package_name == 'Microsoft.ML.OnnxRuntime.Gpu'
is_openvino_package = args.package_name == 'Microsoft.ML.OnnxRuntime.Openvino'
is_dml_package = args.package_name == 'Microsoft.ML.OnnxRuntime.DirectML'
is_windowsai_package = args.package_name == 'Microsoft.AI.MachineLearning'
@ -171,7 +170,38 @@ def generate_files(list, args):
includes_winml = is_windowsai_package
includes_directml = (is_dml_package or is_windowsai_package) and (args.target_architecture == 'x64'
or args.target_architecture == 'x86')
includes_openvino = is_openvino_package
is_windows_build = is_windows()
nuget_dependencies = {}
if is_windows_build:
nuget_dependencies = {'mklml': 'mklml.dll',
'openmp': 'libiomp5md.dll',
'dnnl': 'dnnl.dll',
'tvm': 'tvm.dll',
'providers_shared_lib': 'onnxruntime_providers_shared.dll',
'dnnl_ep_shared_lib': 'onnxruntime_providers_dnnl.dll',
'tensorrt_ep_shared_lib': 'onnxruntime_providers_tensorrt.dll',
'onnxruntime_perf_test': 'onnxruntime_perf_test.exe',
'onnx_test_runner': 'onnx_test_runner.exe'}
copy_command = "copy"
runtimes_target = '" target="runtimes\\win-'
else:
nuget_dependencies = {'mklml': 'libmklml_intel.so',
'mklml_1': 'libmklml_gnu.so',
'openmp': 'libiomp5.so',
'dnnl': 'libdnnl.so.1',
'tvm': 'libtvm.so.0.5.1',
'providers_shared_lib': 'libonnxruntime_providers_shared.so',
'dnnl_ep_shared_lib': 'libonnxruntime_providers_dnnl.so',
'tensorrt_ep_shared_lib': 'libonnxruntime_providers_tensorrt.so',
'onnxruntime_perf_test': 'onnxruntime_perf_test',
'onnx_test_runner': 'onnx_test_runner'}
copy_command = "cp"
runtimes_target = '" target="runtimes\\linux-'
# Process headers
files_list.append('<file src=' + '"' + os.path.join(args.sources_path,
@ -188,12 +218,24 @@ def generate_files(list, args):
'include\\onnxruntime\\core\\providers\\cuda\\cuda_provider_factory.h') +
'" target="build\\native\\include" />')
if includes_openvino:
if args.execution_provider == 'openvino':
files_list.append('<file src=' + '"' +
os.path.join(args.sources_path,
'include\\onnxruntime\\core\\providers\\openvino\\openvino_provider_factory.h') +
'" target="build\\native\\include" />')
if args.execution_provider == 'tensorrt':
files_list.append('<file src=' + '"' +
os.path.join(args.sources_path,
'include\\onnxruntime\\core\\providers\\tensorrt\\tensorrt_provider_factory.h') +
'" target="build\\native\\include" />')
if args.execution_provider == 'dnnl':
files_list.append('<file src=' + '"' +
os.path.join(args.sources_path,
'include\\onnxruntime\\core\\providers\\dnnl\\dnnl_provider_factory.h') +
'" target="build\\native\\include" />')
if includes_directml:
files_list.append('<file src=' + '"' +
os.path.join(args.sources_path,
@ -227,18 +269,19 @@ def generate_files(list, args):
'" target="lib\\netstandard2.0\\Microsoft.AI.MachineLearning.Interop.pdb" />')
# Process runtimes
# Process linux
if args.is_linux_build.lower() == 'true':
files_list.append('<file src=' + '"' + os.path.join(args.sources_path, 'libonnxruntime.so') +
'" target="runtimes\\linux-' + args.target_architecture + '\\native" />')
# Process onnxruntime import lib, dll, and pdb
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnxruntime.lib') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnxruntime.dll') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnxruntime.pdb') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
if is_windows_build:
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnxruntime.lib') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnxruntime.dll') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
if os.path.exists(os.path.join(args.native_build_path, 'onnxruntime.pdb')):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnxruntime.pdb') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
else:
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'nuget-staging/usr/local/lib',
'libonnxruntime.so') + '" target="runtimes\\linux-' + args.target_architecture +
'\\native" />')
if includes_directml:
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'DirectML.dll') +
@ -262,39 +305,62 @@ def generate_files(list, args):
'microsoft.ai.machinelearning.pdb') +
'" target="runtimes\\win-' + args.target_architecture +
'\\native\\Microsoft.AI.MachineLearning.pdb" />')
# Process execution providers which are built as shared libs
if args.execution_provider == "tensorrt":
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path,
nuget_dependencies['providers_shared_lib']) +
runtimes_target + args.target_architecture + '\\native" />')
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path,
nuget_dependencies['tensorrt_ep_shared_lib']) +
runtimes_target + args.target_architecture + '\\native" />')
if args.execution_provider == "dnnl":
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path,
nuget_dependencies['providers_shared_lib']) +
runtimes_target + args.target_architecture + '\\native" />')
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path,
nuget_dependencies['dnnl_ep_shared_lib']) +
runtimes_target + args.target_architecture + '\\native" />')
# process all other library dependencies
if is_cpu_package or is_cuda_gpu_package or is_dml_package or is_mklml_package:
# Process dnll.dll
if os.path.exists(os.path.join(args.native_build_path, 'dnnl.dll')):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'dnnl.dll') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
# Process dnnl dependency
if os.path.exists(os.path.join(args.native_build_path, nuget_dependencies['dnnl'])):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, nuget_dependencies['dnnl']) +
runtimes_target + args.target_architecture + '\\native" />')
# Process mklml.dll
if os.path.exists(os.path.join(args.native_build_path, 'mklml.dll')):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'mklml.dll') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
# Process mklml dependency
if os.path.exists(os.path.join(args.native_build_path, nuget_dependencies['mklml'])):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, nuget_dependencies['mklml']) +
runtimes_target + args.target_architecture + '\\native" />')
# Process libiomp5md.dll
if os.path.exists(os.path.join(args.native_build_path, 'libiomp5md.dll')):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'libiomp5md.dll') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
if is_linux() and os.path.exists(os.path.join(args.native_build_path, nuget_dependencies['mklml_1'])):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, nuget_dependencies['mklml_1']) +
runtimes_target + args.target_architecture + '\\native" />')
# Process tvm.dll
if os.path.exists(os.path.join(args.native_build_path, 'tvm.dll')):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'tvm.dll') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
# Process libiomp5md dependency
if os.path.exists(os.path.join(args.native_build_path, nuget_dependencies['openmp'])):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, nuget_dependencies['openmp']) +
runtimes_target + args.target_architecture + '\\native" />')
# Process tvm dependency
if os.path.exists(os.path.join(args.native_build_path, nuget_dependencies['tvm'])):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, nuget_dependencies['tvm']) +
runtimes_target + args.target_architecture + '\\native" />')
# Some tools to be packaged in nightly build only, should not be released
# These are copied to the runtimes folder for convenience of loading with the dlls
if args.is_release_build.lower() != 'true' and args.target_architecture == 'x64' and \
os.path.exists(os.path.join(args.native_build_path, 'onnxruntime_perf_test.exe')):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnxruntime_perf_test.exe') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
os.path.exists(os.path.join(args.native_build_path, nuget_dependencies['onnxruntime_perf_test'])):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path,
nuget_dependencies['onnxruntime_perf_test']) +
runtimes_target + args.target_architecture + '\\native" />')
if args.is_release_build.lower() != 'true' and args.target_architecture == 'x64' and \
os.path.exists(os.path.join(args.native_build_path, 'onnx_test_runner.exe')):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path, 'onnx_test_runner.exe') +
'" target="runtimes\\win-' + args.target_architecture + '\\native" />')
os.path.exists(os.path.join(args.native_build_path, nuget_dependencies['onnx_test_runner'])):
files_list.append('<file src=' + '"' + os.path.join(args.native_build_path,
nuget_dependencies['onnx_test_runner']) +
runtimes_target + args.target_architecture + '\\native" />')
# Process props and targets files
if is_windowsai_package:
@ -322,7 +388,7 @@ def generate_files(list, args):
source_props = os.path.join(args.sources_path, 'csharp', 'src', 'Microsoft.ML.OnnxRuntime', 'props.xml')
target_props = os.path.join(args.sources_path, 'csharp', 'src', 'Microsoft.ML.OnnxRuntime',
args.package_name + '.props')
os.system('copy ' + source_props + ' ' + target_props)
os.system(copy_command + ' ' + source_props + ' ' + target_props)
files_list.append('<file src=' + '"' + target_props + '" target="build\\native" />')
files_list.append('<file src=' + '"' + target_props + '" target="build\\netstandard1.1" />')
@ -330,7 +396,7 @@ def generate_files(list, args):
source_targets = os.path.join(args.sources_path, 'csharp', 'src', 'Microsoft.ML.OnnxRuntime', 'targets.xml')
target_targets = os.path.join(args.sources_path, 'csharp', 'src', 'Microsoft.ML.OnnxRuntime',
args.package_name + '.targets')
os.system('copy ' + source_targets + ' ' + target_targets)
os.system(copy_command + ' ' + source_targets + ' ' + target_targets)
files_list.append('<file src=' + '"' + target_targets + '" target="build\\native" />')
files_list.append('<file src=' + '"' + target_targets + '" target="build\\netstandard1.1" />')
@ -361,12 +427,31 @@ def is_windows():
return sys.platform.startswith("win")
def main():
if not is_windows():
raise Exception('Native Nuget generation is currently supported only on Windows')
def is_linux():
return sys.platform.startswith("linux")
def validate_platform():
if not(is_windows() or is_linux()):
raise Exception('Native Nuget generation is currently supported only on Windows and Linux')
def validate_execution_provider(execution_provider):
if is_linux():
if not (execution_provider == 'None' or execution_provider == 'dnnl'
or execution_provider == 'tensorrt' or execution_provider == 'openvino'):
raise Exception('On Linux platform nuget generation is supported only '
'for cpu|cuda|dnnl|tensorrt|openvino execution providers.')
def main():
# Parse arguments
args = parse_arguments()
validate_platform()
validate_execution_provider(args.execution_provider)
if (args.is_release_build.lower() != 'true' and args.is_release_build.lower() != 'false'):
raise Exception('Only valid options for IsReleaseBuild are: true and false')