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