diff options
author | obadz <dav-github@odav.org> | 2015-05-22 14:25:02 +0100 |
---|---|---|
committer | obadz <dav-github@odav.org> | 2015-06-06 09:06:22 -0400 |
commit | d4681bf62672083f92545e02e00b8cf040247e8d (patch) | |
tree | 24f50b3dfad442cf340db277740ec2e7fe0b7239 /pkgs/build-support | |
parent | 4cf3596fdae5982b5c549c52977662ace7bff26a (diff) | |
download | nixpkgs-d4681bf62672083f92545e02e00b8cf040247e8d.tar nixpkgs-d4681bf62672083f92545e02e00b8cf040247e8d.tar.gz nixpkgs-d4681bf62672083f92545e02e00b8cf040247e8d.tar.bz2 nixpkgs-d4681bf62672083f92545e02e00b8cf040247e8d.tar.lz nixpkgs-d4681bf62672083f92545e02e00b8cf040247e8d.tar.xz nixpkgs-d4681bf62672083f92545e02e00b8cf040247e8d.tar.zst nixpkgs-d4681bf62672083f92545e02e00b8cf040247e8d.zip |
Lay down the foundation for packaging the .NET echosystem
- fetchNuGet can fetch binaries from nuget servers - buildDotnetPackage can build .NET packages using mono/xbuild - Places nuget & paket as they would clash with nix - Patch project files because F# targets are expected to be found in the mono directory (and we know that's not going to happen on nix) - Find DLLs that were copied from buildInputs and replace by symlink for sharing - Export produced DLL via the pkg-config mechanism - Create wrappers for produced EXEs - Repackaged this new infrastructure: keepass, monodevelop - Newly packaged: ExtCore, UnionArgParser, FSharp.Data, Paket, and a bunch more.. This is a combination of 73 commits.
Diffstat (limited to 'pkgs/build-support')
8 files changed, 246 insertions, 0 deletions
diff --git a/pkgs/build-support/build-dotnet-package/default.nix b/pkgs/build-support/build-dotnet-package/default.nix new file mode 100644 index 00000000000..00be987af75 --- /dev/null +++ b/pkgs/build-support/build-dotnet-package/default.nix @@ -0,0 +1,109 @@ +{ stdenv, lib, makeWrapper, pkgconfig, mono, dotnetbuildhelpers }: + +attrsOrig @ +{ baseName +, version +, buildInputs ? [] +, xBuildFiles ? [ ] +, xBuildFlags ? [ "/p:Configuration=Release" ] +, outputFiles ? [ "bin/Release/*" ] +, dllFiles ? [ "*.dll" ] +, exeFiles ? [ "*.exe" ] +, ... }: + let + arrayToShell = (a: toString (map (lib.escape (lib.stringToCharacters "\\ ';$`()|<>\t") ) a)); + + attrs = { + name = "${baseName}-${version}"; + + buildInputs = [ + pkgconfig + mono + dotnetbuildhelpers + makeWrapper + ] ++ buildInputs; + + configurePhase = '' + runHook preConfigure + + [ -z "$dontPlacateNuget" ] && placate-nuget.sh + [ -z "$dontPlacatePaket" ] && placate-paket.sh + [ -z "$dontPatchFSharpTargets" ] && patch-fsharp-targets.sh + + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + + echo Building dotNET packages... + + # Probably needs to be moved to fsharp + if pkg-config FSharp.Core + then + export FSharpTargetsPath="$(dirname $(pkg-config FSharp.Core --variable=Libraries))/Microsoft.FSharp.Targets" + fi + + ran="" + for xBuildFile in ${arrayToShell xBuildFiles} ''${xBuildFilesExtra} + do + ran="yes" + xbuild ${arrayToShell xBuildFlags} ''${xBuildFlagsArray} $xBuildFile + done + + [ -z "$ran" ] && xbuild ${arrayToShell xBuildFlags} ''${xBuildFlagsArray} + + runHook postBuild + ''; + + dontStrip = true; + + installPhase = '' + runHook preInstall + + target="$out/lib/dotnet/${baseName}" + mkdir -p "$target" + + cp -rv ${arrayToShell outputFiles} "''${outputFilesArray[@]}" "$target" + + if [ -z "$dontRemoveDuplicatedDlls" ] + then + pushd "$out" + remove-duplicated-dlls.sh + popd + fi + + set -f + for dllPattern in ${arrayToShell dllFiles} ''${dllFilesArray[@]} + do + set +f + for dll in "$target"/$dllPattern + do + [ -f "$dll" ] || continue + if pkg-config $(basename -s .dll "$dll") + then + echo "$dll already exported by a buildInputs, not re-exporting" + else + ${dotnetbuildhelpers}/bin/create-pkg-config-for-dll.sh "$out/lib/pkgconfig" "$dll" + fi + done + done + + set -f + for exePattern in ${arrayToShell exeFiles} ''${exeFilesArray[@]} + do + set +f + for exe in "$target"/$exePattern + do + [ -f "$exe" ] || continue + mkdir -p "$out"/bin + commandName="$(basename -s .exe "$(echo "$exe" | tr "[A-Z]" "[a-z]")")" + makeWrapper "${mono}/bin/mono \"$exe\"" "$out"/bin/"$commandName" + done + done + + runHook postInstall + ''; + }; + in + stdenv.mkDerivation (attrs // (builtins.removeAttrs attrsOrig [ "buildInputs" ] )) diff --git a/pkgs/build-support/dotnetbuildhelpers/create-pkg-config-for-dll.sh b/pkgs/build-support/dotnetbuildhelpers/create-pkg-config-for-dll.sh new file mode 100644 index 00000000000..37914170452 --- /dev/null +++ b/pkgs/build-support/dotnetbuildhelpers/create-pkg-config-for-dll.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +targetDir="$1" +dllFullPath="$2" + +dllVersion="$(monodis --assembly "$dllFullPath" | grep ^Version: | cut -f 2 -d : | xargs)" +[ -z "$dllVersion" ] && echo "Defaulting dllVersion to 0.0.0" && dllVersion="0.0.0" +dllFileName="$(basename $dllFullPath)" +dllRootName="$(basename -s .dll $dllFileName)" +targetPcFile="$targetDir"/"$dllRootName".pc + +mkdir -p "$targetDir" + +cat > $targetPcFile << EOF +Libraries=$dllFullPath + +Name: $dllRootName +Description: $dllRootName +Version: $dllVersion +Libs: -r:$dllFileName +EOF + +echo "Created $targetPcFile" diff --git a/pkgs/build-support/dotnetbuildhelpers/default.nix b/pkgs/build-support/dotnetbuildhelpers/default.nix new file mode 100644 index 00000000000..ed0d4f790c8 --- /dev/null +++ b/pkgs/build-support/dotnetbuildhelpers/default.nix @@ -0,0 +1,18 @@ +{ helperFunctions, mono, pkgconfig }: + helperFunctions.runCommand + "dotnetbuildhelpers" + { preferLocalBuild = true; } + '' + target="$out/bin" + mkdir -p "$target" + + for script in ${./create-pkg-config-for-dll.sh} ${./patch-fsharp-targets.sh} ${./remove-duplicated-dlls.sh} ${./placate-nuget.sh} ${./placate-paket.sh} + do + scriptName="$(basename "$script" | cut -f 2- -d -)" + cp -v "$script" "$target"/"$scriptName" + chmod 755 "$target"/"$scriptName" + patchShebangs "$target"/"$scriptName" + substituteInPlace "$target"/"$scriptName" --replace pkg-config ${pkgconfig}/bin/pkg-config + substituteInPlace "$target"/"$scriptName" --replace monodis ${mono}/bin/monodis + done + '' diff --git a/pkgs/build-support/dotnetbuildhelpers/patch-fsharp-targets.sh b/pkgs/build-support/dotnetbuildhelpers/patch-fsharp-targets.sh new file mode 100644 index 00000000000..3f81cc73e80 --- /dev/null +++ b/pkgs/build-support/dotnetbuildhelpers/patch-fsharp-targets.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Some project files look for F# targets in $(FSharpTargetsPath) +# so it's a good idea to add something like this to your ~/.bash_profile: + +# export FSharpTargetsPath=$(dirname $(which fsharpc))/../lib/mono/4.0/Microsoft.FSharp.Targets + +# In build scripts, you would add somehting like this: + +# export FSharpTargetsPath="${fsharp}/lib/mono/4.0/Microsoft.FSharp.Targets" + +# However, some project files look for F# targets in the main Mono directory. When that happens +# patch the project files using this script so they will look in $(FSharpTargetsPath) instead. + +echo "Patching F# targets in fsproj files..." + +find -iname \*.fsproj -print -exec \ + sed --in-place=.bak \ + -e 's,<FSharpTargetsPath>\([^<]*\)</FSharpTargetsPath>,<FSharpTargetsPath Condition="Exists('\'\\1\'')">\1</FSharpTargetsPath>,'g \ + {} \; diff --git a/pkgs/build-support/dotnetbuildhelpers/placate-nuget.sh b/pkgs/build-support/dotnetbuildhelpers/placate-nuget.sh new file mode 100644 index 00000000000..8a7f36522a3 --- /dev/null +++ b/pkgs/build-support/dotnetbuildhelpers/placate-nuget.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +echo Placating Nuget in nuget.targets +find -iname nuget.targets -print -exec sed --in-place=bak -e 's,mono --runtime[^<]*,true NUGET PLACATED BY buildDotnetPackage,g' {} \; + +echo Just to be sure, replacing Nuget executables by empty files. +find . -iname nuget.exe \! -size 0 -exec mv -v {} {}.bak \; -exec touch {} \; diff --git a/pkgs/build-support/dotnetbuildhelpers/placate-paket.sh b/pkgs/build-support/dotnetbuildhelpers/placate-paket.sh new file mode 100644 index 00000000000..0dbf1eecbad --- /dev/null +++ b/pkgs/build-support/dotnetbuildhelpers/placate-paket.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +echo Placating Paket in paket.targets +find -iname paket.targets -print -exec sed --in-place=bak -e 's,mono --runtime[^<]*,true PAKET PLACATED BY buildDotnetPackage,g' {} \; + +echo Just to be sure, replacing Paket executables by empty files. +find . -iname paket\*.exe \! -size 0 -exec mv -v {} {}.bak \; -exec touch {} \; diff --git a/pkgs/build-support/dotnetbuildhelpers/remove-duplicated-dlls.sh b/pkgs/build-support/dotnetbuildhelpers/remove-duplicated-dlls.sh new file mode 100644 index 00000000000..d8d29912c8f --- /dev/null +++ b/pkgs/build-support/dotnetbuildhelpers/remove-duplicated-dlls.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +IFS=" +" + +for dll in $(find -iname \*.dll) +do + baseName="$(basename "$dll" | sed "s/.dll$//i")" + if pkg-config "$baseName" + then + candidateDll="$(pkg-config "$baseName" --variable=Libraries)" + + if diff "$dll" "$candidateDll" >/dev/null + then + echo "$dll is identical to $candidateDll. Substituting..." + rm -vf "$dll" + ln -sv "$candidateDll" "$dll" + else + echo "$dll and $candidateDll share the same name but have different contents, leaving alone." + fi + fi +done diff --git a/pkgs/build-support/fetchnuget/default.nix b/pkgs/build-support/fetchnuget/default.nix new file mode 100644 index 00000000000..803db27c9d5 --- /dev/null +++ b/pkgs/build-support/fetchnuget/default.nix @@ -0,0 +1,40 @@ +{ stdenv, fetchurl, buildDotnetPackage, unzip }: + +attrs @ +{ baseName +, version +, url ? "https://www.nuget.org/api/v2/package/${baseName}/${version}" +, sha256 ? "" +, md5 ? "" +, ... +}: + buildDotnetPackage ({ + src = fetchurl { + inherit url sha256 md5; + name = "${baseName}.${version}.zip"; + }; + + sourceRoot = "."; + + buildInputs = [ unzip ]; + + phases = [ "unpackPhase" "installPhase" ]; + + preInstall = '' + function traverseRename () { + for e in * + do + t="$(echo "$e" | sed -e "s/%20/\ /g" -e "s/%2B/+/g")" + [ "$t" != "$e" ] && mv -vn "$e" "$t" + if [ -d "$t" ] + then + cd "$t" + traverseRename + cd .. + fi + done + } + + traverseRename + ''; + } // attrs) |