- Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
Introduction
This is the documentation page for the .NETStandard2.0 wrapper of OR-Tools.
Table of Content
Pre-requisites
The library is compiled against netstandard2.0, so you'll only need:
- .Net Core SDK >= 2.1.302
Directory Layout
Google.OrTools.runtime.linux-x64Contains the .Net Standard 2.0 native project for the rid linux-x64.Google.OrTools.runtime.osx-x64Contains the .Net Standard 2.0 native project for the rid osx-x64.Google.OrTools.runtime.win-x64Contains the .Net Standard 2.0 native project for the rid win-x64.Google.OrToolsIs the .Net Standard 2.0 meta-package which should depends on all previous available packages and contains the Reference Assembly.
Build
Either use the Makefile based build or you can build in Visual Studio.
The workflow is typically make dotnet which will build both C# and F# libraries package in debug mode.
The output will be placed in <OR_ROOT>/packages folder. All tests will be run based on this folder.
Build Process
To Create a native dependent package we will split it in two parts:
- A bunch of
Google.OrTools.runtime.{rid}.nupkgpackages for each Runtime Identifier (RId) targeted. - A meta-package
Google.OrTools.nupkgdepending on each runtime packages.
note: Microsoft.NetCore.App packages
follow this layout.
We have two use case scenario:
-
Locally, be able to build a Google.OrTools package which only target the local
OS Platform, i.e. building for only one Runtime Identifier (RID).
note: This is usefull since the C++ build is a complex process for Windows, Linux and MacOS.
i.e. We don't support cross-compilation for the native library generation. -
Be able to create a complete cross-platform (ed. platform as multiple rid) Google.OrTools package.
i.e. First you generate each native Nuget package (Google.OrTools.runtime.{rid}.nupkg) on each native architecture, then copy paste these artifacts on one native machine to generate the meta-packageGoogle.OrTools.
Local Google.OrTools Package
Let's start with scenario 1: Create a Local Google.OrTools package targeting one
Runtime Identifier (RID).
We would like to build a Google.OrTools.nupkg package which only depends on one
Google.OrTools.runtime.{rid}.nupkg in order to work locally.
The pipeline for linux-x64 should be as follow:
note: The pipeline will be similar for osx-x64 and win-x64 architecture, don't hesitate to look at the CI log.
Building local runtime Google.OrTools Package
disclaimer: We won't cover the C++ ortools library build.
So first let's create the local Google.OrTools.runtime.{rid}.nupkg nuget package.
Here some dev-note concerning this Google.OrTools.runtime.{rid}.csproj.
AssemblyNamemust beGoogle.OrTools.dlli.e. all {rid} projects must generate an assembly with the same name (i.e. no {rid} in the name). On the other hand package identifier will contain the {rid}...<RuntimeIdentifier>{rid}</RuntimeIdentifier> <AssemblyName>Google.OrTools</AssemblyName> <PackageId>Google.OrTools.runtime.{rid}</PackageId>- Once you specify a
RuntimeIdentifierthendotnet buildordotnet build -r {rid}will behave identically (save you from typing it).- note: not the case if you use
RuntimeIdentifiers(notice the 's')
- note: not the case if you use
- It is recommended
to add the tag
nativeto the nuget package tags<PackageTags>native</PackageTags> - Specify the output target folder for having the assembly output in
runtimes/{rid}/lib/netstandard2.0in the nupkgnote: Every files with an extension different from<BuildOutputTargetFolder>runtimes/$(RuntimeIdentifier)/lib</BuildOutputTargetFolder>.dllwill be filter out by nuget.
note: dotnet/cli automatically add the$(TargetFramework)(i.e.netstandard2.0) to the output path. - Add the native shared library to the nuget package in the repository
runtimes/{rib}/native. e.g. for linux-x64:<Content Include="*.so"> <PackagePath>runtimes/linux-x64/native/%(Filename)%(Extension)</PackagePath> <Pack>true</Pack> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - Generate the runtime package to a defined directory (i.e. so later in meta Google.OrTools package we will be able to locate it)
<PackageOutputPath>{...}/packages</PackageOutputPath> - Generate the Reference Assembly (but don't include it to this runtime nupkg !, see below for explanation) using:
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
Then you can generate the package using:
dotnet pack src/Google.OrTools.runtime.{rid}
note: this will automatically trigger the dotnet build.
If everything good the package (located where your PackageOutputPath was defined) should have this layout:
{...}/packages/Google.OrTools.runtime.{rid}.nupkg:
\- Google.OrTools.runtime.{rid}.nuspec
\- runtimes
\- {rid}
\- lib
\- netstandard2.0
\- Google.OrTools.dll
\- native
\- *.so / *.dylib / *.dll
...
note: {rid} could be linux-x64
tips: since nuget package are zip archive you can use unzip -l <package>.nupkg to study their layout.
Building local Google.OrTools Package
So now, let's create the local Google.OrTools.nupkg nuget package which will depend on our previous runtime package.
Here some dev-note concerning this Google.OrTools.csproj.
- This package is a meta-package so we don't want to ship an empty assembly file:
<IncludeBuildOutput>false</IncludeBuildOutput> - Add the previous package directory:
<RestoreSources>{...}/packages;$(RestoreSources)</RestoreSources> - Add dependency (i.e.
PackageReference) on each runtime package(s) availabe:Thanks to the<ItemGroup Condition="Exists('{...}/packages/Google.OrTools.runtime.linux-x64.1.0.0.nupkg')"> <PackageReference Include="Google.OrTools.runtime.linux-x64" Version="1.0.0" /> </ItemGroup>RestoreSourcewe can work locally with our just builded package without the need to upload it on nuget.org. - To expose the .Net Surface API the
Google.OrTools.csprojmust contains a least one Reference Assembly of the previously rumtime package.<Content Include="../Google.OrTools.runtime.{rid}/bin/$(Configuration)/$(TargetFramework)/{rid}/ref/*.dll"> <PackagePath>ref/$(TargetFramework)/%(Filename)%(Extension)</PackagePath> <Pack>true</Pack> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
Then you can generate the package using:
dotnet pack src/Google.OrTools
If everything good the package (located where your PackageOutputPath was defined) should have this layout:
{...}/packages/Google.OrTools.nupkg:
\- Google.OrTools.nuspec
\- ref
\- netstandard2.0
\- Google.OrTools.dll
...
Complete Google.OrTools Package
Let's start with scenario 2: Create a Complete Google.OrTools.nupkg package targeting multiple
Runtime Identifier (RID).
We would like to build a Google.OrTools.nupkg package which depends on several Google.OrTools.runtime.{rid}.nupkg.
The pipeline should be as follow:
note: This pipeline should be run on any architecture,
provided you have generated the three architecture dependent Google.OrTools.runtime.{rid}.nupkg nuget packages.
Building All runtime Google.OrTools Package
Like in the previous scenario, on each targeted OS Platform you can build the coresponding
Google.OrTools.runtime.{rid}.nupkg package.
Simply run on each platform
dotnet build src/Google.OrTools.runtime.{rid}
dotnet pack src/Google.OrTools.runtime.{rid}
note: replace {rid} by the Runtime Identifier associated to the current OS platform.
Then on one machine used, you copy all other packages in the {...}/packages so
when building Google.OrTools.csproj we can have access to all package...
Building Complete Google.OrTools Package
This is the same step than in the previous scenario, since we "see" all runtime
packages in {...}/packages, the project will depends on each of them.
Once copied all runtime package locally, simply run:
dotnet build src/Google.OrTools
dotnet pack src/Google.OrTools
Examples
The Test projects show examples of building applications with netcoreapp2.0.
The F# example folder shows how to compile against the typical .NET Framework installed on machine.
Appendices
Few links on the subject...
Ressources
Issues
Some issue related to this process
- Nuget needs to support dependencies specific to target runtime #1660
- Improve documentation on creating native packages #238
Misc
Image has been generated using plantuml:
plantuml -Tpng doc/{file}.dot
So you can find the dot source files in doc.