nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 295 lines 9.1 kB view raw
1{ 2 stdenv, 3 lib, 4 elixir, 5 erlang, 6 hex, 7 git, 8 rebar, 9 rebar3, 10 fetchMixDeps, 11 findutils, 12 ripgrep, 13 bbe, 14 makeWrapper, 15 coreutils, 16 gnused, 17 gnugrep, 18 gawk, 19}@inputs: 20 21{ 22 pname, 23 version, 24 src, 25 nativeBuildInputs ? [ ], 26 buildInputs ? [ ], 27 meta ? { }, 28 enableDebugInfo ? false, 29 mixEnv ? "prod", 30 mixTarget ? "host", 31 compileFlags ? [ ], 32 # Build a particular named release. 33 # see https://hexdocs.pm/mix/1.12/Mix.Tasks.Release.html#content 34 mixReleaseName ? "", 35 # If set, the given escript binary will be copied to the output 36 # instead of the release 37 escriptBinName ? null, 38 39 # Options to be passed to the Erlang compiler. As documented in the reference 40 # manual, these must be valid Erlang terms. They will be turned into an 41 # erlang list and set as the ERL_COMPILER_OPTIONS environment variable. 42 # See https://www.erlang.org/doc/man/compile 43 erlangCompilerOptions ? [ ], 44 45 # Deterministic Erlang builds remove full system paths from debug information 46 # among other things to keep builds more reproducible. See their docs for more: 47 # https://www.erlang.org/doc/man/compile 48 erlangDeterministicBuilds ? true, 49 50 # Mix dependencies provided as a fixed output derivation 51 mixFodDeps ? null, 52 53 # Mix dependencies generated by mix2nix 54 # 55 # This assumes each dependency is built by buildMix or buildRebar3. Each 56 # dependency needs to have a setup hook to add the lib path to $ERL_LIBS. 57 # This is how Mix finds dependencies. 58 mixNixDeps ? { }, 59 60 elixir ? inputs.elixir, 61 erlang ? inputs.erlang, 62 hex ? inputs.hex.override { inherit elixir; }, 63 64 # Remove releases/COOKIE 65 # 66 # People have different views on the nature of cookies. Some believe that they are 67 # secrets, while others believe they are just ids for clustering nodes instead of 68 # secrets. 69 # 70 # If you think cookie is secret, you can set this attr to true, then it will be 71 # removed from nix store. If not, you can set it to false. 72 # 73 # For backward compatibility, it is set to true by default. 74 # 75 # You can always specify a custom cookie by using RELEASE_COOKIE environment 76 # variable, regardless of the value of this attr. 77 removeCookie ? true, 78 79 # This reduces closure size, but can lead to some hard to understand runtime 80 # errors, so use with caution. See e.g. 81 # https://github.com/whitfin/cachex/issues/205 82 # https://framagit.org/framasoft/mobilizon/-/issues/1169 83 stripDebug ? false, 84 85 ... 86}@attrs: 87let 88 # Remove non standard attributes that cannot be coerced to strings 89 overridable = removeAttrs attrs [ 90 "compileFlags" 91 "erlangCompilerOptions" 92 "mixNixDeps" 93 ]; 94in 95assert mixNixDeps != { } -> mixFodDeps == null; 96assert stripDebug -> !enableDebugInfo; 97assert escriptBinName != null -> mixReleaseName == ""; 98 99stdenv.mkDerivation ( 100 overridable 101 // { 102 nativeBuildInputs = 103 nativeBuildInputs 104 ++ 105 # Erlang/Elixir deps 106 [ 107 erlang 108 elixir 109 hex 110 git 111 ] 112 ++ 113 # Mix deps 114 (builtins.attrValues mixNixDeps) 115 ++ 116 # other compile-time deps 117 [ 118 findutils 119 ripgrep 120 bbe 121 makeWrapper 122 ]; 123 124 buildInputs = buildInputs ++ lib.optionals (escriptBinName != null) [ erlang ]; 125 126 MIX_ENV = mixEnv; 127 MIX_TARGET = mixTarget; 128 MIX_BUILD_PREFIX = (if mixTarget == "host" then "" else "${mixTarget}_") + "${mixEnv}"; 129 MIX_DEBUG = if enableDebugInfo then 1 else 0; 130 HEX_OFFLINE = 1; 131 132 __darwinAllowLocalNetworking = true; 133 134 DEBUG = if enableDebugInfo then 1 else 0; # for Rebar3 compilation 135 # The API with `mix local.rebar rebar path` makes a copy of the binary 136 # some older dependencies still use rebar. 137 MIX_REBAR = "${rebar}/bin/rebar"; 138 MIX_REBAR3 = "${rebar3}/bin/rebar3"; 139 140 ERL_COMPILER_OPTIONS = 141 let 142 options = erlangCompilerOptions ++ lib.optionals erlangDeterministicBuilds [ "deterministic" ]; 143 in 144 "[${lib.concatStringsSep "," options}]"; 145 146 LANG = if stdenv.hostPlatform.isLinux then "C.UTF-8" else "C"; 147 LC_CTYPE = if stdenv.hostPlatform.isLinux then "C.UTF-8" else "UTF-8"; 148 149 postUnpack = '' 150 # Mix and Hex 151 export MIX_HOME="$TEMPDIR/mix" 152 export HEX_HOME="$TEMPDIR/hex" 153 154 # Rebar 155 export REBAR_GLOBAL_CONFIG_DIR="$TEMPDIR/rebar3" 156 export REBAR_CACHE_DIR="$TEMPDIR/rebar3.cache" 157 158 ${lib.optionalString (mixFodDeps != null) '' 159 # Compilation of the dependencies will require that the dependency path is 160 # writable, thus a copy to the $TEMPDIR is inevitable here. 161 export MIX_DEPS_PATH="$TEMPDIR/deps" 162 cp --no-preserve=mode -R "${mixFodDeps}" "$MIX_DEPS_PATH" 163 ''} 164 '' 165 + (attrs.postUnpack or ""); 166 167 configurePhase = 168 attrs.configurePhase or '' 169 runHook preConfigure 170 171 ${./mix-configure-hook.sh} 172 173 # This is needed for projects that have a specific compile step 174 # the dependency needs to be compiled in order for the task 175 # to be available. 176 # 177 # Phoenix projects for example will need compile.phoenix. 178 mix deps.compile --no-deps-check --skip-umbrella-children 179 180 # Symlink dependency sources. This is needed for projects that require 181 # access to the source of their dependencies. For example, Phoenix 182 # projects need javascript assets to build asset bundles. 183 ${lib.optionalString (mixNixDeps != { }) '' 184 mkdir -p deps 185 186 ${lib.concatMapStringsSep "\n" (dep: '' 187 dep_name=$(basename ${dep} | cut -d '-' -f2) 188 dep_path="deps/$dep_name" 189 if [ -d "${dep}/src" ]; then 190 ln -s ${dep}/src $dep_path 191 fi 192 '') (builtins.attrValues mixNixDeps)} 193 ''} 194 195 # Symlink deps to build root. Similar to above, but allows for mixFodDeps 196 # Phoenix projects to find javascript assets. 197 ${lib.optionalString (mixFodDeps != null) '' 198 ln -s "$MIX_DEPS_PATH" ./deps 199 ''} 200 201 runHook postConfigure 202 ''; 203 204 buildPhase = 205 attrs.buildPhase or '' 206 runHook preBuild 207 208 mix compile --no-deps-check ${lib.concatStringsSep " " compileFlags} 209 210 ${lib.optionalString (escriptBinName != null) '' 211 mix escript.build --no-deps-check 212 ''} 213 214 runHook postBuild 215 ''; 216 217 installPhase = 218 attrs.installPhase or '' 219 runHook preInstall 220 221 ${ 222 if (escriptBinName != null) then 223 '' 224 mkdir -p $out/bin 225 cp ${escriptBinName} $out/bin 226 '' 227 else 228 '' 229 mix release ${mixReleaseName} --no-deps-check --path "$out" 230 '' 231 } 232 233 runHook postInstall 234 ''; 235 236 postFixup = '' 237 echo "removing files for Microsoft Windows" 238 rm -f "$out"/bin/*.bat 239 240 echo "wrapping programs in $out/bin with their runtime deps" 241 for f in $(find $out/bin/ -type f -executable); do 242 wrapProgram "$f" \ 243 --prefix PATH : ${ 244 lib.makeBinPath [ 245 coreutils 246 gnused 247 gnugrep 248 gawk 249 ] 250 } 251 done 252 '' 253 + lib.optionalString removeCookie '' 254 if [ -e $out/releases/COOKIE ]; then 255 echo "removing $out/releases/COOKIE" 256 rm $out/releases/COOKIE 257 fi 258 '' 259 + '' 260 if [ -e $out/erts-* ]; then 261 # ERTS is included in the release, then erlang is not required as a runtime dependency. 262 # But, erlang is still referenced in some places. To removed references to erlang, 263 # following steps are required. 264 265 # 1. remove references to erlang from plain text files 266 for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches); do 267 echo "removing references to erlang in $file" 268 substituteInPlace "$file" --replace "${erlang}/lib/erlang" "$out" 269 done 270 271 # 2. remove references to erlang from .beam files 272 # 273 # No need to do anything, because it has been handled by "deterministic" option specified 274 # by ERL_COMPILER_OPTIONS. 275 276 # 3. remove references to erlang from normal binary files 277 for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches --binary --iglob '!*.beam'); do 278 echo "removing references to erlang in $file" 279 # use bbe to substitute strings in binary files, because using substituteInPlace 280 # on binaries will raise errors 281 bbe -e "s|${erlang}/lib/erlang|$out|" -o "$file".tmp "$file" 282 rm -f "$file" 283 mv "$file".tmp "$file" 284 done 285 286 # References to erlang should be removed from output after above processing. 287 fi 288 '' 289 + lib.optionalString stripDebug '' 290 # Strip debug symbols to avoid hardreferences to "foreign" closures actually 291 # not needed at runtime, while at the same time reduce size of BEAM files. 292 erl -noinput -eval 'lists:foreach(fun(F) -> io:format("Stripping ~p.~n", [F]), beam_lib:strip(F) end, filelib:wildcard("'"$out"'/**/*.beam"))' -s init stop 293 ''; 294 } 295)