Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

Python: setuptools/wheel/pip now bootstrap from source

Since wheel support was introduced in 2015 we always relied on pre-built
wheels for bootstrapping. Now, we can bootstrap directly from the
sources of these packages in git.

The `bootstrapped-pip` packages is used to build `pip`, `setuptools` and `wheel`,
after which those packages are used to build everything else.

Note that when building `bootstrapped-pip` some errors are shown.
These are not important, the build actually does succeed and work as intended.

authored by Frederik Rietdijk and committed by Frederik Rietdijk 56727dc1 1fca2ab5

+79 -55
+36 -39
pkgs/development/python-modules/bootstrapped-pip/default.nix
··· 1 1 { stdenv, python, fetchPypi, makeWrapper, unzip, makeSetupHook 2 2 , pipInstallHook 3 3 , setuptoolsBuildHook 4 - 4 + , wheel, pip, setuptools 5 5 }: 6 6 7 - let 8 - wheel_source = fetchPypi { 9 - pname = "wheel"; 10 - version = "0.33.6"; 11 - format = "wheel"; 12 - sha256 = "f4da1763d3becf2e2cd92a14a7c920f0f00eca30fdde9ea992c836685b9faf28"; 13 - }; 14 - setuptools_source = fetchPypi { 15 - pname = "setuptools"; 16 - version = "41.4.0"; 17 - format = "wheel"; 18 - sha256 = "8d01f7ee4191d9fdcd9cc5796f75199deccb25b154eba82d44d6a042cf873670"; 19 - }; 20 - 21 - in stdenv.mkDerivation rec { 7 + stdenv.mkDerivation rec { 22 8 pname = "pip"; 23 - version = "19.3.1"; 9 + inherit (pip) version; 24 10 name = "${python.libPrefix}-bootstrapped-${pname}-${version}"; 25 11 26 - src = fetchPypi { 27 - inherit pname version; 28 - format = "wheel"; 29 - sha256 = "6917c65fc3769ecdc61405d3dfd97afdedd75808d200b2838d7d961cebc0c2c7"; 30 - }; 12 + srcs = [ wheel.src pip.src setuptools.src ]; 13 + sourceRoot = "."; 31 14 32 15 dontUseSetuptoolsBuild = true; 16 + dontUsePipInstall = true; 33 17 34 18 # Should be propagatedNativeBuildInputs 35 19 propagatedBuildInputs = [ ··· 38 22 (setuptoolsBuildHook.override{setuptools=null; wheel=null;}) 39 23 ]; 40 24 41 - unpackPhase = '' 42 - mkdir -p $out/${python.sitePackages} 43 - unzip -d $out/${python.sitePackages} $src 44 - unzip -d $out/${python.sitePackages} ${setuptools_source} 45 - unzip -d $out/${python.sitePackages} ${wheel_source} 46 - ''; 47 - 48 25 postPatch = '' 49 26 mkdir -p $out/bin 50 27 ''; ··· 52 29 nativeBuildInputs = [ makeWrapper unzip ]; 53 30 buildInputs = [ python ]; 54 31 55 - installPhase = '' 32 + buildPhase = ":"; 33 + 34 + installPhase = stdenv.lib.strings.optionalString (!stdenv.hostPlatform.isWindows) '' 35 + export SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES=0 36 + '' + '' 37 + # Give folders a known name 38 + mv pip* pip 39 + mv setuptools* setuptools 40 + mv wheel* wheel 41 + # Set up PYTHONPATH. The above folders need to be on PYTHONPATH 42 + # $out is where we are installing to and takes precedence 43 + export PYTHONPATH="$out/${python.sitePackages}:$(pwd)/pip/src:$(pwd)/setuptools:$(pwd)/setuptools/pkg_resources:$(pwd)/wheel" 44 + 45 + echo "Building setuptools wheel..." 46 + pushd setuptools 47 + ${python.pythonForBuild.interpreter} -m pip install --no-build-isolation --no-index --prefix=$out --ignore-installed --no-dependencies --no-cache --build tmpbuild . 48 + popd 56 49 57 - # install pip binary 58 - echo '#!${python.interpreter}' > $out/bin/pip 59 - echo 'import sys;from pip._internal import main' >> $out/bin/pip 60 - echo 'sys.exit(main())' >> $out/bin/pip 61 - chmod +x $out/bin/pip 50 + echo "Building wheel wheel..." 51 + pushd wheel 52 + ${python.pythonForBuild.interpreter} -m pip install --no-build-isolation --no-index --prefix=$out --ignore-installed --no-dependencies --no-cache --build tmpbuild . 53 + popd 62 54 63 - # wrap binaries with PYTHONPATH 64 - for f in $out/bin/*; do 65 - wrapProgram $f --prefix PYTHONPATH ":" $out/${python.sitePackages}/ 66 - done 55 + echo "Building pip wheel..." 56 + pushd pip 57 + ${python.pythonForBuild.interpreter} -m pip install --no-build-isolation --no-index --prefix=$out --ignore-installed --no-dependencies --no-cache --build tmpbuild . 58 + popd 67 59 ''; 68 60 61 + meta = { 62 + description = "Version of pip used for bootstrapping"; 63 + license = stdenv.lib.unique (pip.meta.license ++ setuptools.meta.license ++ wheel.meta.license); 64 + homepage = pip.meta.homepage; 65 + }; 69 66 }
+8 -5
pkgs/development/python-modules/pip/default.nix
··· 2 2 , python 3 3 , buildPythonPackage 4 4 , bootstrapped-pip 5 - , fetchPypi 5 + , fetchFromGitHub 6 6 , mock 7 7 , scripttest 8 8 , virtualenv ··· 17 17 version = "19.3.1"; 18 18 format = "other"; 19 19 20 - src = fetchPypi { 21 - inherit pname version; 22 - sha256 = "21207d76c1031e517668898a6b46a9fb1501c7a4710ef5dfd6a40ad9e6757ea7"; 20 + src = fetchFromGitHub { 21 + owner = "pypa"; 22 + repo = pname; 23 + rev = version; 24 + sha256 = "079gz0v37ah1l4i5iwyfb0d3mni422yv5ynnxa0wcqpnvkc7sfnw"; 25 + name = "${pname}-${version}-source"; 23 26 }; 24 27 25 28 nativeBuildInputs = [ bootstrapped-pip ]; ··· 34 37 35 38 meta = { 36 39 description = "The PyPA recommended tool for installing Python packages"; 37 - license = lib.licenses.mit; 40 + license = with lib.licenses; [ mit ]; 38 41 homepage = https://pip.pypa.io/; 39 42 priority = 10; 40 43 };
+28 -7
pkgs/development/python-modules/setuptools/default.nix
··· 1 1 { stdenv 2 2 , buildPythonPackage 3 - , fetchPypi 3 + , fetchFromGitHub 4 4 , python 5 5 , wrapPython 6 6 , unzip ··· 11 11 , setuptoolsBuildHook 12 12 }: 13 13 14 - buildPythonPackage rec { 14 + let 15 15 pname = "setuptools"; 16 16 version = "41.4.0"; 17 + 18 + # Create an sdist of setuptools 19 + sdist = stdenv.mkDerivation rec { 20 + name = "${pname}-${version}-sdist.tar.gz"; 21 + 22 + src = fetchFromGitHub { 23 + owner = "pypa"; 24 + repo = pname; 25 + rev = "v${version}"; 26 + sha256 = "0asxfnsi56r81lm48ynqbfkmm3kvw2jwrlf2l9azn5w6xm30jvp5"; 27 + name = "${pname}-${version}-source"; 28 + }; 29 + 30 + buildPhase = '' 31 + ${python.pythonForBuild.interpreter} bootstrap.py 32 + ${python.pythonForBuild.interpreter} setup.py sdist --formats=gztar 33 + ''; 34 + 35 + installPhase = '' 36 + echo "Moving sdist..." 37 + mv dist/*.tar.gz $out 38 + ''; 39 + }; 40 + in buildPythonPackage rec { 41 + inherit pname version; 17 42 # Because of bootstrapping we don't use the setuptoolsBuildHook that comes with format="setuptools" directly. 18 43 # Instead, we override it to remove setuptools to avoid a circular dependency. 19 44 # The same is done for pip and the pipInstallHook. 20 45 format = "other"; 21 46 22 - src = fetchPypi { 23 - inherit pname version; 24 - extension = "zip"; 25 - sha256 = "7eae782ccf36b790c21bde7d86a4f303a441cd77036b25c559a602cf5186ce4d"; 26 - }; 47 + src = sdist; 27 48 28 49 nativeBuildInputs = [ 29 50 bootstrapped-pip
+7 -4
pkgs/development/python-modules/wheel/default.nix
··· 2 2 , setuptools 3 3 , pip 4 4 , buildPythonPackage 5 - , fetchPypi 5 + , fetchFromGitHub 6 6 , pytest 7 7 , pytestcov 8 8 , coverage ··· 15 15 version = "0.33.6"; 16 16 format = "other"; 17 17 18 - src = fetchPypi { 19 - inherit pname version; 20 - sha256 = "10c9da68765315ed98850f8e048347c3eb06dd81822dc2ab1d4fde9dc9702646"; 18 + src = fetchFromGitHub { 19 + owner = "pypa"; 20 + repo = pname; 21 + rev = version; 22 + sha256 = "1bg4bxazsjxp621ymaykd8l75k7rvcvwawlipmjk7nsrl72l4p0s"; 23 + name = "${pname}-${version}-source"; 21 24 }; 22 25 23 26 checkInputs = [ pytest pytestcov coverage ];