summary refs log tree commit diff
path: root/pkgs/misc/my-env/default.nix
blob: ffdaf3949aea3e8036e3bd735530cf46a01c913a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# idea: provide a build environments for your developement of preference
/*
  #### examples of use: ####
  # Add this to your ~/.nixpkgs/config.nix:
  {
    packageOverrides = pkgs : with pkgs; {
      sdlEnv = pkgs.myEnvFun {
          name = "sdl";
          buildInputs = [ stdenv SDL SDL_image SDL_ttf SDL_gfx cmake SDL_net  pkgconfig];
      };
    };
  }

  # Then you can install it by:  
  #  $ nix-env -i env-sdl
  # And you can load it simply calling:  
  #  $ load-env-sdl
  # and this will update your env vars to have 'make' and 'gcc' finding the SDL
  # headers and libs.


  ##### Another example, more complicated but achieving more: #######
  # Make an environment to build nix from source and create ctags (tagfiles can
  # be extracted from TAG_FILES) from every source package. Here would be a
  # full ~/.nixpkgs/config.nix
  {
    packageOverrides = pkgs : with pkgs; with sourceAndTags;
    let complicatedMyEnv = { name, buildInputs ? [], cTags ? [], extraCmds ? ""}:
            pkgs.myEnvFun {
              inherit name;
            buildInputs = buildInputs 
                  ++ map (x : sourceWithTagsDerivation
                    ( (addCTaggingInfo x ).passthru.sourceWithTags ) ) cTags;
            extraCmds = ''
              ${extraCmds}
              HOME=${builtins.getEnv "HOME"}
              . ~/.bashrc
            '';
          };
    in rec {
      # this is the example we will be using
      nixEnv = complicatedMyEnv {
        name = "nix";
        buildInputs = [ libtool stdenv perl curl bzip2 openssl db5 autoconf automake zlib ];
      };
    };
  }

  # Now we should build our newly defined custom environment using this command on a shell, so type:
  #  $ nix-env -i env-nix

  # You can load the environment simply typing a "load-env-${name}" command.
  #  $ load-env-nix
  # The result using that command should be:
  #  env-nix loaded
  and show you a shell with a prefixed prompt.
*/

{ mkDerivation, substituteAll, pkgs }:
    { stdenv ? pkgs.stdenv, name, buildInputs ? []
    , propagatedBuildInputs ? [], gcc ? stdenv.cc, cTags ? [], extraCmds ? ""
    , cleanupCmds ? "", shell ? "${pkgs.bashInteractive}/bin/bash --norc"}:

mkDerivation {
  # The setup.sh script from stdenv will expect the native build inputs in
  # the nativeBuildInputs environment variable.
  nativeBuildInputs = [ ] ++ buildInputs;
  # Trick to bypass the stdenv usual change of propagatedBuildInputs => propagatedNativeBuildInputs
  propagatedBuildInputs2 = propagatedBuildInputs;

  name = "env-${name}";
  phases = [ "buildPhase" "fixupPhase" ];
  setupNew = substituteAll {
    src = ../../stdenv/generic/setup.sh;
    inherit gcc;
  };

  buildPhase = let
    initialPath = import ../../stdenv/common-path.nix { inherit pkgs; };
  in ''
    set -x
    mkdir -p "$out/dev-envs" "$out/nix-support" "$out/bin"
    s="$out/nix-support/setup-new-modified"
    # shut some warning up.., do not use set -e
    sed -e 's@set -e@@' \
        -e 's@assertEnvExists\s\+NIX_STORE@:@' \
        -e 's@trap.*@@' \
        -e '1i initialPath="${toString initialPath}"' \
        "$setupNew" > "$s"
    cat >> "$out/dev-envs/''${name/env-/}" << EOF
      defaultNativeBuildInputs="$defaultNativeBuildInputs"
      nativeBuildInputs="$nativeBuildInputs"
      propagatedBuildInputs="$propagatedBuildInputs2"
      # the setup-new script wants to write some data to a temp file.. so just let it do that and tidy up afterwards
      tmp="\$("${pkgs.coreutils}/bin/mktemp" -d)"
      NIX_BUILD_TOP="\$tmp"
      phases=
      # only do all the setup stuff in nix-support/*
      set +e
      # This prevents having -rpath /lib in NIX_LDFLAGS
      export NIX_NO_SELF_RPATH=1
      if [[ -z "\$ZSH_VERSION" ]]; then
        source "$s"
      else
        setopt interactivecomments
        # fix bash indirection
        # let's hope the bash arrays aren't used
        # substitute is using bash array, so skip it
        echo '
            setopt NO_BAD_PATTERN
            setopt NO_BANG_HIST
            setopt NO_BG_NICE
            setopt NO_EQUALS
            setopt NO_FUNCTION_ARGZERO
            setopt GLOB_SUBST
            setopt NO_HUP
            setopt INTERACTIVE_COMMENTS
            setopt KSH_ARRAYS
            setopt NO_MULTIOS
            setopt NO_NOMATCH
            setopt RM_STAR_SILENT
            setopt POSIX_BUILTINS
            setopt SH_FILE_EXPANSION
            setopt SH_GLOB
            setopt SH_OPTION_LETTERS
            setopt SH_WORD_SPLIT
          ' >> "\$tmp/script"
        sed -e 's/\''${!\([^}]*\)}/\''${(P)\1}/g' \
            -e 's/[[]\*\]//' \
            -e 's/substitute() {/ substitute() { return; /' \
            -e 's@PATH=\$@PATH=${pkgs.coreutils}/bin@' \
            "$s" >> "\$tmp/script"
        echo "\$tmp/script";
        source "\$tmp/script";
      fi
      ${pkgs.coreutils}/bin/rm -fr "\$tmp"
      ${extraCmds}

      nix_cleanup() {
        :
        ${cleanupCmds}
      }

      export PATH
      echo $name loaded >&2

      trap nix_cleanup EXIT
    EOF

    mkdir -p $out/bin
    sed -e 's,@shell@,${shell},' -e s,@myenvpath@,$out/dev-envs/${name}, \
      -e 's,@name@,${name},' ${./loadenv.sh} > $out/bin/load-env-${name}
    chmod +x $out/bin/load-env-${name}
  '';
}