Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at netboot-syslinux-multiplatform 214 lines 8.4 kB view raw
1# The base package for automatic multiple-output splitting. Used in stdenv as well. 2preConfigureHooks+=(_multioutConfig) 3preFixupHooks+=(_multioutDocs) 4preFixupHooks+=(_multioutDevs) 5postFixupHooks+=(_multioutPropagateDev) 6 7# _assignFirst varName otherVarNames* 8# 9# Set the value of the variable named $varName to the first of otherVarNames 10# that refers to a non-empty variable name. 11# 12# If none of otherVarNames refers to a non-empty variable, the error message is 13# specific to this function's use case, which is setting up the output variables. 14_assignFirst() { 15 local varName="$1" 16 local _var 17 local REMOVE=REMOVE # slightly hacky - we allow REMOVE (i.e. not a variable name) 18 shift 19 for _var in "$@"; do 20 if [ -n "${!_var-}" ]; then eval "${varName}"="${_var}"; return; fi 21 done 22 echo 23 echo "error: _assignFirst: could not find a non-empty variable whose name to assign to ${varName}." 24 echo " The following variables were all unset or empty:" 25 echo " $*" 26 if [ -z "${out:-}" ]; then 27 echo ' If you do not want an "out" output in your derivation, make sure to define' 28 echo ' the other specific required outputs. This can be achieved by picking one' 29 echo " of the above as an output." 30 echo ' You do not have to remove "out" if you want to have a different default' 31 echo ' output, because the first output is taken as a default.' 32 echo 33 fi 34 return 1 # none found 35} 36 37# Same as _assignFirst, but only if "$1" = "" 38_overrideFirst() { 39 if [ -z "${!1-}" ]; then 40 _assignFirst "$@" 41 fi 42} 43 44 45# Setup chains of sane default values with easy overridability. 46# The variables are global to be usable anywhere during the build. 47# Typical usage in package is defining outputBin = "dev"; 48 49_overrideFirst outputDev "dev" "out" 50_overrideFirst outputBin "bin" "out" 51 52_overrideFirst outputInclude "$outputDev" 53 54# so-libs are often among the main things to keep, and so go to $out 55_overrideFirst outputLib "lib" "out" 56 57_overrideFirst outputDoc "doc" "out" 58_overrideFirst outputDevdoc "devdoc" REMOVE # documentation for developers 59# man and info pages are small and often useful to distribute with binaries 60_overrideFirst outputMan "man" "$outputBin" 61_overrideFirst outputDevman "devman" "devdoc" "$outputMan" 62_overrideFirst outputInfo "info" "$outputBin" 63 64 65# Add standard flags to put files into the desired outputs. 66_multioutConfig() { 67 if [ "$(getAllOutputNames)" = "out" ] || [ -z "${setOutputFlags-1}" ]; then return; fi; 68 69 # try to detect share/doc/${shareDocName} 70 # Note: sadly, $configureScript detection comes later in configurePhase, 71 # and reordering would cause more trouble than worth. 72 if [ -z "$shareDocName" ]; then 73 local confScript="$configureScript" 74 if [ -z "$confScript" ] && [ -x ./configure ]; then 75 confScript=./configure 76 fi 77 if [ -f "$confScript" ]; then 78 local shareDocName="$(sed -n "s/^PACKAGE_TARNAME='\(.*\)'$/\1/p" < "$confScript")" 79 fi 80 # PACKAGE_TARNAME sometimes contains garbage. 81 if [ -z "$shareDocName" ] || echo "$shareDocName" | grep -q '[^a-zA-Z0-9_-]'; then 82 shareDocName="$(echo "$name" | sed 's/-[^a-zA-Z].*//')" 83 fi 84 fi 85 86 prependToVar configureFlags \ 87 --bindir="${!outputBin}"/bin --sbindir="${!outputBin}"/sbin \ 88 --includedir="${!outputInclude}"/include --oldincludedir="${!outputInclude}"/include \ 89 --mandir="${!outputMan}"/share/man --infodir="${!outputInfo}"/share/info \ 90 --docdir="${!outputDoc}"/share/doc/"${shareDocName}" \ 91 --libdir="${!outputLib}"/lib --libexecdir="${!outputLib}"/libexec \ 92 --localedir="${!outputLib}"/share/locale 93 94 prependToVar installFlags \ 95 pkgconfigdir="${!outputDev}"/lib/pkgconfig \ 96 m4datadir="${!outputDev}"/share/aclocal aclocaldir="${!outputDev}"/share/aclocal 97} 98 99 100# Add rpath prefixes to library paths, and avoid stdenv doing it for $out. 101_addRpathPrefix "${!outputLib}" 102NIX_NO_SELF_RPATH=1 103 104 105# Move subpaths that match pattern $1 from under any output/ to the $2 output/ 106# Beware: only globbing patterns are accepted, e.g.: * ? [abc] 107# A special target "REMOVE" is allowed: moveToOutput foo REMOVE 108moveToOutput() { 109 local patt="$1" 110 local dstOut="$2" 111 local output 112 for output in $(getAllOutputNames); do 113 if [ "${!output}" = "$dstOut" ]; then continue; fi 114 local srcPath 115 for srcPath in "${!output}"/$patt; do 116 # apply to existing files/dirs, *including* broken symlinks 117 if [ ! -e "$srcPath" ] && [ ! -L "$srcPath" ]; then continue; fi 118 119 if [ "$dstOut" = REMOVE ]; then 120 echo "Removing $srcPath" 121 rm -r "$srcPath" 122 else 123 local dstPath="$dstOut${srcPath#${!output}}" 124 echo "Moving $srcPath to $dstPath" 125 126 if [ -d "$dstPath" ] && [ -d "$srcPath" ] 127 then # attempt directory merge 128 # check the case of trying to move an empty directory 129 rmdir "$srcPath" --ignore-fail-on-non-empty 130 if [ -d "$srcPath" ]; then 131 mv -t "$dstPath" "$srcPath"/* 132 rmdir "$srcPath" 133 fi 134 else # usual move 135 mkdir -p "$(readlink -m "$dstPath/..")" 136 mv "$srcPath" "$dstPath" 137 fi 138 fi 139 140 # remove empty directories, printing iff at least one gets removed 141 local srcParent="$(readlink -m "$srcPath/..")" 142 if [ -n "$(find "$srcParent" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then 143 echo "Removing empty $srcParent/ and (possibly) its parents" 144 rmdir -p --ignore-fail-on-non-empty "$srcParent" \ 145 2> /dev/null || true # doesn't ignore failure for some reason 146 fi 147 done 148 done 149} 150 151# Move documentation to the desired outputs. 152_multioutDocs() { 153 local REMOVE=REMOVE # slightly hacky - we expand ${!outputFoo} 154 155 moveToOutput share/info "${!outputInfo}" 156 moveToOutput share/doc "${!outputDoc}" 157 moveToOutput share/gtk-doc "${!outputDevdoc}" 158 moveToOutput share/devhelp/books "${!outputDevdoc}" 159 160 # the default outputMan is in $bin 161 moveToOutput share/man "${!outputMan}" 162 moveToOutput share/man/man3 "${!outputDevman}" 163} 164 165# Move development-only stuff to the desired outputs. 166_multioutDevs() { 167 if [ "$(getAllOutputNames)" = "out" ] || [ -z "${moveToDev-1}" ]; then return; fi; 168 moveToOutput include "${!outputInclude}" 169 # these files are sometimes provided even without using the corresponding tool 170 moveToOutput lib/pkgconfig "${!outputDev}" 171 moveToOutput share/pkgconfig "${!outputDev}" 172 moveToOutput lib/cmake "${!outputDev}" 173 moveToOutput share/aclocal "${!outputDev}" 174 # don't move *.la, as libtool needs them in the directory of the library 175 176 for f in "${!outputDev}"/{lib,share}/pkgconfig/*.pc; do 177 echo "Patching '$f' includedir to output ${!outputInclude}" 178 sed -i "/^includedir=/s,=\${prefix},=${!outputInclude}," "$f" 179 done 180} 181 182# Make the "dev" propagate other outputs needed for development. 183_multioutPropagateDev() { 184 if [ "$(getAllOutputNames)" = "out" ]; then return; fi; 185 186 local outputFirst 187 for outputFirst in $(getAllOutputNames); do 188 break 189 done 190 local propagaterOutput="$outputDev" 191 if [ -z "$propagaterOutput" ]; then 192 propagaterOutput="$outputFirst" 193 fi 194 195 # Default value: propagate binaries, includes and libraries 196 if [ -z "${propagatedBuildOutputs+1}" ]; then 197 local po_dirty="$outputBin $outputInclude $outputLib" 198 set +o pipefail 199 propagatedBuildOutputs=`echo "$po_dirty" \ 200 | tr -s ' ' '\n' | grep -v -F "$propagaterOutput" \ 201 | sort -u | tr '\n' ' ' ` 202 set -o pipefail 203 fi 204 205 # The variable was explicitly set to empty or we resolved it so 206 if [ -z "$propagatedBuildOutputs" ]; then 207 return 208 fi 209 210 mkdir -p "${!propagaterOutput}"/nix-support 211 for output in $propagatedBuildOutputs; do 212 echo -n " ${!output}" >> "${!propagaterOutput}"/nix-support/propagated-build-inputs 213 done 214}