Merge pull request #150066 from ezemtsov/buildDotnetModule

buildDotnetModule: add support for local project references
This commit is contained in:
Luke Granger-Brown 2021-12-14 08:39:24 +00:00 committed by GitHub
commit 5abdc76f23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 3 deletions

View File

@ -73,6 +73,17 @@ To package Dotnet applications, you can use `buildDotnetModule`. This has simila
* `projectFile` has to be used for specifying the dotnet project file relative to the source root. These usually have `.sln` or `.csproj` file extensions. This can be an array of multiple projects as well.
* `nugetDeps` has to be used to specify the NuGet dependency file. Unfortunately, these cannot be deterministically fetched without a lockfile. This file should be generated using `nuget-to-nix` tool, which is available in nixpkgs.
* `packNupkg` is used to pack project as a `nupkg`, and installs it to `$out/share`. If set to `true`, the derivation can be used as a dependency for another dotnet project by adding it to `projectReferences`.
* `projectReferences` can be used to resolve `ProjectReference` project items. Referenced projects can be packed with `buildDotnetModule` by setting the `packNupkg = true` attribute and passing a list of derivations to `projectReferences`. Since we are sharing referenced projects as NuGets they must be added to csproj/fsproj files as `PackageReference` as well.
For example, your project has a local dependency:
```xml
<ProjectReference Include="../foo/bar.fsproj" />
```
To enable discovery through `projectReferences` you would need to add:
```xml
<ProjectReference Include="../foo/bar.fsproj" />
<PackageReference Include="bar" Version="*" Condition=" '$(ContinuousIntegrationBuild)'=='true' "/>
```
* `executables` is used to specify which executables get wrapped to `$out/bin`, relative to `$out/lib/$pname`. If this is unset, all executables generated will get installed. If you do not want to install any, set this to `[]`.
* `runtimeDeps` is used to wrap libraries into `LD_LIBRARY_PATH`. This is how dotnet usually handles runtime dependencies.
* `buildType` is used to change the type of build. Possible values are `Release`, `Debug`, etc. By default, this is set to `Release`.
@ -83,15 +94,18 @@ To package Dotnet applications, you can use `buildDotnetModule`. This has simila
* `disabledTests` is used to disable running specific unit tests. This gets passed as: `dotnet test --filter "FullyQualifiedName!={}"`, to ensure compatibility with all unit test frameworks.
* `dotnetRestoreFlags` can be used to pass flags to `dotnet restore`.
* `dotnetBuildFlags` can be used to pass flags to `dotnet build`.
* `dotnetTestFlags` can be used to pass flags to `dotnet test`.
* `dotnetTestFlags` can be used to pass flags to `dotnet test`. Used only if `doCheck` is set to `true`.
* `dotnetInstallFlags` can be used to pass flags to `dotnet install`.
* `dotnetPackFlags` can be used to pass flags to `dotnet pack`. Used only if `packNupkg` is set to `true`.
* `dotnetFlags` can be used to pass flags to all of the above phases.
Here is an example `default.nix`, using some of the previously discussed arguments:
```nix
{ lib, buildDotnetModule, dotnetCorePackages, ffmpeg }:
buildDotnetModule rec {
let
referencedProject = import ../../bar { ... };
in buildDotnetModule rec {
pname = "someDotnetApplication";
version = "0.1";
@ -99,6 +113,7 @@ buildDotnetModule rec {
projectFile = "src/project.sln";
nugetDeps = ./deps.nix; # File generated with `nuget-to-nix path/to/src > deps.nix`.
projectReferences = [ referencedProject ]; # `referencedProject` must contain `nupkg` in the folder structure.
dotnet-sdk = dotnetCorePackages.sdk_3_1;
dotnet-runtime = dotnetCorePackages.net_5_0;
@ -107,6 +122,8 @@ buildDotnetModule rec {
executables = [ "foo" ]; # This wraps "$out/lib/$pname/foo" to `$out/bin/foo`.
executables = []; # Don't install any executables.
packNupkg = true; # This packs the project as "foo-0.1.nupkg" at `$out/share`.
runtimeDeps = [ ffmpeg ]; # This will wrap ffmpeg's library path into `LD_LIBRARY_PATH`.
}
```

View File

@ -14,6 +14,8 @@
, dotnetTestFlags ? []
# Flags to pass to `dotnet install`.
, dotnetInstallFlags ? []
# Flags to pass to `dotnet pack`.
, dotnetPackFlags ? []
# Flags to pass to dotnet in all phases.
, dotnetFlags ? []
@ -21,11 +23,22 @@
# Unfortunately, dotnet has no method for doing this automatically.
# If unset, all executables in the projects root will get installed. This may cause bloat!
, executables ? null
# Packs a project as a `nupkg`, and installs it to `$out/share`. If set to `true`, the derivation can be used as a dependency for another dotnet project by adding it to `projectReferences`.
, packNupkg ? false
# The packages project file, which contains instructions on how to compile it. This can be an array of multiple project files as well.
, projectFile ? null
# The NuGet dependency file. This locks all NuGet dependency versions, as otherwise they cannot be deterministically fetched.
# This can be generated using the `nuget-to-nix` tool.
, nugetDeps ? null
# A list of derivations containing nupkg packages for local project references.
# Referenced derivations can be built with `buildDotnetModule` with `packNupkg=true` flag.
# Since we are sharing them as nugets they must be added to csproj/fsproj files as `PackageReference` as well.
# For example, your project has a local dependency:
# <ProjectReference Include="../foo/bar.fsproj" />
# To enable discovery through `projectReferences` you would need to add a line:
# <ProjectReference Include="../foo/bar.fsproj" />
# <PackageReference Include="bar" Version="*" Condition=" '$(ContinuousIntegrationBuild)'=='true' "/>
, projectReferences ? []
# Libraries that need to be available at runtime should be passed through this.
# These get wrapped into `LD_LIBRARY_PATH`.
, runtimeDeps ? []
@ -60,6 +73,7 @@ let
inherit sha256;
};
});
_localDeps = linkFarmFromDrvs "${name}-local-nuget-deps" projectReferences;
nuget-source = stdenvNoCC.mkDerivation rec {
name = "${args.pname}-nuget-source";
@ -72,6 +86,8 @@ let
nuget sources Add -Name nixos -Source "$out/lib"
nuget init "${_nugetDeps}" "$out/lib"
${lib.optionalString (projectReferences != [])
"nuget init \"${_localDeps}\" \"$out/lib\""}
# Generates a list of all unique licenses' spdx ids.
find "$out/lib" -name "*.nuspec" -exec sh -c \
@ -167,7 +183,18 @@ let
"''${dotnetInstallFlags[@]}" \
"''${dotnetFlags[@]}"
done
'' + (if executables != null then ''
'' + (lib.optionalString packNupkg ''
for project in ''${projectFile[@]}; do
dotnet pack "$project" \
-p:ContinuousIntegrationBuild=true \
-p:Deterministic=true \
--output $out/share \
--configuration "$buildType" \
--no-build \
"''${dotnetPackFlags[@]}" \
"''${dotnetFlags[@]}"
done
'') + (if executables != null then ''
for executable in $executables; do
execPath="$out/lib/${args.pname}/$executable"