summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authorDaiderd Jordan <daiderd@gmail.com>2017-07-08 22:21:32 +0200
committerDaiderd Jordan <daiderd@gmail.com>2017-07-08 22:22:17 +0200
commit980346592c07e565c90f947a68f4ea1a2f3e3dc2 (patch)
treee6b44f9a5458db30026c2a1645aa6e14db1b51fe /pkgs/build-support
parent800d44984f50947122fa39de559127e416f0ddc8 (diff)
parent7e3a1a58cf8e5bf6cac5811493389953090f678a (diff)
downloadnixlib-980346592c07e565c90f947a68f4ea1a2f3e3dc2.tar
nixlib-980346592c07e565c90f947a68f4ea1a2f3e3dc2.tar.gz
nixlib-980346592c07e565c90f947a68f4ea1a2f3e3dc2.tar.bz2
nixlib-980346592c07e565c90f947a68f4ea1a2f3e3dc2.tar.lz
nixlib-980346592c07e565c90f947a68f4ea1a2f3e3dc2.tar.xz
nixlib-980346592c07e565c90f947a68f4ea1a2f3e3dc2.tar.zst
nixlib-980346592c07e565c90f947a68f4ea1a2f3e3dc2.zip
Merge branch 'staging' into master
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix18
-rw-r--r--pkgs/build-support/cc-wrapper/expand-response-params.c84
-rw-r--r--pkgs/build-support/cc-wrapper/utils.sh56
-rw-r--r--pkgs/build-support/fetchgit/default.nix16
-rw-r--r--pkgs/build-support/fetchgit/gitrepotoname.nix14
-rwxr-xr-xpkgs/build-support/fetchgit/nix-prefetch-git4
6 files changed, 129 insertions, 63 deletions
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index e6576e5a3894..676fbd006881 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -10,6 +10,7 @@
 , zlib ? null, extraPackages ? [], extraBuildCommands ? ""
 , dyld ? null # TODO: should this be a setup-hook on dyld?
 , isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null
+, buildPackages ? {}, hostPlatform, targetPlatform
 , runCommand ? null
 }:
 
@@ -121,6 +122,17 @@ let
          null)
     else "";
 
