summary refs log tree commit diff
path: root/pkgs/development/interpreters/python/2.7/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/interpreters/python/2.7/default.nix')
-rw-r--r--pkgs/development/interpreters/python/2.7/default.nix259
1 files changed, 168 insertions, 91 deletions
diff --git a/pkgs/development/interpreters/python/2.7/default.nix b/pkgs/development/interpreters/python/2.7/default.nix
index d9ec86088bb8..483a7e5fc002 100644
--- a/pkgs/development/interpreters/python/2.7/default.nix
+++ b/pkgs/development/interpreters/python/2.7/default.nix
@@ -1,110 +1,187 @@
 { stdenv, fetchurl, zlib ? null, zlibSupport ? true, bzip2
-, gdbmSupport ? true, gdbm ? null
-, sqlite ? null
-, db4 ? null
-, readline ? null
-, openssl ? null
-, tk ? null
-, tcl ? null
-, libX11 ? null
-, xproto ? null
-, arch ? null
-, sw_vers ? null
-, ncurses ? null
+, sqlite, tcl, tk, x11, openssl, readline, db4, ncurses, gdbm
+, darwinArchUtility ? null, darwinSwVersUtility ? null
 }:
 
 assert zlibSupport -> zlib != null;
-assert gdbmSupport -> gdbm != null;
-assert stdenv.isDarwin -> arch != null;
-assert stdenv.isDarwin -> sw_vers != null;
+assert stdenv.isDarwin -> darwinArchUtility != null;
+assert stdenv.isDarwin -> darwinSwVersUtility != null;
 
 with stdenv.lib;
 
 let
 
   majorVersion = "2.7";
-  version = "${majorVersion}";
+  version = "${majorVersion}.1";
+
+  src = fetchurl {
+    url = "http://www.python.org/ftp/python/${version}/Python-${version}.tar.bz2";
+    sha256 = "14i2c7yqa7ljmx2i2bb827n61q33zn23ax96czi8rbkyyny8gqw0";
+  };
+
+  patches =
+    [ # Look in C_INCLUDE_PATH and LIBRARY_PATH for stuff.
+      ./search-path.patch
+
+      # Python recompiles a Python if the mtime stored *in* the
+      # pyc/pyo file differs from the mtime of the source file.  This
+      # doesn't work in Nix because Nix changes the mtime of files in
+      # the Nix store to 1.  So treat that as a special case.
+      ./nix-store-mtime.patch
+    ];
 
   buildInputs =
     optional (stdenv ? gcc && stdenv.gcc.libc != null) stdenv.gcc.libc ++
-    [bzip2]
+    [ bzip2 ]
     ++ optional zlibSupport zlib
