1# idea: provide a build environments for your developement of preference
2/*
3 #### examples of use: ####
4 # Add this to your ~/.config/nixpkgs/config.nix:
5 {
6 packageOverrides = pkgs : with pkgs; {
7 sdlEnv = pkgs.myEnvFun {
8 name = "sdl";
9 nativeBuildInputs = [ cmake pkg-config ];
10 buildInputs = [ stdenv SDL SDL_image SDL_ttf SDL_gfx SDL_net];
11 };
12 };
13 }
14
15 # Then you can install it by:
16 # $ nix-env -i env-sdl
17 # And you can load it simply calling:
18 # $ load-env-sdl
19 # and this will update your env vars to have 'make' and 'gcc' finding the SDL
20 # headers and libs.
21
22
23 ##### Another example, more complicated but achieving more: #######
24 # Make an environment to build nix from source and create ctags (tagfiles can
25 # be extracted from TAG_FILES) from every source package. Here would be a
26 # full ~/.config/nixpkgs/config.nix
27 {
28 packageOverrides = pkgs : with pkgs; with sourceAndTags;
29 let complicatedMyEnv = { name, buildInputs ? [], cTags ? [], extraCmds ? ""}:
30 pkgs.myEnvFun {
31 inherit name;
32 buildInputs = buildInputs
33 ++ map (x : sourceWithTagsDerivation
34 ( (addCTaggingInfo x ).passthru.sourceWithTags ) ) cTags;
35 extraCmds = ''
36 ${extraCmds}
37 HOME=${builtins.getEnv "HOME"}
38 . ~/.bashrc
39 '';
40 };
41 in rec {
42 # this is the example we will be using
43 nixEnv = complicatedMyEnv {
44 name = "nix";
45 buildInputs = [ libtool stdenv perl curl bzip2 openssl db5 autoconf automake zlib ];
46 };
47 };
48 }
49
50 # Now we should build our newly defined custom environment using this command on a shell, so type:
51 # $ nix-env -i env-nix
52
53 # You can load the environment simply typing a "load-env-${name}" command.
54 # $ load-env-nix
55 # The result using that command should be:
56 # env-nix loaded
57 and show you a shell with a prefixed prompt.
58*/
59
60{ mkDerivation, substituteAll, pkgs }:
61 { stdenv ? pkgs.stdenv, name, buildInputs ? []
62 , propagatedBuildInputs ? [], gcc ? stdenv.cc, extraCmds ? ""
63 , cleanupCmds ? "", shell ? "${pkgs.bashInteractive}/bin/bash --norc"}:
64
65mkDerivation {
66 inherit buildInputs propagatedBuildInputs;
67
68 name = "env-${name}";
69 phases = [ "buildPhase" "fixupPhase" ];
70 setupNew = substituteAll {
71 src = ../../stdenv/generic/setup.sh;
72 inherit gcc;
73 };
74
75 buildPhase = let
76 initialPath = import ../../stdenv/generic/common-path.nix { inherit pkgs; };
77 in ''
78 set -x
79 mkdir -p "$out/dev-envs" "$out/nix-support" "$out/bin"
80 s="$out/nix-support/setup-new-modified"
81 # shut some warning up.., do not use set -e
82 sed -e 's@set -eu@@' \
83 -e 's@assertEnvExists\s\+NIX_STORE@:@' \
84 -e 's@trap.*@@' \
85 -e '1i initialPath="${toString initialPath}"' \
86 "$setupNew" > "$s"
87 cat >> "$out/dev-envs/''${name/env-/}" << EOF
88 defaultNativeBuildInputs="$defaultNativeBuildInputs"
89 buildInputs="$buildInputs"
90 propagatedBuildInputs="$propagatedBuildInputs"
91 # the setup-new script wants to write some data to a temp file.. so just let it do that and tidy up afterwards
92 tmp="\$("${pkgs.coreutils}/bin/mktemp" -d)"
93 NIX_BUILD_TOP="\$tmp"
94 phases=
95 # only do all the setup stuff in nix-support/*
96 set +e
97 # This prevents having -rpath /lib in NIX_LDFLAGS
98 export NIX_NO_SELF_RPATH=1
99 if [[ -z "\$ZSH_VERSION" ]]; then
100 source "$s"
101 else
102 setopt interactivecomments
103 # fix bash indirection
104 # let's hope the bash arrays aren't used
105 # substitute is using bash array, so skip it
106 echo '
107 setopt NO_BAD_PATTERN
108 setopt NO_BANG_HIST
109 setopt NO_BG_NICE
110 setopt NO_EQUALS
111 setopt NO_FUNCTION_ARGZERO
112 setopt GLOB_SUBST
113 setopt NO_HUP
114 setopt INTERACTIVE_COMMENTS
115 setopt KSH_ARRAYS
116 setopt NO_MULTIOS
117 setopt NO_NOMATCH
118 setopt RM_STAR_SILENT
119 setopt POSIX_BUILTINS
120 setopt SH_FILE_EXPANSION
121 setopt SH_GLOB
122 setopt SH_OPTION_LETTERS
123 setopt SH_WORD_SPLIT
124 ' >> "\$tmp/script"
125 sed -e 's/\''${!\([^}]*\)}/\''${(P)\1}/g' \
126 -e 's/[[]\*\]//' \
127 -e 's/substitute() {/ substitute() { return; /' \
128 -e 's@PATH=\$@PATH=${pkgs.coreutils}/bin@' \
129 "$s" >> "\$tmp/script"
130 echo "\$tmp/script";
131 source "\$tmp/script";
132 fi
133 ${pkgs.coreutils}/bin/rm -fr "\$tmp"
134 ${extraCmds}
135
136 nix_cleanup() {
137 :
138 ${cleanupCmds}
139 }
140
141 export PATH
142 echo $name loaded >&2
143
144 trap nix_cleanup EXIT
145 EOF
146
147 mkdir -p $out/bin
148 sed -e 's,@shell@,${shell},' -e s,@myenvpath@,$out/dev-envs/${name}, \
149 -e 's,@name@,${name},' ${./loadenv.sh} > $out/bin/load-env-${name}
150 chmod +x $out/bin/load-env-${name}
151 '';
152}