From ab730370ba807cc98d6d23325589dbf490833bd6 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Tue, 28 Jul 2015 14:06:06 +0300 Subject: [PATCH] chroot-env: simplify, clean directories structure --- .../build-support/build-fhs-chrootenv/env.nix | 146 +++++++----------- 1 file changed, 55 insertions(+), 91 deletions(-) diff --git a/pkgs/build-support/build-fhs-chrootenv/env.nix b/pkgs/build-support/build-fhs-chrootenv/env.nix index 9665c71d3dfd..3acb0c8e6b7d 100644 --- a/pkgs/build-support/build-fhs-chrootenv/env.nix +++ b/pkgs/build-support/build-fhs-chrootenv/env.nix @@ -1,61 +1,48 @@ { nixpkgs, nixpkgs_i686, system } : -{ name, pkgs ? [], profile ? "" -, targetPkgs ? null, multiPkgs ? null +{ name, profile ? "" +, pkgs ? null, targetPkgs ? pkgs: [], multiPkgs ? pkgs: [] , extraBuildCommands ? "", extraBuildCommandsMulti ? "" }: -assert pkgs != [] -> targetPkgs == null && multiPkgs == null; -assert targetPkgs != null -> multiPkgs != null; -assert multiPkgs != null -> targetPkgs != null; -assert targetPkgs != null -> pkgs == []; - - # HOWTO: -# If pkgs is defined buildFHSEnv will run in legacy mode. This means -# it will build all pkgs contained in pkgs and basePkgs and then just merge -# all of their contents together via buildEnv. +# All packages (most likely programs) returned from targetPkgs will only be +# installed once--matching the host's architecture (64bit on x86_64 and 32bit on +# x86). # -# The new way is to define both targetPkgs and multiPkgs. These two are -# functions which get a pkgs environment supplied and should then return a list -# of packages based this environment. -# For example: targetPkgs = pkgs: [ pkgs.nmap ]; -# -# All packages (most likely programs) placed in targetPkgs will only be -# installed once--matching the hosts architecture (64bit on x86_64 and 32bit on -# x86). These packages will populate the chroot directory tree. -# -# Packages (most likeley libraries) defined in multiPkgs will be installed once -# on x86 systems and twice on x86_64 systems. -# On x86 they will just be merge with the packages defined in targetPkgs. -# On x86_64 they will be added to targetPkgs and in addition their 32bit -# versions will also be installed. The final directory should look as follows: -# /lib will include 32bit libraries from multiPkgs -# /lib32 will link to /lib +# Packages (most likely libraries) returned from multiPkgs are installed +# once on x86 systems and twice on x86_64 systems. +# On x86 they are merged with packages from targetPkgs. +# On x86_64 they are added to targetPkgs and in addition their 32bit +# versions are also installed. The final directory structure looks as +# follows: +# /lib32 will include 32bit libraries from multiPkgs # /lib64 will include 64bit libraries from multiPkgs and targetPkgs -# /x86 will contain a complete 32bit environment composed by multiPkgs +# /lib will link to /lib32 let - is64Bit = system == "x86_64-linux"; - # enable multi builds on x86_64 hosts if pakgs_target/multi are defined - isMultiBuild = is64Bit && targetPkgs != null; + isMultiBuild = pkgs == null && multiPkgs != null && system == "x86_64-linux"; isTargetBuild = !isMultiBuild; - # list of packages (usually programs) which will only be installed for the - # hosts architecture - targetPaths = if targetPkgs == null - then pkgs - else targetPkgs nixpkgs ++ multiPkgs nixpkgs; + # support deprecated "pkgs" option. + targetPkgs' = + if pkgs != null + then builtins.trace "buildFHSEnv: 'pkgs' option is deprecated, use 'targetPkgs'" (pkgs': pkgs) + else targetPkgs; - # list of pckages which should be build for both x86 and x86_64 on x86_64 + # list of packages (usually programs) which are only be installed for the + # host's architecture + targetPaths = targetPkgs' nixpkgs ++ (if multiPkgs == null then [] else multiPkgs nixpkgs); + + # list of packages which are installed for both x86 and x86_64 on x86_64 # systems multiPaths = if isMultiBuild then multiPkgs nixpkgs_i686 else []; # base packages of the chroot - # these match the hosts architecture, gcc/glibc_multi will be choosen - # on multi builds + # these match the host's architecture, gcc/glibc_multi are used for multilib + # builds. chosenGcc = if isMultiBuild then nixpkgs.gcc_multi else nixpkgs.gcc; basePkgs = with nixpkgs; [ (if isMultiBuild then glibc_multi else glibc) @@ -73,11 +60,11 @@ let cd $out/etc # environment variables - cat >> profile << "EOF" + cat >> profile < links to the whole profile defined by multiPaths - # /lib, /lib32 -> links to 32bit binaries - # /lib64 -> links to 64bit binaries - # /usr/lib* -> same as above - setupMultiProfile = if isTargetBuild then "" else '' - mkdir -m0755 x86 - cd x86 - ${linkProfile staticUsrProfileMulti} - cd .. - ''; - # setup library paths only for the targeted architecture setupLibDirs_target = '' mkdir -m0755 lib # copy content of targetPaths - cp -rsf ${staticUsrProfileTarget}/lib/* lib/ + cp -rsHf ${staticUsrProfileTarget}/lib/* lib/ ''; # setup /lib, /lib32 and /lib64 setupLibDirs_multi = '' - mkdir -m0755 lib + mkdir -m0755 lib32 mkdir -m0755 lib64 - ln -s lib lib32 + ln -s lib32 lib # copy glibc stuff - cp -rsf ${staticUsrProfileTarget}/lib/32/* lib/ && chmod u+w -R lib/ + cp -rsHf ${staticUsrProfileTarget}/lib/32/* lib32/ && chmod u+w -R lib32/ # copy content of multiPaths (32bit libs) - [ -d ${staticUsrProfileMulti}/lib ] && cp -rsf ${staticUsrProfileMulti}/lib/* lib/ && chmod u+w -R lib/ + [ -d ${staticUsrProfileMulti}/lib ] && cp -rsHf ${staticUsrProfileMulti}/lib/* lib32/ && chmod u+w -R lib32/ # copy content of targetPaths (64bit libs) - cp -rsf ${staticUsrProfileTarget}/lib/* lib64/ && chmod u+w -R lib64/ + cp -rsHf ${staticUsrProfileTarget}/lib/* lib64/ && chmod u+w -R lib64/ # most 64bit only libs put their stuff into /lib - # some pkgs (like gcc_multi) put 32bit libs into and /lib 64bit libs into /lib64 + # some pkgs (like gcc_multi) put 32bit libs into /lib and 64bit libs into /lib64 # by overwriting these we will hopefully catch all these cases - # in the end /lib should only contain 32bit and /lib64 only 64bit libs - cp -rsf ${staticUsrProfileTarget}/lib64/* lib64/ && chmod u+w -R lib64/ + # in the end /lib32 should only contain 32bit and /lib64 only 64bit libs + cp -rsHf ${staticUsrProfileTarget}/lib64/* lib64/ && chmod u+w -R lib64/ - # copy gcc libs (and may overwrite exitsting wrongly placed libs) - cp -rsf ${chosenGcc.cc}/lib/* lib/ - cp -rsf ${chosenGcc.cc}/lib64/* lib64/ + # copy gcc libs + cp -rsHf ${chosenGcc.cc}/lib/* lib32/ + cp -rsHf ${chosenGcc.cc}/lib64/* lib64/ ''; setupLibDirs = if isTargetBuild then setupLibDirs_target else setupLibDirs_multi; - setupIncludeDir = '' - if [ -x "${staticUsrProfileTarget}/include" ] - then - ln -s "${staticUsrProfileTarget}/include" - fi - ''; - # the target profile is the actual profile that will be used for the chroot setupTargetProfile = '' - ${linkProfile staticUsrProfileTarget} - ${setupLibDirs} - mkdir -m0755 usr cd usr - ${linkProfile staticUsrProfileTarget} ${setupLibDirs} - ${setupIncludeDir} + for i in bin sbin share include; do + cp -r "${staticUsrProfileTarget}/$i" $i + done cd .. - rm -rf usr/etc usr/var + + for i in var etc; do + cp -r "${staticUsrProfileTarget}/$i" "$i" + done + for i in usr/{bin,sbin,lib,lib32,lib64}; do + if [ -x "$i" ]; then + ln -s "$i" + fi + done ''; in nixpkgs.stdenv.mkDerivation { @@ -210,7 +175,6 @@ in nixpkgs.stdenv.mkDerivation { mkdir -p $out cd $out ${setupTargetProfile} - ${setupMultiProfile} cd $out ${extraBuildCommands} cd $out