2024-08-01 12:58:28 +00:00
{
lib ,
runtimeShell ,
stdenvNoCC ,
callPackage ,
substituteAll ,
writeShellScript ,
makeWrapper ,
dotnetCorePackages ,
cacert ,
2024-09-08 01:36:21 +00:00
addNuGetDeps ,
2024-10-29 02:34:35 +00:00
dotnet-sdk ,
2022-08-18 21:24:38 +00:00
} :
2024-08-01 00:18:03 +00:00
let
2024-10-29 02:34:35 +00:00
default-sdk = dotnet-sdk ;
2024-08-01 00:18:03 +00:00
transformArgs =
finalAttrs :
{
enableParallelBuilding ? true ,
# Flags to pass to `makeWrapper`. This is done to avoid double wrapping.
makeWrapperArgs ? [ ] ,
2021-07-26 22:46:18 +00:00
2024-08-01 00:18:03 +00:00
# Flags to pass to `dotnet restore`.
dotnetRestoreFlags ? [ ] ,
# Flags to pass to `dotnet build`.
dotnetBuildFlags ? [ ] ,
# Flags to pass to `dotnet test`, if running tests is enabled.
dotnetTestFlags ? [ ] ,
# Flags to pass to `dotnet install`.
dotnetInstallFlags ? [ ] ,
# Flags to pass to `dotnet pack`.
dotnetPackFlags ? [ ] ,
# Flags to pass to dotnet in all phases.
dotnetFlags ? [ ] ,
2021-07-26 22:46:18 +00:00
2024-08-01 00:18:03 +00:00
# The path to publish the project to. When unset, the directory "$out/lib/$pname" is used.
installPath ? null ,
# The binaries that should get installed to `$out/bin`, relative to `$installPath/`. These get wrapped accordingly.
# 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 by running the `passthru.fetch-deps` script.
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 ? [ ] ,
# The dotnet runtime ID. If null, fetch-deps will gather dependencies for all
# platforms in meta.platforms which are supported by the sdk.
runtimeId ? null ,
2021-07-26 22:46:18 +00:00
2024-08-22 16:05:19 +00:00
# Test filters. This gets passed to `dotnet test --filter`, concatenated using `&`.
# You may also use `disabledTests` to filter tests based on their name.
# See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test#filter-option-details for more details.
testFilters ? [ ] ,
2024-08-01 00:18:03 +00:00
# Tests to disable. This gets passed to `dotnet test --filter "FullyQualifiedName!={}"`, to ensure compatibility with all frameworks.
2024-08-22 16:05:19 +00:00
# You may also use `testFilters` to pass more generic filters to `dotnet test --filter`.
2024-08-01 00:18:03 +00:00
# See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test#filter-option-details for more details.
disabledTests ? [ ] ,
# The project file to run unit tests against. This is usually referenced in the regular project file, but sometimes it needs to be manually set.
# It gets restored and build, but not installed. You may need to regenerate your nuget lockfile after setting this.
testProjectFile ? null ,
2024-06-15 19:53:16 +00:00
2024-08-01 00:18:03 +00:00
# The type of build to perform. This is passed to `dotnet` with the `--configuration` flag. Possible values are `Release`, `Debug`, etc.
buildType ? " R e l e a s e " ,
# If set to true, builds the application as a self-contained - removing the runtime dependency on dotnet
selfContainedBuild ? false ,
# Whether to use an alternative wrapper, that executes the application DLL using the dotnet runtime from the user environment. `dotnet-runtime` is provided as a default in case no .NET is installed
# This is useful for .NET tools and applications that may need to run under different .NET runtimes
useDotnetFromEnv ? false ,
# Whether to explicitly enable UseAppHost when building. This is redundant if useDotnetFromEnv is enabled
useAppHost ? true ,
# The dotnet SDK to use.
2024-10-29 02:34:35 +00:00
dotnet-sdk ? default-sdk ,
2024-08-01 00:18:03 +00:00
# The dotnet runtime to use.
2024-10-29 02:34:35 +00:00
dotnet-runtime ? dotnet-sdk . runtime ,
2024-08-01 00:18:03 +00:00
. . .
} @ args :
let
projectFiles = lib . optionals ( projectFile != null ) ( lib . toList projectFile ) ;
testProjectFiles = lib . optionals ( testProjectFile != null ) ( lib . toList testProjectFile ) ;
platforms =
if args ? meta . platforms then
lib . intersectLists args . meta . platforms dotnet-sdk . meta . platforms
else
dotnet-sdk . meta . platforms ;
inherit ( callPackage ./hooks { inherit dotnet-sdk dotnet-runtime ; } )
dotnetConfigureHook
dotnetBuildHook
dotnetCheckHook
dotnetInstallHook
dotnetFixupHook
;
inherit ( dotnetCorePackages ) systemToDotnetRid ;
in
2024-09-08 01:36:21 +00:00
args
2024-08-01 00:18:03 +00:00
// {
dotnetInstallPath = installPath ;
dotnetExecutables = executables ;
dotnetBuildType = buildType ;
dotnetProjectFiles = projectFiles ;
dotnetTestProjectFiles = testProjectFiles ;
2024-08-22 16:05:19 +00:00
dotnetTestFilters = testFilters ;
2024-08-01 00:18:03 +00:00
dotnetDisabledTests = disabledTests ;
dotnetRuntimeIds = lib . singleton (
if runtimeId != null then runtimeId else systemToDotnetRid stdenvNoCC . hostPlatform . system
) ;
dotnetRuntimeDeps = map lib . getLib runtimeDeps ;
dotnetSelfContainedBuild = selfContainedBuild ;
dotnetUseAppHost = useAppHost ;
2024-09-04 01:49:22 +00:00
inherit
enableParallelBuilding
dotnetRestoreFlags
dotnetBuildFlags
dotnetTestFlags
dotnetInstallFlags
dotnetPackFlags
dotnetFlags
packNupkg
useDotnetFromEnv
2024-09-08 01:36:21 +00:00
nugetDeps
runtimeId
2024-09-21 01:08:12 +00:00
dotnet-sdk
2024-09-04 01:49:22 +00:00
;
2024-09-03 19:57:51 +00:00
2024-08-01 00:18:03 +00:00
nativeBuildInputs = args . nativeBuildInputs or [ ] ++ [
dotnetConfigureHook
dotnetBuildHook
dotnetCheckHook
dotnetInstallHook
dotnetFixupHook
cacert
makeWrapper
dotnet-sdk
] ;
2024-09-21 01:08:12 +00:00
buildInputs = args . buildInputs or [ ] ++ dotnet-sdk . packages ++ projectReferences ;
2024-08-01 00:18:03 +00:00
# Parse the version attr into a format acceptable for the Version msbuild property
# The actual version attr is saved in InformationalVersion, which accepts an arbitrary string
versionForDotnet =
if ! ( lib . hasAttr " v e r s i o n " args ) || args . version == null then
2024-08-01 12:58:28 +00:00
null
else
let
2024-08-01 00:18:03 +00:00
components = lib . pipe args . version [
lib . splitVersion
( lib . filter ( x : ( lib . strings . match " [ 0 - 9 ] + " x ) != null ) )
( lib . filter ( x : ( lib . toIntBase10 x ) < 65535 ) ) # one version component in dotnet has to fit in 16 bits
] ;
in
if ( lib . length components ) == 0 then
null
else
lib . concatStringsSep " . " (
( lib . take 4 components )
++ ( if ( lib . length components ) < 4 then lib . replicate ( 4 - ( lib . length components ) ) " 0 " else [ ] )
2024-08-01 12:58:28 +00:00
) ;
2024-08-01 00:18:03 +00:00
makeWrapperArgs = args . makeWrapperArgs or [ ] ++ [
" - - p r e f i x "
" L D _ L I B R A R Y _ P A T H "
" : "
" ${ dotnet-sdk . icu } / l i b "
] ;
2024-08-01 12:58:28 +00:00
2024-08-01 00:18:03 +00:00
# Stripping breaks the executable
dontStrip = args . dontStrip or true ;
# gappsWrapperArgs gets included when wrapping for dotnet, as to avoid double wrapping
dontWrapGApps = args . dontWrapGApps or true ;
# propagate the runtime sandbox profile since the contents apply to published
# executables
2024-10-27 16:40:31 +00:00
propagatedSandboxProfile = lib . optionalString ( dotnet-runtime != null ) (
toString dotnet-runtime . __propagatedSandboxProfile
) ;
2024-08-01 00:18:03 +00:00
meta = ( args . meta or { } ) // {
inherit platforms ;
} ;
2024-08-01 12:58:28 +00:00
} ;
2024-09-08 01:36:21 +00:00
2024-08-01 00:18:03 +00:00
in
fnOrAttrs :
stdenvNoCC . mkDerivation (
finalAttrs :
let
2024-09-08 01:36:21 +00:00
args = if lib . isFunction fnOrAttrs then fnOrAttrs ( args' // finalAttrs ) else fnOrAttrs ;
args' = transformArgs finalAttrs args ;
2024-09-21 01:08:12 +00:00
inherit ( args' )
nugetDeps
runtimeId
meta
dotnet-sdk
;
2024-09-08 01:36:21 +00:00
args'' = removeAttrs args' [
" n u g e t D e p s "
" r u n t i m e I d "
" i n s t a l l P a t h "
" e x e c u t a b l e s "
" p r o j e c t F i l e "
" p r o j e c t R e f e r e n c e s "
" r u n t i m e D e p s "
" d i s a b l e d T e s t s "
" t e s t P r o j e c t F i l e "
" b u i l d T y p e "
" s e l f C o n t a i n e d B u i l d "
" u s e D o t n e t "
" u s e A p p H o s t "
2024-09-21 01:08:12 +00:00
" d o t n e t - s d k "
2024-09-08 01:36:21 +00:00
] ;
2024-08-01 00:18:03 +00:00
in
2024-09-08 01:36:21 +00:00
if nugetDeps != null then
addNuGetDeps {
inherit nugetDeps ;
overrideFetchAttrs =
2024-09-21 01:08:12 +00:00
old :
lib . optionalAttrs ( ( args' . runtimeId or null ) == null ) rec {
2024-09-08 01:36:21 +00:00
dotnetRuntimeIds = map ( system : dotnetCorePackages . systemToDotnetRid system ) meta . platforms ;
2024-09-21 01:08:12 +00:00
buildInputs =
old . buildInputs
++ lib . concatLists ( lib . attrValues ( lib . getAttrs dotnetRuntimeIds dotnet-sdk . targetPackages ) ) ;
2024-09-08 01:36:21 +00:00
} ;
} args'' finalAttrs
else
args''
2024-08-01 12:58:28 +00:00
)