at 16.09-beta 9.0 kB view raw
1{ stdenv, fetchurl, self, callPackage, python27Packages 2, bzip2, openssl, gettext 3, less 4 5, includeModules ? false 6 7, db, gdbm, ncurses, sqlite, readline 8 9, tcl ? null, tk ? null, xlibsWrapper ? null, libX11 ? null, x11Support ? !stdenv.isCygwin 10, zlib ? null, zlibSupport ? true 11, expat, libffi 12 13, CF, configd 14}: 15 16assert zlibSupport -> zlib != null; 17assert x11Support -> tcl != null 18 && tk != null 19 && xlibsWrapper != null 20 && libX11 != null; 21 22with stdenv.lib; 23 24let 25 majorVersion = "2.7"; 26 version = "${majorVersion}.12"; 27 28 src = fetchurl { 29 url = "http://www.python.org/ftp/python/${version}/Python-${version}.tar.xz"; 30 sha256 = "0y7rl603vmwlxm6ilkhc51rx2mfj14ckcz40xxgs0ljnvlhp30yp"; 31 }; 32 33 patches = 34 [ # Look in C_INCLUDE_PATH and LIBRARY_PATH for stuff. 35 ./search-path.patch 36 37 # Python recompiles a Python if the mtime stored *in* the 38 # pyc/pyo file differs from the mtime of the source file. This 39 # doesn't work in Nix because Nix changes the mtime of files in 40 # the Nix store to 1. So treat that as a special case. 41 ./nix-store-mtime.patch 42 43 # patch python to put zero timestamp into pyc 44 # if DETERMINISTIC_BUILD env var is set 45 ./deterministic-build.patch 46 47 ./properly-detect-curses.patch 48 ] ++ optionals stdenv.isLinux [ 49 50 # Disable the use of ldconfig in ctypes.util.find_library (since 51 # ldconfig doesn't work on NixOS), and don't use 52 # ctypes.util.find_library during the loading of the uuid module 53 # (since it will do a futile invocation of gcc (!) to find 54 # libuuid, slowing down program startup a lot). 55 ./no-ldconfig.patch 56 57 ] ++ optionals stdenv.isCygwin [ 58 ./2.5.2-ctypes-util-find_library.patch 59 ./2.5.2-tkinter-x11.patch 60 ./2.6.2-ssl-threads.patch 61 ./2.6.5-export-PySignal_SetWakeupFd.patch 62 ./2.6.5-FD_SETSIZE.patch 63 ./2.6.5-ncurses-abi6.patch 64 ./2.7.3-dbm.patch 65 ./2.7.3-dylib.patch 66 ./2.7.3-getpath-exe-extension.patch 67 ./2.7.3-no-libm.patch 68 ]; 69 70 preConfigure = '' 71 # Purity. 72 for i in /usr /sw /opt /pkg; do 73 substituteInPlace ./setup.py --replace $i /no-such-path 74 done 75 '' + optionalString (stdenv ? cc && stdenv.cc.libc != null) '' 76 for i in Lib/plat-*/regen; do 77 substituteInPlace $i --replace /usr/include/ ${stdenv.cc.libc}/include/ 78 done 79 '' + optionalString stdenv.isDarwin '' 80 substituteInPlace configure --replace '`/usr/bin/arch`' '"i386"' 81 substituteInPlace Lib/multiprocessing/__init__.py \ 82 --replace 'os.popen(comm)' 'os.popen("nproc")' 83 ''; 84 85 configureFlags = [ 86 "--enable-shared" 87 "--with-threads" 88 "--enable-unicode=ucs4" 89 ] ++ optionals stdenv.isCygwin [ 90 "--with-system-ffi" 91 "--with-system-expat" 92 "ac_cv_func_bind_textdomain_codeset=yes" 93 ] ++ optionals stdenv.isDarwin [ 94 "--disable-toolbox-glue" 95 ]; 96 97 postConfigure = if stdenv.isCygwin then '' 98 sed -i Makefile -e 's,PYTHONPATH="$(srcdir),PYTHONPATH="$(abs_srcdir),' 99 '' else null; 100 101 buildInputs = 102 optional (stdenv ? cc && stdenv.cc.libc != null) stdenv.cc.libc ++ 103 [ bzip2 openssl ] 104 ++ optionals stdenv.isCygwin [ expat libffi ] 105 ++ optionals includeModules ( 106 [ db gdbm ncurses sqlite readline 107 ] ++ optionals x11Support [ tcl tk xlibsWrapper libX11 ] 108 ) 109 ++ optional zlibSupport zlib 110 ++ optional stdenv.isDarwin CF; 111 112 propagatedBuildInputs = [ less ] ++ optional stdenv.isDarwin configd; 113 114 mkPaths = paths: { 115 C_INCLUDE_PATH = makeSearchPathOutput "dev" "include" paths; 116 LIBRARY_PATH = makeLibraryPath paths; 117 }; 118 119 # Build the basic Python interpreter without modules that have 120 # external dependencies. 121 python = stdenv.mkDerivation { 122 name = "python-${version}"; 123 pythonVersion = majorVersion; 124 125 inherit majorVersion version src patches buildInputs propagatedBuildInputs 126 preConfigure configureFlags; 127 128 LDFLAGS = stdenv.lib.optionalString (!stdenv.isDarwin) "-lgcc_s"; 129 inherit (mkPaths buildInputs) C_INCLUDE_PATH LIBRARY_PATH; 130 131 NIX_CFLAGS_COMPILE = optionalString stdenv.isDarwin "-msse2"; 132 DETERMINISTIC_BUILD = 1; 133 134 setupHook = ./setup-hook.sh; 135 136 postInstall = 137 '' 138 # needed for some packages, especially packages that backport 139 # functionality to 2.x from 3.x 140 for item in $out/lib/python${majorVersion}/test/*; do 141 if [[ "$item" != */test_support.py* ]]; then 142 rm -rf "$item" 143 else 144 echo $item 145 fi 146 done 147 touch $out/lib/python${majorVersion}/test/__init__.py 148 ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb 149 ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb${majorVersion} 150 ln -s $out/share/man/man1/{python2.7.1.gz,python.1.gz} 151 152 paxmark E $out/bin/python${majorVersion} 153 154 ${optionalString includeModules "$out/bin/python ./setup.py build_ext"} 155 156 rm "$out"/lib/python*/plat-*/regen # refers to glibc.dev 157 ''; 158 159 passthru = rec { 160 inherit zlibSupport; 161 isPy2 = true; 162 isPy27 = true; 163 buildEnv = callPackage ../../wrapper.nix { python = self; }; 164 withPackages = import ../../with-packages.nix { inherit buildEnv; pythonPackages = python27Packages; }; 165 libPrefix = "python${majorVersion}"; 166 executable = libPrefix; 167 sitePackages = "lib/${libPrefix}/site-packages"; 168 interpreter = "${self}/bin/${executable}"; 169 }; 170 171 enableParallelBuilding = true; 172 173 meta = { 174 homepage = "http://python.org"; 175 description = "A high-level dynamically-typed programming language"; 176 longDescription = '' 177 Python is a remarkably powerful dynamic programming language that 178 is used in a wide variety of application domains. Some of its key 179 distinguishing features include: clear, readable syntax; strong 180 introspection capabilities; intuitive object orientation; natural 181 expression of procedural code; full modularity, supporting 182 hierarchical packages; exception-based error handling; and very 183 high level dynamic data types. 184 ''; 185 license = stdenv.lib.licenses.psfl; 186 platforms = stdenv.lib.platforms.all; 187 maintainers = with stdenv.lib.maintainers; [ chaoflow domenkozar ]; 188 }; 189 }; 190 191 192 # This function builds a Python module included in the main Python 193 # distribution in a separate derivation. 194 buildInternalPythonModule = 195 { moduleName 196 , internalName ? "_" + moduleName 197 , deps 198 }: 199 if includeModules then null else stdenv.mkDerivation rec { 200 name = "python-${moduleName}-${python.version}"; 201 202 inherit src patches preConfigure postConfigure configureFlags; 203 204 buildInputs = [ python ] ++ deps; 205 206 # We need to set this for python.buildEnv 207 pythonPath = []; 208 209 inherit (mkPaths buildInputs) C_INCLUDE_PATH LIBRARY_PATH; 210 211 # non-python gdbm has a libintl dependency on i686-cygwin, not on x86_64-cygwin 212 buildPhase = (if (stdenv.system == "i686-cygwin" && moduleName == "gdbm") then '' 213 sed -i setup.py -e "s:libraries = \['gdbm'\]:libraries = ['gdbm', 'intl']:" 214 '' else '''') + '' 215 substituteInPlace setup.py --replace 'self.extensions = extensions' \ 216 'self.extensions = [ext for ext in self.extensions if ext.name in ["${internalName}"]]' 217 218 python ./setup.py build_ext 219 [ -z "$(find build -name '*_failed.so' -print)" ] 220 ''; 221 222 installPhase = 223 '' 224 dest=$out/lib/${python.libPrefix}/site-packages 225 mkdir -p $dest 226 cp -p $(find . -name "*.${if stdenv.isCygwin then "dll" else "so"}") $dest/ 227 ''; 228 }; 229 230 231 # The Python modules included in the main Python distribution, built 232 # as separate derivations. 233 modules = { 234 235 bsddb = buildInternalPythonModule { 236 moduleName = "bsddb"; 237 deps = [ db ]; 238 }; 239 240 curses = buildInternalPythonModule { 241 moduleName = "curses"; 242 deps = [ ncurses ]; 243 }; 244 245 curses_panel = buildInternalPythonModule { 246 moduleName = "curses_panel"; 247 deps = [ ncurses modules.curses ]; 248 }; 249 250 crypt = buildInternalPythonModule { 251 moduleName = "crypt"; 252 internalName = "crypt"; 253 deps = optional (stdenv ? glibc) stdenv.glibc; 254 }; 255 256 gdbm = buildInternalPythonModule { 257 moduleName = "gdbm"; 258 internalName = "gdbm"; 259 deps = [ gdbm ] ++ stdenv.lib.optional stdenv.isCygwin gettext; 260 }; 261 262 sqlite3 = buildInternalPythonModule { 263 moduleName = "sqlite3"; 264 deps = [ sqlite ]; 265 }; 266 267 } // optionalAttrs x11Support { 268 269 tkinter = if stdenv.isCygwin then null else (buildInternalPythonModule { 270 moduleName = "tkinter"; 271 deps = [ tcl tk xlibsWrapper libX11 ]; 272 }); 273 274 } // { 275 276 readline = buildInternalPythonModule { 277 moduleName = "readline"; 278 internalName = "readline"; 279 deps = [ readline ]; 280 }; 281 282 }; 283 284in python // { inherit modules; }