+  expand-response-params = if buildPackages.stdenv.cc or null != null && buildPackages.stdenv.cc != "/dev/null"
+  then buildPackages.stdenv.mkDerivation {
+    name = "expand-response-params";
+    src = ./expand-response-params.c;
+    buildCommand = ''
+      # Work around "stdenv-darwin-boot-2 is not allowed to refer to path /nix/store/...-expand-response-params.c"
+      cp "$src" expand-response-params.c
+      "$CC" -std=c99 -O3 -o "$out" expand-response-params.c
+    '';
+  } else "";
+
 in
 
 stdenv.mkDerivation {
@@ -369,11 +381,13 @@ stdenv.mkDerivation {
     + ''
       substituteAll ${preWrap ./add-flags.sh} $out/nix-support/add-flags.sh
       substituteAll ${preWrap ./add-hardening.sh} $out/nix-support/add-hardening.sh
-      cp -p ${preWrap ./utils.sh} $out/nix-support/utils.sh
+      substituteAll ${preWrap ./utils.sh} $out/nix-support/utils.sh
     ''
     + extraBuildCommands;
 
-  inherit dynamicLinker;
+  inherit dynamicLinker expand-response-params;
+
+  expandResponseParams = expand-response-params; # for substitution in utils.sh
 
   crossAttrs = {
     shell = shell.crossDrv + shell.crossDrv.shellPath;
diff --git a/pkgs/build-support/cc-wrapper/expand-response-params.c b/pkgs/build-support/cc-wrapper/expand-response-params.c
new file mode 100644
index 000000000000..05b9c62b1e8d
--- /dev/null
+++ b/pkgs/build-support/cc-wrapper/expand-response-params.c
@@ -0,0 +1,84 @@
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct { char *data; size_t len, cap; } String;
+
+void resize(String *s, size_t len) {
+    s->len = len;
+    if (s->cap < s->len) {
+        s->cap = s->len * 2;
+        s->data = (char *)realloc(s->data, s->cap);
+        assert(s->data);
+    }
+}
+
+void append(String *s, const char *data, size_t len) {
+    resize(s, s->len + len);
+    memcpy(s->data + s->len - len, data, len);
+}
+
+typedef enum { space = 0, other = 1, backslash = 2, apostrophe = 3, quotation_mark = 4 } CharClass;
+typedef enum { outside, unq, unq_esc, sq, sq_esc, dq, dq_esc } State;
+
+// current State -> CharClass -> next State
+const State transitions[][5] = {
+    [outside] = {outside, unq, unq_esc, sq,  dq},
+    [unq]     = {outside, unq, unq_esc, sq,  dq},
+    [unq_esc] = {unq,     unq, unq,     unq, unq},
+    [sq]      = {sq,      sq,  sq_esc,  unq, sq},
+    [sq_esc]  = {sq,      sq,  sq,      sq,  sq},
+    [dq]      = {dq,      dq,  dq_esc,  dq,  unq},
+    [dq_esc]  = {dq,      dq,  dq,      dq,  dq},
+};
+
+CharClass charClass(int c) {
+    return c == '\\' ? backslash : c == '\'' ? apostrophe : c == '"' ? quotation_mark :
+            isspace(c) ? space : other;
+}
+
+// expandArg writes NULL-terminated expansions of `arg', a NULL-terminated
+// string, to stdout.  If arg does not begin with `@' or does not refer to a
+// file, it is written as is.  Otherwise the contents of the file are
+// recursively expanded.  On unexpected EOF in malformed response files an
+// incomplete final argument is written, even if it is empty, to parse like GCC.
+void expandArg(String *arg) {
+    FILE *f;
+    if (arg->data[0] != '@' || !(f = fopen(&arg->data[1], "r"))) {
+        fwrite(arg->data, 1, arg->len, stdout);
+        return;
+    }
+
+    resize(arg, 0);
+    State cur = outside;
+    int c;
+    do {
+        c = fgetc(f);
+        State next = transitions[cur][charClass(c)];
+        if ((cur == unq && next == outside) || (cur != outside && c == EOF)) {
+            append(arg, "", 1);
+            expandArg(arg);
+            resize(arg, 0);
+        } else if (cur == unq_esc || cur == sq_esc || cur == dq_esc ||
+                   (cur == outside ? next == unq : cur == next)) {
+            char s = c;
+            append(arg, &s, 1);
+        }
+        cur = next;
+    } while (c != EOF);
+
+    fclose(f);
+}
+
+int main(int argc, char **argv) {
+    String arg = { 0 };
+    while (*++argv) {
+        resize(&arg, 0);
+        append(&arg, *argv, strlen(*argv) + 1);
+        expandArg(&arg);
+    }
+    free(arg.data);
+    return EXIT_SUCCESS;
+}
diff --git a/pkgs/build-support/cc-wrapper/utils.sh b/pkgs/build-support/cc-wrapper/utils.sh
index 8cefc47816f8..87e48da9c8d5 100644
--- a/pkgs/build-support/cc-wrapper/utils.sh
+++ b/pkgs/build-support/cc-wrapper/utils.sh
@@ -23,52 +23,18 @@ badPath() {
         "${p:0:${#NIX_BUILD_TOP}}" != "$NIX_BUILD_TOP"
 }
 
-# @args.rsp parser.
-# Char classes: space, other, backslash, single quote, double quote.
-# States: 0 - outside, 1/2 - unquoted arg/slash, 3/4 - 'arg'/slash, 5/6 - "arg"/slash.
-# State transitions:
-rspT=(01235 01235 11111 33413 33333 55651 55555)
-# Push (a) arg or (c) char on transition:
-rspP[10]=a rspP[01]=c rspP[11]=c rspP[21]=c rspP[33]=c rspP[43]=c rspP[55]=c rspP[65]=c
-
-rspParse() {
-    rsp=()
-    local state=0
-    local arg=''
-    local c
-
-    while read -r -N1 c; do
-        local cls=1
-        case "$c" in
-            ' ' | $'\t' | $'\r' | $'\n') cls=0 ;;
-            '\') cls=2 ;;
-            "'") cls=3 ;;
-            '"') cls=4 ;;
-        esac
-        local nextstates="${rspT[$state]}"
-        local nextstate="${nextstates:$cls:1}"
-        case "${rspP[$state$nextstate]}" in
-            'c') arg+="$c" ;;
-            'a') rsp+=("$arg"); arg='' ;;
-        esac
-        state="$nextstate"
-    done
-
-    if [ "$state" -ne 0 ]; then
-        rsp+=("$arg")
-    fi
-}
-
 expandResponseParams() {
-    params=()
-    while [ $# -gt 0 ]; do
-        local p="$1"
-        shift
-        if [ "${p:0:1}" = '@' -a -e "${p:1}" ]; then
-            rspParse <"${p:1}"
-            set -- "${rsp[@]}" "$@"
-        else
-            params+=("$p")
+    params=("$@")
+    local arg
+    for arg in "$@"; do
+        if [[ "$arg" == @* ]]; then
+            if [ -n "@expandResponseParams@" ]; then
+                readarray -d '' params < <("@expandResponseParams@" "$@")
+                return 0
+            else
+                echo "Response files aren't supported during bootstrapping" >&2
+                return 1
+            fi
         fi
     done
 }
diff --git a/pkgs/build-support/fetchgit/default.nix b/pkgs/build-support/fetchgit/default.nix
index 8e060b87ebd3..57afb1c4ab87 100644
--- a/pkgs/build-support/fetchgit/default.nix
+++ b/pkgs/build-support/fetchgit/default.nix
@@ -1,21 +1,9 @@
-{stdenv, git, cacert}: let
-  urlToName = url: rev: let
-    inherit (stdenv.lib) removeSuffix splitString last;
-    base = last (splitString ":" (baseNameOf (removeSuffix "/" url)));
+{stdenv, git, cacert, gitRepoToName}:
 
-    matched = builtins.match "(.*).git" base;
-
-    short = builtins.substring 0 7 rev;
-
-    appendShort = if (builtins.match "[a-f0-9]*" rev) != null
-      then "-${short}"
-      else "";
-  in "${if matched == null then base else builtins.head matched}${appendShort}";
-in
 { url, rev ? "HEAD", md5 ? "", sha256 ? "", leaveDotGit ? deepClone
 , fetchSubmodules ? true, deepClone ? false
 , branchName ? null
-, name ? urlToName url rev
+, name ? gitRepoToName url rev
 , # Shell code executed after the file has been fetched
   # successfully. This can do things like check or transform the file.
   postFetch ? ""
diff --git a/pkgs/build-support/fetchgit/gitrepotoname.nix b/pkgs/build-support/fetchgit/gitrepotoname.nix
new file mode 100644
index 000000000000..9f4392c387f6
--- /dev/null
+++ b/pkgs/build-support/fetchgit/gitrepotoname.nix
@@ -0,0 +1,14 @@
+{ lib }:
+
+urlOrRepo: rev: let
+  inherit (lib) removeSuffix splitString last;
+  base = last (splitString ":" (baseNameOf (removeSuffix "/" urlOrRepo)));
+
+  matched = builtins.match "(.*).git" base;
+
+  short = builtins.substring 0 7 rev;
+
+  appendShort = if (builtins.match "[a-f0-9]*" rev) != null
+    then "-${short}"
+    else "";
+in "${if matched == null then base else builtins.head matched}${appendShort}"
\ No newline at end of file
diff --git a/pkgs/build-support/fetchgit/nix-prefetch-git b/pkgs/build-support/fetchgit/nix-prefetch-git
index fa66a1f55406..a180509a3265 100755
--- a/pkgs/build-support/fetchgit/nix-prefetch-git
+++ b/pkgs/build-support/fetchgit/nix-prefetch-git
@@ -283,8 +283,8 @@ _clone_user_rev() {
             if test -z "$(echo "$rev" | tr -d 0123456789abcdef)"; then
                 clone "$dir" "$url" "$rev" "" 1>&2
             else
-                echo 1>&2 "Bad commit hash or bad reference."
-                exit 1
+                # if revision is not hexadecimal it might be a tag
+                clone "$dir" "$url" "" "refs/tags/$rev" 1>&2
             fi;;
     esac