compiler wrapper: prioritize spack store paths in -L, -I, -rpath (#43593)
* compiler wrapper: prioritize spack managed paths in search order
This commit partitions search paths of -L, -I (and -rpath) into three
groups, from highest priority to lowest:
1. Spack managed directories: these include absolute paths such as
   stores and the stage dir, as well as all relative paths since they
   are relative to a Spack owned dir
2. Non-system dirs: these are for externals that live in non-system
   locations
3. System dirs: your typical `/usr/lib` etc.
It's very easy for Spack to known the prefixes it owns, it's much more
difficult to tell system dirs from non-system dirs. Before this commit
Spack tried to distinguish only system and non-system dirs, and failed
for very trivial cases like `/usr/lib/x/..` which comes up often, since
build systems sometimes copy search paths from `gcc -print-search-dirs`.
Potentially this implementation is even faster than the current state of
things, since a loop over paths is replaced with an eval'ed `case ...`.
* Trigger a pipeline
* Revert "Trigger a pipeline"
This reverts commit 5d7fa863de.
* remove redudant return statement
			
			
This commit is contained in:
		
							
								
								
									
										244
									
								
								lib/spack/env/cc
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										244
									
								
								lib/spack/env/cc
									
									
									
									
										vendored
									
									
								
							@@ -47,7 +47,8 @@ SPACK_F77_RPATH_ARG
 | 
			
		||||
SPACK_FC_RPATH_ARG
 | 
			
		||||
SPACK_LINKER_ARG
 | 
			
		||||
SPACK_SHORT_SPEC
 | 
			
		||||
SPACK_SYSTEM_DIRS"
 | 
			
		||||
SPACK_SYSTEM_DIRS
 | 
			
		||||
SPACK_MANAGED_DIRS"
 | 
			
		||||
 | 
			
		||||
# Optional parameters that aren't required to be set
 | 
			
		||||
 | 
			
		||||
@@ -173,21 +174,17 @@ preextend() {
 | 
			
		||||
    unset IFS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# system_dir PATH
 | 
			
		||||
# test whether a path is a system directory
 | 
			
		||||
system_dir() {
 | 
			
		||||
    IFS=':'  # SPACK_SYSTEM_DIRS is colon-separated
 | 
			
		||||
    path="$1"
 | 
			
		||||
    for sd in $SPACK_SYSTEM_DIRS; do
 | 
			
		||||
        if [ "${path}" = "${sd}" ] || [ "${path}" = "${sd}/" ]; then
 | 
			
		||||
            # success if path starts with a system prefix
 | 
			
		||||
            unset IFS
 | 
			
		||||
            return 0
 | 
			
		||||
        fi
 | 
			
		||||
    done
 | 
			
		||||
    unset IFS
 | 
			
		||||
    return 1  # fail if path starts no system prefix
 | 
			
		||||
# eval this because SPACK_MANAGED_DIRS and SPACK_SYSTEM_DIRS are inputs we don't wanna loop over.
 | 
			
		||||
# moving the eval inside the function would eval it every call.
 | 
			
		||||
eval "\
 | 
			
		||||
path_order() {
 | 
			
		||||
case \"\$1\" in
 | 
			
		||||
    $SPACK_MANAGED_DIRS) return 0 ;;
 | 
			
		||||
    $SPACK_SYSTEM_DIRS) return 2 ;;
 | 
			
		||||
    /*) return 1 ;;
 | 
			
		||||
esac
 | 
			
		||||
}
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
# Fail with a clear message if the input contains any bell characters.
 | 
			
		||||
if eval "[ \"\${*#*${lsep}}\" != \"\$*\" ]"; then
 | 
			
		||||
@@ -420,11 +417,12 @@ input_command="$*"
 | 
			
		||||
parse_Wl() {
 | 
			
		||||
    while [ $# -ne 0 ]; do
 | 
			
		||||
    if [ "$wl_expect_rpath" = yes ]; then
 | 
			
		||||
        if system_dir "$1"; then
 | 
			
		||||
            append return_system_rpath_dirs_list "$1"
 | 
			
		||||
        else
 | 
			
		||||
            append return_rpath_dirs_list "$1"
 | 
			
		||||
        fi
 | 
			
		||||
        path_order "$1"
 | 
			
		||||
        case $? in
 | 
			
		||||
            0) append return_spack_store_rpath_dirs_list "$1" ;;
 | 
			
		||||
            1) append return_rpath_dirs_list "$1" ;;
 | 
			
		||||
            2) append return_system_rpath_dirs_list "$1" ;;
 | 
			
		||||
        esac
 | 
			
		||||
        wl_expect_rpath=no
 | 
			
		||||
    else
 | 
			
		||||
        case "$1" in
 | 
			
		||||
@@ -432,21 +430,25 @@ parse_Wl() {
 | 
			
		||||
                arg="${1#-rpath=}"
 | 
			
		||||
                if [ -z "$arg" ]; then
 | 
			
		||||
                    shift; continue
 | 
			
		||||
                elif system_dir "$arg"; then
 | 
			
		||||
                    append return_system_rpath_dirs_list "$arg"
 | 
			
		||||
                else
 | 
			
		||||
                    append return_rpath_dirs_list "$arg"
 | 
			
		||||
                fi
 | 
			
		||||
                path_order "$arg"
 | 
			
		||||
                case $? in
 | 
			
		||||
                    0) append return_spack_store_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                    1) append return_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                    2) append return_system_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                esac
 | 
			
		||||
                ;;
 | 
			
		||||
            --rpath=*)
 | 
			
		||||
                arg="${1#--rpath=}"
 | 
			
		||||
                if [ -z "$arg" ]; then
 | 
			
		||||
                    shift; continue
 | 
			
		||||
                elif system_dir "$arg"; then
 | 
			
		||||
                    append return_system_rpath_dirs_list "$arg"
 | 
			
		||||
                else
 | 
			
		||||
                    append return_rpath_dirs_list "$arg"
 | 
			
		||||
                fi
 | 
			
		||||
                path_order "$arg"
 | 
			
		||||
                case $? in
 | 
			
		||||
                    0) append return_spack_store_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                    1) append return_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                    2) append return_system_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                esac
 | 
			
		||||
                ;;
 | 
			
		||||
            -rpath|--rpath)
 | 
			
		||||
                wl_expect_rpath=yes
 | 
			
		||||
@@ -473,12 +475,20 @@ categorize_arguments() {
 | 
			
		||||
 | 
			
		||||
    return_other_args_list=""
 | 
			
		||||
    return_isystem_was_used=""
 | 
			
		||||
 | 
			
		||||
    return_isystem_spack_store_include_dirs_list=""
 | 
			
		||||
    return_isystem_system_include_dirs_list=""
 | 
			
		||||
    return_isystem_include_dirs_list=""
 | 
			
		||||
 | 
			
		||||
    return_spack_store_include_dirs_list=""
 | 
			
		||||
    return_system_include_dirs_list=""
 | 
			
		||||
    return_include_dirs_list=""
 | 
			
		||||
 | 
			
		||||
    return_spack_store_lib_dirs_list=""
 | 
			
		||||
    return_system_lib_dirs_list=""
 | 
			
		||||
    return_lib_dirs_list=""
 | 
			
		||||
 | 
			
		||||
    return_spack_store_rpath_dirs_list=""
 | 
			
		||||
    return_system_rpath_dirs_list=""
 | 
			
		||||
    return_rpath_dirs_list=""
 | 
			
		||||
 | 
			
		||||
@@ -546,29 +556,32 @@ categorize_arguments() {
 | 
			
		||||
                arg="${1#-isystem}"
 | 
			
		||||
                return_isystem_was_used=true
 | 
			
		||||
                if [ -z "$arg" ]; then shift; arg="$1"; fi
 | 
			
		||||
                if system_dir "$arg"; then
 | 
			
		||||
                    append return_isystem_system_include_dirs_list "$arg"
 | 
			
		||||
                else
 | 
			
		||||
                    append return_isystem_include_dirs_list "$arg"
 | 
			
		||||
                fi
 | 
			
		||||
                path_order "$arg"
 | 
			
		||||
                case $? in
 | 
			
		||||
                    0) append return_isystem_spack_store_include_dirs_list "$arg" ;;
 | 
			
		||||
                    1) append return_isystem_include_dirs_list "$arg" ;;
 | 
			
		||||
                    2) append return_isystem_system_include_dirs_list "$arg" ;;
 | 
			
		||||
                esac
 | 
			
		||||
                ;;
 | 
			
		||||
            -I*)
 | 
			
		||||
                arg="${1#-I}"
 | 
			
		||||
                if [ -z "$arg" ]; then shift; arg="$1"; fi
 | 
			
		||||
                if system_dir "$arg"; then
 | 
			
		||||
                    append return_system_include_dirs_list "$arg"
 | 
			
		||||
                else
 | 
			
		||||
                    append return_include_dirs_list "$arg"
 | 
			
		||||
                fi
 | 
			
		||||
                path_order "$arg"
 | 
			
		||||
                case $? in
 | 
			
		||||
                    0) append return_spack_store_include_dirs_list "$arg" ;;
 | 
			
		||||
                    1) append return_include_dirs_list "$arg" ;;
 | 
			
		||||
                    2) append return_system_include_dirs_list "$arg" ;;
 | 
			
		||||
                esac
 | 
			
		||||
                ;;
 | 
			
		||||
            -L*)
 | 
			
		||||
                arg="${1#-L}"
 | 
			
		||||
                if [ -z "$arg" ]; then shift; arg="$1"; fi
 | 
			
		||||
                if system_dir "$arg"; then
 | 
			
		||||
                    append return_system_lib_dirs_list "$arg"
 | 
			
		||||
                else
 | 
			
		||||
                    append return_lib_dirs_list "$arg"
 | 
			
		||||
                fi
 | 
			
		||||
                path_order "$arg"
 | 
			
		||||
                case $? in
 | 
			
		||||
                    0) append return_spack_store_lib_dirs_list "$arg" ;;
 | 
			
		||||
                    1) append return_lib_dirs_list "$arg" ;;
 | 
			
		||||
                    2) append return_system_lib_dirs_list "$arg" ;;
 | 
			
		||||
                esac
 | 
			
		||||
                ;;
 | 
			
		||||
            -l*)
 | 
			
		||||
                # -loopopt=0 is generated erroneously in autoconf <= 2.69,
 | 
			
		||||
@@ -601,29 +614,32 @@ categorize_arguments() {
 | 
			
		||||
                    break
 | 
			
		||||
                elif [ "$xlinker_expect_rpath" = yes ]; then
 | 
			
		||||
                    # Register the path of -Xlinker -rpath <other args> -Xlinker <path>
 | 
			
		||||
                    if system_dir "$1"; then
 | 
			
		||||
                        append return_system_rpath_dirs_list "$1"
 | 
			
		||||
                    else
 | 
			
		||||
                        append return_rpath_dirs_list "$1"
 | 
			
		||||
                    fi
 | 
			
		||||
                    path_order "$1"
 | 
			
		||||
                    case $? in
 | 
			
		||||
                        0) append return_spack_store_rpath_dirs_list "$1" ;;
 | 
			
		||||
                        1) append return_rpath_dirs_list "$1" ;;
 | 
			
		||||
                        2) append return_system_rpath_dirs_list "$1" ;;
 | 
			
		||||
                    esac
 | 
			
		||||
                    xlinker_expect_rpath=no
 | 
			
		||||
                else
 | 
			
		||||
                    case "$1" in
 | 
			
		||||
                        -rpath=*)
 | 
			
		||||
                            arg="${1#-rpath=}"
 | 
			
		||||
                            if system_dir "$arg"; then
 | 
			
		||||
                                append return_system_rpath_dirs_list "$arg"
 | 
			
		||||
                            else
 | 
			
		||||
                                append return_rpath_dirs_list "$arg"
 | 
			
		||||
                            fi
 | 
			
		||||
                            path_order "$arg"
 | 
			
		||||
                            case $? in
 | 
			
		||||
                                0) append return_spack_store_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                                1) append return_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                                2) append return_system_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                            esac
 | 
			
		||||
                            ;;
 | 
			
		||||
                        --rpath=*)
 | 
			
		||||
                            arg="${1#--rpath=}"
 | 
			
		||||
                            if system_dir "$arg"; then
 | 
			
		||||
                                append return_system_rpath_dirs_list "$arg"
 | 
			
		||||
                            else
 | 
			
		||||
                                append return_rpath_dirs_list "$arg"
 | 
			
		||||
                            fi
 | 
			
		||||
                            path_order "$arg"
 | 
			
		||||
                            case $? in
 | 
			
		||||
                                0) append return_spack_store_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                                1) append return_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                                2) append return_system_rpath_dirs_list "$arg" ;;
 | 
			
		||||
                            esac
 | 
			
		||||
                            ;;
 | 
			
		||||
                        -rpath|--rpath)
 | 
			
		||||
                            xlinker_expect_rpath=yes
 | 
			
		||||
@@ -661,16 +677,25 @@ categorize_arguments() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
categorize_arguments "$@"
 | 
			
		||||
    include_dirs_list="$return_include_dirs_list"
 | 
			
		||||
    lib_dirs_list="$return_lib_dirs_list"
 | 
			
		||||
    rpath_dirs_list="$return_rpath_dirs_list"
 | 
			
		||||
    system_include_dirs_list="$return_system_include_dirs_list"
 | 
			
		||||
    system_lib_dirs_list="$return_system_lib_dirs_list"
 | 
			
		||||
    system_rpath_dirs_list="$return_system_rpath_dirs_list"
 | 
			
		||||
    isystem_was_used="$return_isystem_was_used"
 | 
			
		||||
    isystem_system_include_dirs_list="$return_isystem_system_include_dirs_list"
 | 
			
		||||
    isystem_include_dirs_list="$return_isystem_include_dirs_list"
 | 
			
		||||
    other_args_list="$return_other_args_list"
 | 
			
		||||
 | 
			
		||||
spack_store_include_dirs_list="$return_spack_store_include_dirs_list"
 | 
			
		||||
system_include_dirs_list="$return_system_include_dirs_list"
 | 
			
		||||
include_dirs_list="$return_include_dirs_list"
 | 
			
		||||
 | 
			
		||||
spack_store_lib_dirs_list="$return_spack_store_lib_dirs_list"
 | 
			
		||||
system_lib_dirs_list="$return_system_lib_dirs_list"
 | 
			
		||||
lib_dirs_list="$return_lib_dirs_list"
 | 
			
		||||
 | 
			
		||||
spack_store_rpath_dirs_list="$return_spack_store_rpath_dirs_list"
 | 
			
		||||
system_rpath_dirs_list="$return_system_rpath_dirs_list"
 | 
			
		||||
rpath_dirs_list="$return_rpath_dirs_list"
 | 
			
		||||
 | 
			
		||||
isystem_spack_store_include_dirs_list="$return_isystem_spack_store_include_dirs_list"
 | 
			
		||||
isystem_system_include_dirs_list="$return_isystem_system_include_dirs_list"
 | 
			
		||||
isystem_include_dirs_list="$return_isystem_include_dirs_list"
 | 
			
		||||
 | 
			
		||||
isystem_was_used="$return_isystem_was_used"
 | 
			
		||||
other_args_list="$return_other_args_list"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Add flags from Spack's cppflags, cflags, cxxflags, fcflags, fflags, and
 | 
			
		||||
@@ -738,16 +763,25 @@ esac
 | 
			
		||||
IFS="$lsep"
 | 
			
		||||
    categorize_arguments $spack_flags_list
 | 
			
		||||
unset IFS
 | 
			
		||||
        spack_flags_include_dirs_list="$return_include_dirs_list"
 | 
			
		||||
        spack_flags_lib_dirs_list="$return_lib_dirs_list"
 | 
			
		||||
        spack_flags_rpath_dirs_list="$return_rpath_dirs_list"
 | 
			
		||||
        spack_flags_system_include_dirs_list="$return_system_include_dirs_list"
 | 
			
		||||
        spack_flags_system_lib_dirs_list="$return_system_lib_dirs_list"
 | 
			
		||||
        spack_flags_system_rpath_dirs_list="$return_system_rpath_dirs_list"
 | 
			
		||||
        spack_flags_isystem_was_used="$return_isystem_was_used"
 | 
			
		||||
        spack_flags_isystem_system_include_dirs_list="$return_isystem_system_include_dirs_list"
 | 
			
		||||
        spack_flags_isystem_include_dirs_list="$return_isystem_include_dirs_list"
 | 
			
		||||
        spack_flags_other_args_list="$return_other_args_list"
 | 
			
		||||
 | 
			
		||||
spack_flags_isystem_spack_store_include_dirs_list="$return_isystem_spack_store_include_dirs_list"
 | 
			
		||||
spack_flags_isystem_system_include_dirs_list="$return_isystem_system_include_dirs_list"
 | 
			
		||||
spack_flags_isystem_include_dirs_list="$return_isystem_include_dirs_list"
 | 
			
		||||
 | 
			
		||||
spack_flags_spack_store_include_dirs_list="$return_spack_store_include_dirs_list"
 | 
			
		||||
spack_flags_system_include_dirs_list="$return_system_include_dirs_list"
 | 
			
		||||
spack_flags_include_dirs_list="$return_include_dirs_list"
 | 
			
		||||
 | 
			
		||||
spack_flags_spack_store_lib_dirs_list="$return_spack_store_lib_dirs_list"
 | 
			
		||||
spack_flags_system_lib_dirs_list="$return_system_lib_dirs_list"
 | 
			
		||||
spack_flags_lib_dirs_list="$return_lib_dirs_list"
 | 
			
		||||
 | 
			
		||||
spack_flags_spack_store_rpath_dirs_list="$return_spack_store_rpath_dirs_list"
 | 
			
		||||
spack_flags_system_rpath_dirs_list="$return_system_rpath_dirs_list"
 | 
			
		||||
spack_flags_rpath_dirs_list="$return_rpath_dirs_list"
 | 
			
		||||
 | 
			
		||||
spack_flags_isystem_was_used="$return_isystem_was_used"
 | 
			
		||||
spack_flags_other_args_list="$return_other_args_list"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# On macOS insert headerpad_max_install_names linker flag
 | 
			
		||||
@@ -767,11 +801,13 @@ if [ "$mode" = ccld ] || [ "$mode" = ld ]; then
 | 
			
		||||
        # Append RPATH directories. Note that in the case of the
 | 
			
		||||
        # top-level package these directories may not exist yet. For dependencies
 | 
			
		||||
        # it is assumed that paths have already been confirmed.
 | 
			
		||||
        extend spack_store_rpath_dirs_list SPACK_STORE_RPATH_DIRS
 | 
			
		||||
        extend rpath_dirs_list SPACK_RPATH_DIRS
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [ "$mode" = ccld ] || [ "$mode" = ld ]; then
 | 
			
		||||
    extend spack_store_lib_dirs_list SPACK_STORE_LINK_DIRS
 | 
			
		||||
    extend lib_dirs_list SPACK_LINK_DIRS
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
@@ -798,38 +834,50 @@ case "$mode" in
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
case "$mode" in
 | 
			
		||||
    cpp|cc|as|ccld)
 | 
			
		||||
        if [ "$spack_flags_isystem_was_used" = "true" ] || [ "$isystem_was_used" = "true" ]; then
 | 
			
		||||
            extend isystem_spack_store_include_dirs_list SPACK_STORE_INCLUDE_DIRS
 | 
			
		||||
            extend isystem_include_dirs_list SPACK_INCLUDE_DIRS
 | 
			
		||||
        else
 | 
			
		||||
            extend spack_store_include_dirs_list SPACK_STORE_INCLUDE_DIRS
 | 
			
		||||
            extend include_dirs_list SPACK_INCLUDE_DIRS
 | 
			
		||||
        fi
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Finally, reassemble the command line.
 | 
			
		||||
#
 | 
			
		||||
args_list="$flags_list"
 | 
			
		||||
 | 
			
		||||
# Insert include directories just prior to any system include directories
 | 
			
		||||
# Include search paths partitioned by (in store, non-sytem, system)
 | 
			
		||||
# NOTE: adding ${lsep} to the prefix here turns every added element into two
 | 
			
		||||
extend args_list spack_flags_include_dirs_list "-I"
 | 
			
		||||
extend args_list include_dirs_list "-I"
 | 
			
		||||
extend args_list spack_flags_spack_store_include_dirs_list -I
 | 
			
		||||
extend args_list spack_store_include_dirs_list -I
 | 
			
		||||
 | 
			
		||||
extend args_list spack_flags_include_dirs_list -I
 | 
			
		||||
extend args_list include_dirs_list -I
 | 
			
		||||
 | 
			
		||||
extend args_list spack_flags_isystem_spack_store_include_dirs_list "-isystem${lsep}"
 | 
			
		||||
extend args_list isystem_spack_store_include_dirs_list "-isystem${lsep}"
 | 
			
		||||
 | 
			
		||||
extend args_list spack_flags_isystem_include_dirs_list "-isystem${lsep}"
 | 
			
		||||
extend args_list isystem_include_dirs_list "-isystem${lsep}"
 | 
			
		||||
 | 
			
		||||
case "$mode" in
 | 
			
		||||
    cpp|cc|as|ccld)
 | 
			
		||||
        if [ "$spack_flags_isystem_was_used" = "true" ]; then
 | 
			
		||||
            extend args_list SPACK_INCLUDE_DIRS "-isystem${lsep}"
 | 
			
		||||
        elif [ "$isystem_was_used" = "true" ]; then
 | 
			
		||||
            extend args_list SPACK_INCLUDE_DIRS "-isystem${lsep}"
 | 
			
		||||
        else
 | 
			
		||||
            extend args_list SPACK_INCLUDE_DIRS "-I"
 | 
			
		||||
        fi
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
extend args_list spack_flags_system_include_dirs_list -I
 | 
			
		||||
extend args_list system_include_dirs_list -I
 | 
			
		||||
 | 
			
		||||
extend args_list spack_flags_isystem_system_include_dirs_list "-isystem${lsep}"
 | 
			
		||||
extend args_list isystem_system_include_dirs_list "-isystem${lsep}"
 | 
			
		||||
 | 
			
		||||
# Library search paths
 | 
			
		||||
# Library search paths partitioned by (in store, non-sytem, system)
 | 
			
		||||
extend args_list spack_flags_spack_store_lib_dirs_list "-L"
 | 
			
		||||
extend args_list spack_store_lib_dirs_list "-L"
 | 
			
		||||
 | 
			
		||||
extend args_list spack_flags_lib_dirs_list "-L"
 | 
			
		||||
extend args_list lib_dirs_list "-L"
 | 
			
		||||
 | 
			
		||||
extend args_list spack_flags_system_lib_dirs_list "-L"
 | 
			
		||||
extend args_list system_lib_dirs_list "-L"
 | 
			
		||||
 | 
			
		||||
@@ -839,8 +887,12 @@ case "$mode" in
 | 
			
		||||
        if [ -n "$dtags_to_add" ] ; then
 | 
			
		||||
            append args_list "$linker_arg$dtags_to_add"
 | 
			
		||||
        fi
 | 
			
		||||
        extend args_list spack_flags_spack_store_rpath_dirs_list "$rpath"
 | 
			
		||||
        extend args_list spack_store_rpath_dirs_list "$rpath"
 | 
			
		||||
 | 
			
		||||
        extend args_list spack_flags_rpath_dirs_list "$rpath"
 | 
			
		||||
        extend args_list rpath_dirs_list "$rpath"
 | 
			
		||||
 | 
			
		||||
        extend args_list spack_flags_system_rpath_dirs_list "$rpath"
 | 
			
		||||
        extend args_list system_rpath_dirs_list "$rpath"
 | 
			
		||||
        ;;
 | 
			
		||||
@@ -848,8 +900,12 @@ case "$mode" in
 | 
			
		||||
        if [ -n "$dtags_to_add" ] ; then
 | 
			
		||||
            append args_list "$dtags_to_add"
 | 
			
		||||
        fi
 | 
			
		||||
        extend args_list spack_flags_spack_store_rpath_dirs_list "-rpath${lsep}"
 | 
			
		||||
        extend args_list spack_store_rpath_dirs_list "-rpath${lsep}"
 | 
			
		||||
 | 
			
		||||
        extend args_list spack_flags_rpath_dirs_list "-rpath${lsep}"
 | 
			
		||||
        extend args_list rpath_dirs_list "-rpath${lsep}"
 | 
			
		||||
 | 
			
		||||
        extend args_list spack_flags_system_rpath_dirs_list "-rpath${lsep}"
 | 
			
		||||
        extend args_list system_rpath_dirs_list "-rpath${lsep}"
 | 
			
		||||
        ;;
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,7 @@
 | 
			
		||||
import spack.repo
 | 
			
		||||
import spack.schema.environment
 | 
			
		||||
import spack.spec
 | 
			
		||||
import spack.stage
 | 
			
		||||
import spack.store
 | 
			
		||||
import spack.subprocess_context
 | 
			
		||||
import spack.user_environment
 | 
			
		||||
@@ -80,7 +81,7 @@
 | 
			
		||||
from spack.installer import InstallError
 | 
			
		||||
from spack.util.cpus import determine_number_of_jobs
 | 
			
		||||
from spack.util.environment import (
 | 
			
		||||
    SYSTEM_DIRS,
 | 
			
		||||
    SYSTEM_DIR_CASE_ENTRY,
 | 
			
		||||
    EnvironmentModifications,
 | 
			
		||||
    env_flag,
 | 
			
		||||
    filter_system_paths,
 | 
			
		||||
@@ -103,9 +104,13 @@
 | 
			
		||||
# Spack's compiler wrappers.
 | 
			
		||||
#
 | 
			
		||||
SPACK_ENV_PATH = "SPACK_ENV_PATH"
 | 
			
		||||
SPACK_MANAGED_DIRS = "SPACK_MANAGED_DIRS"
 | 
			
		||||
SPACK_INCLUDE_DIRS = "SPACK_INCLUDE_DIRS"
 | 
			
		||||
SPACK_LINK_DIRS = "SPACK_LINK_DIRS"
 | 
			
		||||
SPACK_RPATH_DIRS = "SPACK_RPATH_DIRS"
 | 
			
		||||
SPACK_STORE_INCLUDE_DIRS = "SPACK_STORE_INCLUDE_DIRS"
 | 
			
		||||
SPACK_STORE_LINK_DIRS = "SPACK_STORE_LINK_DIRS"
 | 
			
		||||
SPACK_STORE_RPATH_DIRS = "SPACK_STORE_RPATH_DIRS"
 | 
			
		||||
SPACK_RPATH_DEPS = "SPACK_RPATH_DEPS"
 | 
			
		||||
SPACK_LINK_DEPS = "SPACK_LINK_DEPS"
 | 
			
		||||
SPACK_PREFIX = "SPACK_PREFIX"
 | 
			
		||||
@@ -418,7 +423,7 @@ def set_compiler_environment_variables(pkg, env):
 | 
			
		||||
 | 
			
		||||
    env.set("SPACK_COMPILER_SPEC", str(spec.compiler))
 | 
			
		||||
 | 
			
		||||
    env.set("SPACK_SYSTEM_DIRS", ":".join(SYSTEM_DIRS))
 | 
			
		||||
    env.set("SPACK_SYSTEM_DIRS", SYSTEM_DIR_CASE_ENTRY)
 | 
			
		||||
 | 
			
		||||
    compiler.setup_custom_environment(pkg, env)
 | 
			
		||||
 | 
			
		||||
@@ -546,9 +551,23 @@ def update_compiler_args_for_dep(dep):
 | 
			
		||||
    include_dirs = list(dedupe(filter_system_paths(include_dirs)))
 | 
			
		||||
    rpath_dirs = list(dedupe(filter_system_paths(rpath_dirs)))
 | 
			
		||||
 | 
			
		||||
    env.set(SPACK_LINK_DIRS, ":".join(link_dirs))
 | 
			
		||||
    env.set(SPACK_INCLUDE_DIRS, ":".join(include_dirs))
 | 
			
		||||
    env.set(SPACK_RPATH_DIRS, ":".join(rpath_dirs))
 | 
			
		||||
    spack_managed_dirs: List[str] = [
 | 
			
		||||
        spack.stage.get_stage_root(),
 | 
			
		||||
        spack.store.STORE.db.root,
 | 
			
		||||
        *(db.root for db in spack.store.STORE.db.upstream_dbs),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    env.set(SPACK_MANAGED_DIRS, "|".join(f'"{p}/"*' for p in spack_managed_dirs))
 | 
			
		||||
    is_spack_managed = lambda p: any(p.startswith(store) for store in spack_managed_dirs)
 | 
			
		||||
    link_dirs_spack, link_dirs_system = stable_partition(link_dirs, is_spack_managed)
 | 
			
		||||
    include_dirs_spack, include_dirs_system = stable_partition(include_dirs, is_spack_managed)
 | 
			
		||||
    rpath_dirs_spack, rpath_dirs_system = stable_partition(rpath_dirs, is_spack_managed)
 | 
			
		||||
    env.set(SPACK_LINK_DIRS, ":".join(link_dirs_system))
 | 
			
		||||
    env.set(SPACK_INCLUDE_DIRS, ":".join(include_dirs_system))
 | 
			
		||||
    env.set(SPACK_RPATH_DIRS, ":".join(rpath_dirs_system))
 | 
			
		||||
    env.set(SPACK_STORE_LINK_DIRS, ":".join(link_dirs_spack))
 | 
			
		||||
    env.set(SPACK_STORE_INCLUDE_DIRS, ":".join(include_dirs_spack))
 | 
			
		||||
    env.set(SPACK_STORE_RPATH_DIRS, ":".join(rpath_dirs_spack))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def set_package_py_globals(pkg, context: Context = Context.BUILD):
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,8 @@ def build_environment(working_env):
 | 
			
		||||
    os.environ["SPACK_LINKER_ARG"] = "-Wl,"
 | 
			
		||||
    os.environ["SPACK_DTAGS_TO_ADD"] = "--disable-new-dtags"
 | 
			
		||||
    os.environ["SPACK_DTAGS_TO_STRIP"] = "--enable-new-dtags"
 | 
			
		||||
    os.environ["SPACK_SYSTEM_DIRS"] = "/usr/include /usr/lib"
 | 
			
		||||
    os.environ["SPACK_SYSTEM_DIRS"] = "/usr/include|/usr/lib"
 | 
			
		||||
    os.environ["SPACK_MANAGED_DIRS"] = f"{prefix}/opt/spack"
 | 
			
		||||
    os.environ["SPACK_TARGET_ARGS"] = ""
 | 
			
		||||
 | 
			
		||||
    if "SPACK_DEPENDENCIES" in os.environ:
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
import spack.config
 | 
			
		||||
import spack.spec
 | 
			
		||||
from spack.paths import build_env_path
 | 
			
		||||
from spack.util.environment import SYSTEM_DIRS, set_env
 | 
			
		||||
from spack.util.environment import SYSTEM_DIR_CASE_ENTRY, set_env
 | 
			
		||||
from spack.util.executable import Executable, ProcessError
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
@@ -159,7 +159,8 @@ def wrapper_environment(working_env):
 | 
			
		||||
        SPACK_DEBUG_LOG_ID="foo-hashabc",
 | 
			
		||||
        SPACK_COMPILER_SPEC="gcc@4.4.7",
 | 
			
		||||
        SPACK_SHORT_SPEC="foo@1.2 arch=linux-rhel6-x86_64 /hashabc",
 | 
			
		||||
        SPACK_SYSTEM_DIRS=":".join(SYSTEM_DIRS),
 | 
			
		||||
        SPACK_SYSTEM_DIRS=SYSTEM_DIR_CASE_ENTRY,
 | 
			
		||||
        SPACK_MANAGED_DIRS="/path/to/spack-1/opt/spack/*|/path/to/spack-2/opt/spack/*",
 | 
			
		||||
        SPACK_CC_RPATH_ARG="-Wl,-rpath,",
 | 
			
		||||
        SPACK_CXX_RPATH_ARG="-Wl,-rpath,",
 | 
			
		||||
        SPACK_F77_RPATH_ARG="-Wl,-rpath,",
 | 
			
		||||
@@ -907,3 +908,108 @@ def test_linker_strips_loopopt(wrapper_environment, wrapper_flags):
 | 
			
		||||
        result = cc(*(test_args + ["-loopopt=0", "-c", "x.c"]), output=str)
 | 
			
		||||
        result = result.strip().split("\n")
 | 
			
		||||
        assert "-loopopt=0" in result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_spack_managed_dirs_are_prioritized(wrapper_environment):
 | 
			
		||||
    # We have two different stores with 5 packages divided over them
 | 
			
		||||
    pkg1 = "/path/to/spack-1/opt/spack/linux-ubuntu22.04-zen2/gcc-13.2.0/pkg-1.0-abcdef"
 | 
			
		||||
    pkg2 = "/path/to/spack-1/opt/spack/linux-ubuntu22.04-zen2/gcc-13.2.0/pkg-2.0-abcdef"
 | 
			
		||||
    pkg3 = "/path/to/spack-2/opt/spack/linux-ubuntu22.04-zen2/gcc-13.2.0/pkg-3.0-abcdef"
 | 
			
		||||
    pkg4 = "/path/to/spack-2/opt/spack/linux-ubuntu22.04-zen2/gcc-13.2.0/pkg-4.0-abcdef"
 | 
			
		||||
    pkg5 = "/path/to/spack-2/opt/spack/linux-ubuntu22.04-zen2/gcc-13.2.0/pkg-5.0-abcdef"
 | 
			
		||||
 | 
			
		||||
    variables = {
 | 
			
		||||
        # cppflags, ldflags from the command line, config or package.py take highest priority
 | 
			
		||||
        "SPACK_CPPFLAGS": f"-I/usr/local/include -I/external-1/include -I{pkg1}/include",
 | 
			
		||||
        "SPACK_LDFLAGS": f"-L/usr/local/lib -L/external-1/lib -L{pkg1}/lib "
 | 
			
		||||
        f"-Wl,-rpath,/usr/local/lib -Wl,-rpath,/external-1/lib -Wl,-rpath,{pkg1}/lib",
 | 
			
		||||
        # automatic -L, -Wl,-rpath, -I flags from dependencies -- on the spack side they are
 | 
			
		||||
        # already partitioned into "spack owned prefixes" and "non-spack owned prefixes"
 | 
			
		||||
        "SPACK_STORE_LINK_DIRS": f"{pkg4}/lib:{pkg5}/lib",
 | 
			
		||||
        "SPACK_STORE_RPATH_DIRS": f"{pkg4}/lib:{pkg5}/lib",
 | 
			
		||||
        "SPACK_STORE_INCLUDE_DIRS": f"{pkg4}/include:{pkg5}/include",
 | 
			
		||||
        "SPACK_LINK_DIRS": "/external-3/lib:/external-4/lib",
 | 
			
		||||
        "SPACK_RPATH_DIRS": "/external-3/lib:/external-4/lib",
 | 
			
		||||
        "SPACK_INCLUDE_DIRS": "/external-3/include:/external-4/include",
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    with set_env(SPACK_TEST_COMMAND="dump-args", **variables):
 | 
			
		||||
        effective_call = (
 | 
			
		||||
            cc(
 | 
			
		||||
                # system paths
 | 
			
		||||
                "-I/usr/include",
 | 
			
		||||
                "-L/usr/lib",
 | 
			
		||||
                "-Wl,-rpath,/usr/lib",
 | 
			
		||||
                # some other externals
 | 
			
		||||
                "-I/external-2/include",
 | 
			
		||||
                "-L/external-2/lib",
 | 
			
		||||
                "-Wl,-rpath,/external-2/lib",
 | 
			
		||||
                # relative paths are considered "spack managed" since they are in the stage dir
 | 
			
		||||
                "-I..",
 | 
			
		||||
                "-L..",
 | 
			
		||||
                "-Wl,-rpath,..",  # pathological but simpler for the test.
 | 
			
		||||
                # spack store paths
 | 
			
		||||
                f"-I{pkg2}/include",
 | 
			
		||||
                f"-I{pkg3}/include",
 | 
			
		||||
                f"-L{pkg2}/lib",
 | 
			
		||||
                f"-L{pkg3}/lib",
 | 
			
		||||
                f"-Wl,-rpath,{pkg2}/lib",
 | 
			
		||||
                f"-Wl,-rpath,{pkg3}/lib",
 | 
			
		||||
                "hello.c",
 | 
			
		||||
                "-o",
 | 
			
		||||
                "hello",
 | 
			
		||||
                output=str,
 | 
			
		||||
            )
 | 
			
		||||
            .strip()
 | 
			
		||||
            .split("\n")
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    dash_I = [flag[2:] for flag in effective_call if flag.startswith("-I")]
 | 
			
		||||
    dash_L = [flag[2:] for flag in effective_call if flag.startswith("-L")]
 | 
			
		||||
    dash_Wl_rpath = [flag[11:] for flag in effective_call if flag.startswith("-Wl,-rpath")]
 | 
			
		||||
 | 
			
		||||
    assert dash_I == [
 | 
			
		||||
        # spack owned dirs from SPACK_*FLAGS
 | 
			
		||||
        f"{pkg1}/include",
 | 
			
		||||
        # spack owned dirs from command line & automatic flags for deps (in that order)]
 | 
			
		||||
        "..",
 | 
			
		||||
        f"{pkg2}/include",  # from command line
 | 
			
		||||
        f"{pkg3}/include",  # from command line
 | 
			
		||||
        f"{pkg4}/include",  # from SPACK_STORE_INCLUDE_DIRS
 | 
			
		||||
        f"{pkg5}/include",  # from SPACK_STORE_INCLUDE_DIRS
 | 
			
		||||
        # non-system dirs from SPACK_*FLAGS
 | 
			
		||||
        "/external-1/include",
 | 
			
		||||
        # non-system dirs from command line & automatic flags for deps (in that order)
 | 
			
		||||
        "/external-2/include",  # from command line
 | 
			
		||||
        "/external-3/include",  # from SPACK_INCLUDE_DIRS
 | 
			
		||||
        "/external-4/include",  # from SPACK_INCLUDE_DIRS
 | 
			
		||||
        # system dirs from SPACK_*FLAGS
 | 
			
		||||
        "/usr/local/include",
 | 
			
		||||
        # system dirs from command line
 | 
			
		||||
        "/usr/include",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    assert (
 | 
			
		||||
        dash_L
 | 
			
		||||
        == dash_Wl_rpath
 | 
			
		||||
        == [
 | 
			
		||||
            # spack owned dirs from SPACK_*FLAGS
 | 
			
		||||
            f"{pkg1}/lib",
 | 
			
		||||
            # spack owned dirs from command line & automatic flags for deps (in that order)
 | 
			
		||||
            "..",
 | 
			
		||||
            f"{pkg2}/lib",  # from command line
 | 
			
		||||
            f"{pkg3}/lib",  # from command line
 | 
			
		||||
            f"{pkg4}/lib",  # from SPACK_STORE_LINK_DIRS
 | 
			
		||||
            f"{pkg5}/lib",  # from SPACK_STORE_LINK_DIRS
 | 
			
		||||
            # non-system dirs from SPACK_*FLAGS
 | 
			
		||||
            "/external-1/lib",
 | 
			
		||||
            # non-system dirs from command line & automatic flags for deps (in that order)
 | 
			
		||||
            "/external-2/lib",  # from command line
 | 
			
		||||
            "/external-3/lib",  # from SPACK_LINK_DIRS
 | 
			
		||||
            "/external-4/lib",  # from SPACK_LINK_DIRS
 | 
			
		||||
            # system dirs from SPACK_*FLAGS
 | 
			
		||||
            "/usr/local/lib",
 | 
			
		||||
            # system dirs from command line
 | 
			
		||||
            "/usr/lib",
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@
 | 
			
		||||
 | 
			
		||||
SYSTEM_DIRS = [os.path.join(p, s) for s in SUFFIXES for p in SYSTEM_PATHS] + SYSTEM_PATHS
 | 
			
		||||
 | 
			
		||||
#: used in the compiler wrapper's `/usr/lib|/usr/lib64|...)` case entry
 | 
			
		||||
SYSTEM_DIR_CASE_ENTRY = "|".join(sorted(f'"{d}{suff}"' for d in SYSTEM_DIRS for suff in ("", "/")))
 | 
			
		||||
 | 
			
		||||
_SHELL_SET_STRINGS = {
 | 
			
		||||
    "sh": "export {0}={1};\n",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user