Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{stdenv, lib, unzip, mkLicenses}: 2{packages, os ? null, nativeBuildInputs ? [], buildInputs ? [], patchesInstructions ? {}, meta ? {}, ...}@args: 3 4let 5 extraParams = removeAttrs args [ "packages" "os" "buildInputs" "nativeBuildInputs" "patchesInstructions" ]; 6 sortedPackages = builtins.sort (x: y: builtins.lessThan x.name y.name) packages; 7 8 mkXmlAttrs = attrs: 9 lib.concatStrings (lib.mapAttrsToList (name: value: " ${name}=\"${value}\"") attrs); 10 mkXmlValues = attrs: 11 lib.concatStrings (lib.mapAttrsToList (name: value: 12 let 13 tag = builtins.head (builtins.match "([^:]+).*" name); 14 in 15 if builtins.typeOf value == "string" then "<${tag}>${value}</${tag}>" else mkXmlDoc name value 16 ) attrs); 17 mkXmlDoc = name: doc: 18 let 19 tag = builtins.head (builtins.match "([^:]+).*" name); 20 hasXmlAttrs = builtins.hasAttr "element-attributes" doc; 21 xmlValues = removeAttrs doc [ "element-attributes" ]; 22 hasXmlValues = builtins.length (builtins.attrNames xmlValues) > 0; 23 in 24 if hasXmlAttrs && hasXmlValues then "<${tag}${mkXmlAttrs doc.element-attributes}>${mkXmlValues xmlValues }</${tag}>" 25 else if hasXmlAttrs && !hasXmlValues then "<${tag}${mkXmlAttrs doc.element-attributes}/>" 26 else if !hasXmlAttrs && hasXmlValues then "<${tag}>${mkXmlValues xmlValues}</${tag}>" 27 else "<${tag}/>"; 28 mkXmlPackage = package: '' 29 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 30 <ns2:repository 31 xmlns:ns2="http://schemas.android.com/repository/android/common/02" 32 xmlns:ns3="http://schemas.android.com/repository/android/common/01" 33 xmlns:ns4="http://schemas.android.com/repository/android/generic/01" 34 xmlns:ns5="http://schemas.android.com/repository/android/generic/02" 35 xmlns:ns6="http://schemas.android.com/sdk/android/repo/addon2/01" 36 xmlns:ns7="http://schemas.android.com/sdk/android/repo/addon2/02" 37 xmlns:ns8="http://schemas.android.com/sdk/android/repo/addon2/03" 38 xmlns:ns9="http://schemas.android.com/sdk/android/repo/repository2/01" 39 xmlns:ns10="http://schemas.android.com/sdk/android/repo/repository2/02" 40 xmlns:ns11="http://schemas.android.com/sdk/android/repo/repository2/03" 41 xmlns:ns12="http://schemas.android.com/sdk/android/repo/sys-img2/03" 42 xmlns:ns13="http://schemas.android.com/sdk/android/repo/sys-img2/02" 43 xmlns:ns14="http://schemas.android.com/sdk/android/repo/sys-img2/01" 44 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 45 <license id="${package.license}" type="text">${lib.concatStringsSep "---" (mkLicenses package.license)}</license> 46 <localPackage path="${builtins.replaceStrings [ "/" ] [ ";" ] package.path}" obsolete="${ 47 if (lib.hasAttrByPath [ "obsolete" ] package) 48 then package.obsolete else "false" 49 }"> 50 ${mkXmlDoc "type-details" package.type-details} 51 ${mkXmlDoc "revision" package.revision-details} 52 ${lib.optionalString (lib.hasAttrByPath [ "dependencies" ] package) 53 (mkXmlDoc "dependencies" package.dependencies) 54 } 55 <display-name>${package.displayName}</display-name> 56 <uses-license ref="${package.license}"/> 57 </localPackage> 58 </ns2:repository> 59 ''; 60in 61stdenv.mkDerivation ({ 62 inherit buildInputs; 63 pname = "android-sdk-${lib.concatMapStringsSep "-" (package: package.name) sortedPackages}"; 64 version = lib.concatMapStringsSep "-" (package: package.revision) sortedPackages; 65 src = map (package: 66 if os != null && builtins.hasAttr os package.archives then package.archives.${os} else package.archives.all 67 ) packages; 68 nativeBuildInputs = [ unzip ] ++ nativeBuildInputs; 69 preferLocalBuild = true; 70 71 unpackPhase = '' 72 buildDir=$PWD 73 i=0 74 for srcArchive in $src; do 75 extractedZip="extractedzip-$i" 76 i=$((i+1)) 77 cd "$buildDir" 78 mkdir "$extractedZip" 79 cd "$extractedZip" 80 unpackFile "$srcArchive" 81 done 82 ''; 83 84 installPhase = lib.concatStrings (lib.imap0 (i: package: '' 85 cd $buildDir/extractedzip-${toString i} 86 87 # Most Android Zip packages have a root folder, but some don't. We unpack 88 # the zip file in a folder and we try to discover whether it has a single root 89 # folder. If this is the case, we adjust the current working folder. 90 if [ "$(find . -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ]; then 91 cd "$(find . -mindepth 1 -maxdepth 1 -type d)" 92 fi 93 extractedZip="$PWD" 94 95 packageBaseDir=$out/libexec/android-sdk/${package.path} 96 mkdir -p $packageBaseDir 97 cd $packageBaseDir 98 cp -a $extractedZip/* . 99 ${patchesInstructions.${package.name}} 100 101 if [ ! -f $packageBaseDir/package.xml ]; then 102 cat << EOF > $packageBaseDir/package.xml 103 ${mkXmlPackage package} 104 EOF 105 fi 106 '') packages); 107 108 # Some executables that have been patched with patchelf may not work any longer after they have been stripped. 109 dontStrip = true; 110 dontPatchELF = true; 111 dontAutoPatchelf = true; 112 113 meta = { 114 description = lib.concatMapStringsSep "\n" (package: package.displayName) packages; 115 } // meta; 116} // extraParams)