From b84067f6db52acbc9080bb741a8075c754431e98 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Mon, 6 Aug 2018 03:29:53 -0700 Subject: cc: don't use sed to filter system directories - filtering using sed causes most builds to slow down quite a bit, as the compiler wrapper has to run sed many times, and *it* runs many times - do the system directory parsing directly in bash --- lib/spack/env/cc | 99 ++++++++++++++++++++++++++-------------------- lib/spack/spack/test/cc.py | 36 +++++++++++++++++ 2 files changed, 93 insertions(+), 42 deletions(-) (limited to 'lib') diff --git a/lib/spack/env/cc b/lib/spack/env/cc index 7a0033cb38..f056f0f98e 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -74,6 +74,18 @@ function die { exit 1 } +# test whether a path is a system directory +function system_dir { + path="$1" + for sd in ${SPACK_SYSTEM_DIRS[@]}; do + if [ "${path}" == "${sd}" -o "${path}" == "${sd}/" ]; then + # success if path starts with a system prefix + return 0 + fi + done + return 1 # fail if path starts no system prefix +} + for param in ${parameters[@]}; do if [[ -z ${!param} ]]; then die "Spack compiler must be run from Spack! Input '$param' is missing." @@ -255,21 +267,33 @@ args=() # includes=() libdirs=() -libs=() rpaths=() +system_includes=() +system_libdirs=() +system_rpaths=() +libs=() other_args=() while [ -n "$1" ]; do + rp="" case "$1" in -I*) arg="${1#-I}" if [ -z "$arg" ]; then shift; arg="$1"; fi - includes+=("$arg") + if system_dir "$arg"; then + system_includes+=("$arg") + else + includes+=("$arg") + fi ;; -L*) arg="${1#-L}" if [ -z "$arg" ]; then shift; arg="$1"; fi - libdirs+=("$arg") + if system_dir "$arg"; then + system_libdirs+=("$arg") + else + libdirs+=("$arg") + fi ;; -l*) arg="${1#-l}" @@ -280,15 +304,15 @@ while [ -n "$1" ]; do arg="${1#-Wl,}" if [ -z "$arg" ]; then shift; arg="$1"; fi if [[ "$arg" = -rpath=* ]]; then - rpaths+=("${arg#-rpath=}") + rp="${arg#-rpath=}" elif [[ "$arg" = -rpath,* ]]; then - rpaths+=("${arg#-rpath,}") + rp="${arg#-rpath,}" elif [[ "$arg" = -rpath ]]; then shift; arg="$1" if [[ "$arg" != -Wl,* ]]; then die "-Wl,-rpath was not followed by -Wl,*" fi - rpaths+=("${arg#-Wl,}") + rp="${arg#-Wl,}" else other_args+=("-Wl,$arg") fi @@ -297,13 +321,13 @@ while [ -n "$1" ]; do arg="${1#-Xlinker,}" if [ -z "$arg" ]; then shift; arg="$1"; fi if [[ "$arg" = -rpath=* ]]; then - rpaths+=("${arg#-rpath=}") + rp="${arg#-rpath=}" elif [[ "$arg" = -rpath ]]; then shift; arg="$1" if [[ "$arg" != -Xlinker,* ]]; then die "-Xlinker,-rpath was not followed by -Xlinker,*" fi - rpaths+=("${arg#-Xlinker,}") + rp="${arg#-Xlinker,}" else other_args+=("-Xlinker,$arg") fi @@ -314,7 +338,7 @@ while [ -n "$1" ]; do die "-Xlinker,-rpath was not followed by -Xlinker,*" fi shift 3; - rpaths+=("$1") + rp="$1" else other_args+=("$1") fi @@ -323,6 +347,15 @@ while [ -n "$1" ]; do other_args+=("$1") ;; esac + + # test rpaths against system directories in one place. + if [ -n "$rp" ]; then + if system_dir "$rp"; then + system_rpaths+=("$rp") + else + rpaths+=("$rp") + fi + fi shift done @@ -417,44 +450,26 @@ case "$mode" in ;; esac -# Filter system locations to the end of each sublist of args -# (includes, library dirs, rpaths) -for sd in ${SPACK_SYSTEM_DIRS[@]}; do - stripped_includes=`echo $includes | sed "s#\b$sd/\? \b##g"` - stripped_libdirs=`echo $libdirs | sed "s#\b$sd/\? \b##g"` - stripped_rpaths=`echo $rpaths | sed "s#\b$sd/\? \b##g"` - if [[ "$includes" != "$stripped_includes" ]]; then - $includes="$stripped_includes $sd" - fi - if [[ "$libdirs" != "$stripped_libdirs" ]]; then - $libdirs="$stripped_libdirs $sd" - fi - if [[ "$rpaths" != "$stripped_rpaths" ]]; then - $rpaths="$stripped_rpaths $sd" - fi -done - # Put the arguments back together in one list -# Includes first -for dir in "${includes[@]}"; do - args+=("-I$dir"); -done +# Includes and system includes first +for dir in "${includes[@]}"; do args+=("-I$dir"); done +for dir in "${system_includes[@]}"; do args+=("-I$dir"); done # Library search paths -for dir in "${libdirs[@]}"; do - args+=("-L$dir"); -done +for dir in "${libdirs[@]}"; do args+=("-L$dir"); done +for dir in "${system_libdirs[@]}"; do args+=("-L$dir"); done # RPATHs arguments -if [ "$mode" = ccld ]; then - for dir in "${rpaths[@]}"; do - args+=("$rpath$dir") - done -elif [ "$mode" = ld ]; then - for dir in "${rpaths[@]}"; do - args+=("-rpath" "$dir") - done -fi +case "$mode" in + ccld) + for dir in "${rpaths[@]}"; do args+=("$rpath$dir"); done + for dir in "${system_rpaths[@]}"; do args+=("$rpath$dir"); done + ;; + ld) + for dir in "${rpaths[@]}"; do args+=("-rpath" "$dir"); done + for dir in "${system_rpaths[@]}"; do args+=("-rpath" "$dir"); done + ;; +esac # Other arguments from the input command args+=("${other_args[@]}") diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py index 8435452642..3d06890f55 100644 --- a/lib/spack/spack/test/cc.py +++ b/lib/spack/spack/test/cc.py @@ -432,6 +432,42 @@ def test_cc_deps(dep1, dep2, dep3, dep4): test_args_without_paths) +def test_ccld_with_system_dirs(dep1, dep2, dep3, dep4): + """Ensure all flags are added in ccld mode.""" + deps = ':'.join((dep1, dep2, dep3, dep4)) + with set_env(SPACK_DEPENDENCIES=deps, + SPACK_RPATH_DEPS=deps, + SPACK_LINK_DEPS=deps): + + sys_path_args = ['-I/usr/include', + '-L/usr/local/lib', + '-Wl,-rpath,/usr/lib64', + '-I/usr/local/include', + '-L/lib64/'] + check_cc( + 'dump-args', sys_path_args + test_args, + [real_cc] + + test_include_paths + + ['-I' + dep1 + '/include', + '-I' + dep3 + '/include', + '-I' + dep4 + '/include'] + + ['-I/usr/include', + '-I/usr/local/include'] + + test_library_paths + + ['-L' + dep1 + '/lib', + '-L' + dep2 + '/lib64', + '-L' + dep3 + '/lib64'] + + ['-L/usr/local/lib', + '-L/lib64/'] + + test_wl_rpaths + + pkg_wl_rpaths + + ['-Wl,-rpath,' + dep1 + '/lib', + '-Wl,-rpath,' + dep2 + '/lib64', + '-Wl,-rpath,' + dep3 + '/lib64'] + + ['-Wl,-rpath,/usr/lib64'] + + test_args_without_paths) + + def test_ld_deps(dep1, dep2, dep3, dep4): """Ensure no (extra) -I args or -Wl, are passed in ld mode.""" deps = ':'.join((dep1, dep2, dep3, dep4)) -- cgit v1.2.3-70-g09d2