summary refs log tree commit diff
path: root/pkgs/build-support/buildenv
diff options
context:
space:
mode:
authorAlexey Shmalko <rasen.dubi@gmail.com>2016-07-09 23:47:15 +0300
committerNikolay Amiantov <ab@fmap.me>2016-07-13 03:54:11 +0300
commit0172558e8278eda2f08f9fc02ff831538548ced3 (patch)
treeb2b4fad03a987b3f9b74a94071c40fb46ebc3fd8 /pkgs/build-support/buildenv
parentf56a319e3ef1518274026d3350dfdca956a7ac1e (diff)
downloadnixpkgs-0172558e8278eda2f08f9fc02ff831538548ced3.tar
nixpkgs-0172558e8278eda2f08f9fc02ff831538548ced3.tar.gz
nixpkgs-0172558e8278eda2f08f9fc02ff831538548ced3.tar.bz2
nixpkgs-0172558e8278eda2f08f9fc02ff831538548ced3.tar.lz
nixpkgs-0172558e8278eda2f08f9fc02ff831538548ced3.tar.xz
nixpkgs-0172558e8278eda2f08f9fc02ff831538548ced3.tar.zst
nixpkgs-0172558e8278eda2f08f9fc02ff831538548ced3.zip
buildEnv: build the whole tree of directories to pathsToLink
This patch fixes #16614 and #16741.

The first issue was caused by the fact that both `/share` and
`/share/fish/vendor_completions.d` end in the `pathsToLink`. The
`pkgs/build-support/buildenv/builder.pl` creates `/share`, then links
`/share/fish` under `/share` and then tries to create the directory
`/share/fish/vendor_completions.d` and fails because it already exists.

The simplest way to reproduce the issue is to build the next Nix
expression:

```nix
let pkgs = import <nixpkgs> { };
in pkgs.buildEnv {
  name = "buildenv-issue";

  paths = [
    pkgs.fish
    pkgs.vim
  ];

  pathsToLink = [
    "/share"
    "/share/fish/vendor_completions.d"
  ];
}
```

The second issue is more critical and was caused by the fact findFiles
doesn't recurse deep enough. It stops at first unique directory for the
package (e.g., "/share" or even "/") and later the scripts decides it
shouldn't link it as it doesn't match pathsToLink (e.g., "/share/fish"),
so the result is empty.

The test:
```nix
let pkgs = import <nixpkgs> { };
in pkgs.buildEnv {
  name = "buildenv-issue";

  paths = [
    pkgs.fish
    pkgs.vim
  ];

  pathsToLink = [
    "/share/fish/functions"
  ];
}
```

or

```nix
let pkgs = import <nixpkgs> { };
in pkgs.buildEnv {
  name = "buildenv-issue";

  paths = [
    pkgs.vim
  ];

  pathsToLink = [
    "/share"
  ];
}
```
Diffstat (limited to 'pkgs/build-support/buildenv')
-rwxr-xr-xpkgs/build-support/buildenv/builder.pl18
1 files changed, 16 insertions, 2 deletions
diff --git a/pkgs/build-support/buildenv/builder.pl b/pkgs/build-support/buildenv/builder.pl
index f6cfe52dc31..678f5a3fe9e 100755
--- a/pkgs/build-support/buildenv/builder.pl
+++ b/pkgs/build-support/buildenv/builder.pl
@@ -31,9 +31,23 @@ sub isInPathsToLink {
 
 my %symlinks;
 
+# Add all pathsToLink and all parent directories.
+#
+# For "/a/b/c" that will include
+# [ "", "/a", "/a/b", "/a/b/c" ]
+#
+# That ensures the whole directory tree needed by pathsToLink is
+# created as directories and not symlinks.
+$symlinks{""} = ["", 0];
 for my $p (@pathsToLink) {
-    $p = "" if $p eq "/";
-    $symlinks{$p} = ["", 0];
+    my @parts = split '/', $p;
+
+    my $cur = "";
+    for my $x (@parts) {
+        $cur = $cur . "/$x";
+        $cur = "" if $cur eq "/";
+        $symlinks{$cur} = ["", 0];
+    }
 }
 
 sub findFiles;