-    ++ optional gdbmSupport gdbm
-    ++ optional (sqlite != null) sqlite
-    ++ optional (db4 != null) db4
-    ++ optional (readline != null) readline
-    ++ optional (openssl != null) openssl
-    ++ optional (tk != null) tk
-    ++ optional (tcl != null) tcl
-    ++ optional (libX11 != null) libX11
-    ++ optional (xproto != null) xproto
-    ++ optional (arch != null) arch
-    ++ optional (sw_vers != null) sw_vers
-    ++ optional (ncurses != null) ncurses
-    ;
-
-in
-
-stdenv.mkDerivation ( {
-  name = "python-${version}";
-  inherit majorVersion version;
+    ++ optionals stdenv.isDarwin [ darwinArchUtility darwinSwVersUtility ];
+
+  ensurePurity =
+    ''
+      # Purity.
+      for i in /usr /sw /opt /pkg; do
+        substituteInPlace ./setup.py --replace $i /no-such-path
+      done
+    '';
 
-  src = fetchurl {
-    url = "http://www.python.org/ftp/python/${version}/Python-${version}.tar.bz2";
-    sha256 = "935d3316edfec5eb98c2f6930756b47b00dc27192541e62d6fd0077ffa008af8";
+  # Build the basic Python interpreter without modules that have
+  # external dependencies.
+  python = stdenv.mkDerivation {
+    name = "python-${version}";
+
+    inherit majorVersion version src patches buildInputs;
+
+    C_INCLUDE_PATH = concatStringsSep ":" (map (p: "${p}/include") buildInputs);
+    LIBRARY_PATH = concatStringsSep ":" (map (p: "${p}/lib") buildInputs);
+
+    configureFlags = "--enable-shared --with-threads --enable-unicode --with-wctype-functions";
+
+    preConfigure = "${ensurePurity}" + optionalString stdenv.isCygwin
+      ''
+        # On Cygwin, `make install' tries to read this Makefile.
+        mkdir -p $out/lib/python${majorVersion}/config
+        touch $out/lib/python${majorVersion}/config/Makefile
+        mkdir -p $out/include/python${majorVersion}
+        touch $out/include/python${majorVersion}/pyconfig.h
+      '';
+
+    NIX_CFLAGS_COMPILE = optionalString stdenv.isDarwin "-msse2";
+
+    setupHook = ./setup-hook.sh;
+
+    postInstall =
+      ''
+        rm -rf "$out/lib/python${majorVersion}/test"
+      '';
+
+    passthru = {
+      inherit zlibSupport;
+      libPrefix = "python${majorVersion}";
+    };
+
+    enableParallelBuilding = true;
+
+    meta = {
+      homepage = "http://python.org";
+      description = "Python -- a high-level dynamically-typed programming language";
+      longDescription = ''
+        Python is a remarkably powerful dynamic programming language that
+        is used in a wide variety of application domains. Some of its key
+        distinguishing features include: clear, readable syntax; strong
+        introspection capabilities; intuitive object orientation; natural
+        expression of procedural code; full modularity, supporting
+        hierarchical packages; exception-based error handling; and very
+        high level dynamic data types.
+      '';
+      license = "GPLv2";
+      platforms = stdenv.lib.platforms.all;
+      maintainers = [ stdenv.lib.maintainers.simons ];
+    };
   };
 
-  patches = [
-    # Look in C_INCLUDE_PATH and LIBRARY_PATH for stuff.
-    ./search-path.patch
-  ];
-
-  inherit buildInputs;
-  C_INCLUDE_PATH = concatStringsSep ":" (map (p: "${p}/include") buildInputs);
-  LIBRARY_PATH = concatStringsSep ":" (map (p: "${p}/lib") buildInputs);
-  configureFlags = "--enable-shared --with-threads --enable-unicode --with-wctype-functions";
-
-  preConfigure = ''
-    # Purity.
-    for i in /usr /sw /opt /pkg; do
-      substituteInPlace ./setup.py --replace $i /no-such-path
-    done
-  '' + (if readline != null then ''
-    export NIX_LDFLAGS="$NIX_LDFLAGS -lncurses"
-  '' else "");
-
-  setupHook = ./setup-hook.sh;
-
-  postInstall = ''
-    rm -rf "$out/lib/python${majorVersion}/test"
-  '';
-
-  passthru = {
-    inherit zlibSupport;
-    sqliteSupport = sqlite != null;
-    db4Support = db4 != null;
-    readlineSupport = readline != null;
-    opensslSupport = openssl != null;
-    tkSupport = (tk != null) && (tcl != null);
-    libPrefix = "python${majorVersion}";
-  };
 
-  enableParallelBuilding = true;
-
-  meta = {
-    homepage = "http://python.org";
-    description = "Python -- a high-level dynamically-typed programming language";
-    longDescription = ''
-      Python is a remarkably powerful dynamic programming language that
-      is used in a wide variety of application domains. Some of its key
-      distinguishing features include: clear, readable syntax; strong
-      introspection capabilities; intuitive object orientation; natural
-      expression of procedural code; full modularity, supporting
-      hierarchical packages; exception-based error handling; and very
-      high level dynamic data types.
-    '';
-    license = "GPLv2";
-    platforms = stdenv.lib.platforms.all;
-    maintainers = [ stdenv.lib.maintainers.simons ];
+  # This function builds a Python module included in the main Python
+  # distribution in a separate derivation.
+  buildInternalPythonModule =
+    { moduleName
+    , internalName ? "_" + moduleName
+    , deps
+    }:
+    stdenv.mkDerivation rec {
+      name = "python-${moduleName}-${python.version}";
+
+      inherit src patches;
+
+      buildInputs = [ python ] ++ deps;
+
+      C_INCLUDE_PATH = concatStringsSep ":" (map (p: "${p}/include") buildInputs);
+      LIBRARY_PATH = concatStringsSep ":" (map (p: "${p}/lib") buildInputs);
+
+      configurePhase = "${ensurePurity}";
+
+      buildPhase =
+        ''
+          # Fake the build environment that setup.py expects.
+          ln -s ${python}/include/python*/pyconfig.h .
+          ln -s ${python}/lib/python*/config/Setup Modules/
+          ln -s ${python}/lib/python*/config/Setup.local Modules/
+
+          substituteInPlace setup.py --replace 'self.extensions = extensions' \
+            'self.extensions = [ext for ext in self.extensions if ext.name in ["${internalName}"]]'
+
+          python ./setup.py build_ext
+        '';
+
+      installPhase =
+        ''
+          dest=$out/lib/${python.libPrefix}/site-packages
+          mkdir -p $dest
+          cp -p $(find . -name "*.${if stdenv.isCygwin then "dll" else "so"}") $dest/
+        '';
+    };
+
+
+  # The Python modules included in the main Python distribution, built
+  # as separate derivations.
+  modules = {
+
+    bsddb = buildInternalPythonModule {
+      moduleName = "bsddb";
+      deps = [ db4 ];
+    };
+
+    curses = buildInternalPythonModule {
+      moduleName = "curses";
+      deps = [ ncurses ];
+    };
+
+    gdbm = buildInternalPythonModule {
+      moduleName = "gdbm";
+      internalName = "gdbm";
+      deps = [ gdbm ];
+    };
+
+    sqlite3 = buildInternalPythonModule {
+      moduleName = "sqlite3";
+      deps = [ sqlite ];
+    };
+
+    ssl = buildInternalPythonModule {
+      moduleName = "ssl";
+      deps = [ openssl ];
+    };
+
+    tkinter = buildInternalPythonModule {
+      moduleName = "tkinter";
+      deps = [ tcl tk x11 ];
+    };
+
+    readline = buildInternalPythonModule {
+      moduleName = "readline";
+      internalName = "readline";
+      deps = [ readline ];
+    };
+
   };
-} // (if stdenv.isDarwin then { NIX_CFLAGS_COMPILE = "-msse2" ; patches = [./search-path.patch]; } else {} ) )
+
+in python // { inherit modules; }