diff options
author | Harmen Stoppels <harmenstoppels@gmail.com> | 2023-03-08 09:03:31 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-08 09:03:31 +0100 |
commit | c37d6f97dcf252b9e215b288af7a1af38dc8d2bc (patch) | |
tree | 1804e987cf11a3444454cb0ca2d87236aa2d8d8a | |
parent | ec73157a3446d8e309cdab32fc4ea40b349b72e4 (diff) | |
download | spack-c37d6f97dcf252b9e215b288af7a1af38dc8d2bc.tar.gz spack-c37d6f97dcf252b9e215b288af7a1af38dc8d2bc.tar.bz2 spack-c37d6f97dcf252b9e215b288af7a1af38dc8d2bc.tar.xz spack-c37d6f97dcf252b9e215b288af7a1af38dc8d2bc.zip |
compiler wrapper: parse Wl and Xlinker properly (#35912)
Two fixes:
1. `-Wl,a,b,c,d` is a comma separated list of linker arguments, we
incorrectly assume key/value pairs, which runs into issues with for
example `-Wl,--enable-new-dtags,-rpath,/x`
2. `-Xlinker,xxx` is not a think, so it shouldn't be parsed.
-rwxr-xr-x | lib/spack/env/cc | 93 | ||||
-rw-r--r-- | lib/spack/spack/test/build_environment.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/test/cc.py | 10 |
3 files changed, 57 insertions, 50 deletions
diff --git a/lib/spack/env/cc b/lib/spack/env/cc index 55b79c5290..0f3b860d79 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -427,6 +427,48 @@ isystem_include_dirs_list="" libs_list="" other_args_list="" +# Global state for keeping track of -Wl,-rpath -Wl,/path +wl_expect_rpath=no + +parse_Wl() { + # drop -Wl + shift + while [ $# -ne 0 ]; do + if [ "$wl_expect_rpath" = yes ]; then + rp="$1" + wl_expect_rpath=no + else + rp="" + case "$1" in + -rpath=*) + rp="${1#-rpath=}" + ;; + --rpath=*) + rp="${1#--rpath=}" + ;; + -rpath|--rpath) + wl_expect_rpath=yes + ;; + "$dtags_to_strip") + ;; + *) + append other_args_list "-Wl,$1" + ;; + esac + fi + if [ -n "$rp" ]; then + if system_dir "$rp"; then + append system_rpath_dirs_list "$rp" + else + append rpath_dirs_list "$rp" + fi + fi + shift + done + # By lack of local variables, always set this to empty string. + rp="" +} + while [ $# -ne 0 ]; do @@ -526,54 +568,9 @@ while [ $# -ne 0 ]; do append other_args_list "-l$arg" ;; -Wl,*) - arg="${1#-Wl,}" - if [ -z "$arg" ]; then shift; arg="$1"; fi - case "$arg" in - -rpath=*) rp="${arg#-rpath=}" ;; - --rpath=*) rp="${arg#--rpath=}" ;; - -rpath,*) rp="${arg#-rpath,}" ;; - --rpath,*) rp="${arg#--rpath,}" ;; - -rpath|--rpath) - shift; arg="$1" - case "$arg" in - -Wl,*) - rp="${arg#-Wl,}" - ;; - *) - die "-Wl,-rpath was not followed by -Wl,*" - ;; - esac - ;; - "$dtags_to_strip") - : # We want to remove explicitly this flag - ;; - *) - append other_args_list "-Wl,$arg" - ;; - esac - ;; - -Xlinker,*) - arg="${1#-Xlinker,}" - if [ -z "$arg" ]; then shift; arg="$1"; fi - - case "$arg" in - -rpath=*) rp="${arg#-rpath=}" ;; - --rpath=*) rp="${arg#--rpath=}" ;; - -rpath|--rpath) - shift; arg="$1" - case "$arg" in - -Xlinker,*) - rp="${arg#-Xlinker,}" - ;; - *) - die "-Xlinker,-rpath was not followed by -Xlinker,*" - ;; - esac - ;; - *) - append other_args_list "-Xlinker,$arg" - ;; - esac + IFS=, + parse_Wl $1 + unset IFS ;; -Xlinker) if [ "$2" = "-rpath" ]; then diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index e0ab530fa8..5f450e7d7f 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -127,13 +127,13 @@ def test_static_to_shared_library(build_environment): "linux": ( "/bin/mycc -shared" " -Wl,--disable-new-dtags" - " -Wl,-soname,{2} -Wl,--whole-archive {0}" + " -Wl,-soname -Wl,{2} -Wl,--whole-archive {0}" " -Wl,--no-whole-archive -o {1}" ), "darwin": ( "/bin/mycc -dynamiclib" " -Wl,--disable-new-dtags" - " -install_name {1} -Wl,-force_load,{0} -o {1}" + " -install_name {1} -Wl,-force_load -Wl,{0} -o {1}" ), } diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py index 48dd7fd8a0..f93b388c12 100644 --- a/lib/spack/spack/test/cc.py +++ b/lib/spack/spack/test/cc.py @@ -342,6 +342,16 @@ def test_fc_flags(wrapper_environment, wrapper_flags): ) +def test_Wl_parsing(wrapper_environment): + check_args( + cc, + ["-Wl,-rpath,/a,--enable-new-dtags,-rpath=/b,--rpath", "-Wl,/c"], + [real_cc] + + target_args + + ["-Wl,--disable-new-dtags", "-Wl,-rpath,/a", "-Wl,-rpath,/b", "-Wl,-rpath,/c"], + ) + + def test_dep_rpath(wrapper_environment): """Ensure RPATHs for root package are added.""" check_args(cc, test_args, [real_cc] + target_args + common_compile_args) |