diff options
author | Tobias Bergkvist <tobias@bergkv.ist> | 2021-08-23 23:44:57 +0200 |
---|---|---|
committer | Tobias Bergkvist <tobias@bergkv.ist> | 2021-08-23 23:44:57 +0200 |
commit | dcba4171d4a7150cbaf90cae7a3e12a8381067a7 (patch) | |
tree | 7b2b025acbf675b23b37d4b8c24bab23c2a9759d /pkgs/build-support/setup-hooks | |
parent | 1d6428140194b5bac68266ca11a441ed6f63571c (diff) | |
download | nixpkgs-dcba4171d4a7150cbaf90cae7a3e12a8381067a7.tar nixpkgs-dcba4171d4a7150cbaf90cae7a3e12a8381067a7.tar.gz nixpkgs-dcba4171d4a7150cbaf90cae7a3e12a8381067a7.tar.bz2 nixpkgs-dcba4171d4a7150cbaf90cae7a3e12a8381067a7.tar.lz nixpkgs-dcba4171d4a7150cbaf90cae7a3e12a8381067a7.tar.xz nixpkgs-dcba4171d4a7150cbaf90cae7a3e12a8381067a7.tar.zst nixpkgs-dcba4171d4a7150cbaf90cae7a3e12a8381067a7.zip |
Add support for --add-flags, --prefix and --suffix
Diffstat (limited to 'pkgs/build-support/setup-hooks')
-rw-r--r-- | pkgs/build-support/setup-hooks/make-binary-wrapper.sh | 124 |
1 files changed, 109 insertions, 15 deletions
diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index 33310948333..f19edd483cf 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -4,17 +4,21 @@ # ARGS: # --argv0 NAME : set name of executed process to NAME -# (defaults to EXECUTABLE) +# (otherwise it’s called …-wrapped) # --set VAR VAL : add VAR with value VAL to the executable’s # environment # --set-default VAR VAL : like --set, but only adds VAR if not already set in # the environment # --unset VAR : remove VAR from the environment -# +# --add-flags FLAGS : add FLAGS to invocation of executable + +# --prefix ENV SEP VAL : suffix/prefix ENV with VAL, separated by SEP +# --suffix + # To troubleshoot a binary wrapper after you compiled it, # use the `strings` command or open the binary file in a text editor. makeBinaryWrapper() { - makeDocumentedCWrapper "$1" "${@:3}" | gcc -x c -o "$2" - + makeDocumentedCWrapper "$1" "${@:3}" | gcc -Os -x c -o "$2" - } # Generate source code for the wrapper in such a way that the wrapper source code @@ -31,27 +35,39 @@ makeDocumentedCWrapper() { # makeCWrapper EXECUTABLE ARGS # ARGS: same as makeBinaryWrapper makeCWrapper() { - local argv0 n params cmd + local argv0 n params cmd main flagsBefore flags local executable=$(escapeStringLiteral "$1") local params=("$@") - printf "%s\n" "#include <unistd.h>" - printf "%s\n" "#include <stdlib.h>" - printf "\n%s\n" "int main(int argc, char **argv) {" - for ((n = 1; n < ${#params[*]}; n += 1)); do p="${params[$n]}" if [[ "$p" == "--set" ]]; then cmd=$(setEnv "${params[$((n + 1))]}" "${params[$((n + 2))]}") + main="$main $cmd"$'\n' n=$((n + 2)) - printf "%s\n" " $cmd" elif [[ "$p" == "--set-default" ]]; then cmd=$(setDefaultEnv "${params[$((n + 1))]}" "${params[$((n + 2))]}") + main="$main $cmd"$'\n' n=$((n + 2)) - printf "%s\n" " $cmd" elif [[ "$p" == "--unset" ]]; then cmd=$(unsetEnv "${params[$((n + 1))]}") - printf "%s\n" " $cmd" + main="$main $cmd"$'\n' + n=$((n + 1)) + elif [[ "$p" == "--prefix" ]]; then + cmd=$(setEnvPrefix "${params[$((n + 1))]}" "${params[$((n + 2))]}" "${params[$((n + 3))]}") + main="$main $cmd"$'\n' + uses_prefix=1 + uses_concat3=1 + n=$((n + 3)) + elif [[ "$p" == "--suffix" ]]; then + cmd=$(setEnvSuffix "${params[$((n + 1))]}" "${params[$((n + 2))]}" "${params[$((n + 3))]}") + main="$main $cmd"$'\n' + uses_suffix=1 + uses_concat3=1 + n=$((n + 3)) + elif [[ "$p" == "--add-flags" ]]; then + flags="${params[$((n + 1))]}" + flagsBefore="$flagsBefore $flags" n=$((n + 1)) elif [[ "$p" == "--argv0" ]]; then argv0=$(escapeStringLiteral "${params[$((n + 1))]}") @@ -61,17 +77,63 @@ makeCWrapper() { printf "%s\n" " #error makeCWrapper did not understand argument ${p}" fi done + [ -z ${flagsBefore+"1"} ] || { + flagsBefore=("$flagsBefore") + main="$main"$'\n'$(addFlags $flagsBefore)$'\n'$'\n' + } - printf "%s\n" " argv[0] = \"${argv0:-${executable}}\";" - printf "%s\n" " return execv(\"${executable}\", argv);" - printf "%s\n" "}" + main="$main argv[0] = \"${argv0:-${executable}}\";"$'\n' + main="$main return execv(\"${executable}\", argv);"$'\n' + + printf "%s\n" "#include <unistd.h>" + printf "%s\n" "#include <stdlib.h>" + [ -z "$uses_concat3" ] || printf "\n%s\n" "$(concat3Fn)" + [ -z "$uses_prefix" ] || printf "\n%s\n" "$(setEnvPrefixFn)" + [ -z "$uses_suffix" ] || printf "\n%s\n" "$(setEnvSuffixFn)" + printf "\n%s" "int main(int argc, char **argv) {" + printf "\n%s" "$main" + printf "%s" "}" +} + +addFlags() { + local result n flag flags + local var="argv_tmp" + flags=("$@") + for ((n = 0; n < ${#flags[*]}; n += 1)); do + flag=$(escapeStringLiteral "${flags[((n))]}") + result="$result $var[$((n+1))] = \"$flag\";"$'\n' + done + printf " %s\n" "char **$var = malloc(sizeof(*$var) * ($((n+1)) + argc));" + printf " %s\n" "$var[0] = argv[0];" + printf "%s" "$result" + printf " %s\n" "for (int i = 1; i < argc; ++i) {" + printf " %s\n" " $var[$n + i] = argv[i];" + printf " %s\n" "}" + printf " %s\n" "$var[$n + argc] = NULL;" + printf " %s\n" "argv = $var;" +} + +# prefix ENV SEP VAL +setEnvPrefix() { + local env=$(escapeStringLiteral "$1") + local sep=$(escapeStringLiteral "$2") + local val=$(escapeStringLiteral "$3") + printf "%s" "set_env_prefix(\"$env\", \"$sep\", \"$val\");" +} + +# suffix ENV SEP VAL +setEnvSuffix() { + local env=$(escapeStringLiteral "$1") + local sep=$(escapeStringLiteral "$2") + local val=$(escapeStringLiteral "$3") + printf "%s" "set_env_suffix(\"$env\", \"$sep\", \"$val\");" } # setEnv KEY VALUE setEnv() { local key=$(escapeStringLiteral "$1") local value=$(escapeStringLiteral "$2") - printf "%s" "putenv(\"${key}=${value}\");" + printf "%s" "putenv(\"$key=$value\");" } # setDefaultEnv KEY VALUE @@ -104,3 +166,35 @@ escapeStringLiteral() { result=${result//$'\r'/"\r"} printf "%s" "$result" } + +concat3Fn() { + printf "%s\n" 'char *concat3(char *x, char *y, char *z) {' + printf "%s\n" ' int xn = 0; while(x[++xn]);' + printf "%s\n" ' int yn = 0; while(y[++yn]);' + printf "%s\n" ' int zn = 0; while(z[++zn]);' + printf "%s\n" ' char *res = malloc(sizeof(*res)*(xn + yn + zn + 1));' + printf "%s\n" ' for (int i = 0; i < xn; ++i) res[i] = x[i];' + printf "%s\n" ' for (int i = 0; i < yn; ++i) res[xn+i] = y[i];' + printf "%s\n" ' for (int i = 0; i < zn; ++i) res[xn+yn+i] = z[i];' + printf "%s\n" " res[xn+yn+zn] = '\0';" + printf "%s\n" ' return res;' + printf "%s\n" '}' +} + +setEnvPrefixFn() { + printf "%s\n" 'void set_env_prefix(char *env, char *sep, char *val) {' + printf "%s\n" ' char *existing = getenv(env);' + printf "%s\n" ' if (existing) val = concat3(val, sep, existing);' + printf "%s\n" ' setenv(env, val, 1);' + printf "%s\n" ' if (existing) free(val);' + printf "%s\n" '}' +} + +setEnvSuffixFn() { + printf "%s\n" 'void set_env_suffix(char *env, char *sep, char *val) {' + printf "%s\n" ' char *existing = getenv(env);' + printf "%s\n" ' if (existing) val = concat3(existing, sep, val);' + printf "%s\n" ' setenv(env, val, 1);' + printf "%s\n" ' if (existing) free(val);' + printf "%s\n" '}' +} |