Turn the compiler wrapper into a package
Remove the compiler wrappers from core Spack, and move the relevant code into the "compiler-wrapper" package.
This commit is contained in:
1
lib/spack/env/aocc/clang
vendored
1
lib/spack/env/aocc/clang
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/aocc/clang++
vendored
1
lib/spack/env/aocc/clang++
vendored
@@ -1 +0,0 @@
|
||||
../cpp
|
1
lib/spack/env/aocc/flang
vendored
1
lib/spack/env/aocc/flang
vendored
@@ -1 +0,0 @@
|
||||
../fc
|
1
lib/spack/env/arm/armclang
vendored
1
lib/spack/env/arm/armclang
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/arm/armclang++
vendored
1
lib/spack/env/arm/armclang++
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/arm/armflang
vendored
1
lib/spack/env/arm/armflang
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/c++
vendored
1
lib/spack/env/c++
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/c89
vendored
1
lib/spack/env/c89
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/c99
vendored
1
lib/spack/env/c99
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/case-insensitive/CC
vendored
1
lib/spack/env/case-insensitive/CC
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
963
lib/spack/env/cc
vendored
963
lib/spack/env/cc
vendored
@@ -1,963 +0,0 @@
|
||||
#!/bin/sh -f
|
||||
# shellcheck disable=SC2034 # evals in this script fool shellcheck
|
||||
#
|
||||
# Copyright Spack Project Developers. See COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
#
|
||||
# Spack compiler wrapper script.
|
||||
#
|
||||
# Compiler commands go through this compiler wrapper in Spack builds.
|
||||
# The compiler wrapper is a thin layer around the standard compilers.
|
||||
# It enables several key pieces of functionality:
|
||||
#
|
||||
# 1. It allows Spack to swap compilers into and out of builds easily.
|
||||
# 2. It adds several options to the compile line so that spack
|
||||
# packages can find their dependencies at build time and run time:
|
||||
# -I and/or -isystem arguments for dependency /include directories.
|
||||
# -L arguments for dependency /lib directories.
|
||||
# -Wl,-rpath arguments for dependency /lib directories.
|
||||
#
|
||||
|
||||
# Reset IFS to the default: whitespace-separated lists. When we use
|
||||
# other separators, we set and reset it.
|
||||
unset IFS
|
||||
|
||||
# Separator for lists whose names end with `_list`.
|
||||
# We pick the alarm bell character, which is highly unlikely to
|
||||
# conflict with anything. This is a literal bell character (which
|
||||
# we have to use since POSIX sh does not convert escape sequences
|
||||
# like '\a' outside of the format argument of `printf`).
|
||||
# NOTE: Depending on your editor this may look empty, but it is not.
|
||||
readonly lsep=''
|
||||
|
||||
# This is an array of environment variables that need to be set before
|
||||
# the script runs. They are set by routines in spack.build_environment
|
||||
# as part of the package installation process.
|
||||
readonly params="\
|
||||
SPACK_ENV_PATH
|
||||
SPACK_DEBUG_LOG_DIR
|
||||
SPACK_DEBUG_LOG_ID
|
||||
SPACK_LINKER_ARG
|
||||
SPACK_SHORT_SPEC
|
||||
SPACK_SYSTEM_DIRS
|
||||
SPACK_MANAGED_DIRS"
|
||||
|
||||
# Optional parameters that aren't required to be set
|
||||
|
||||
# Boolean (true/false/custom) if we want to add debug flags
|
||||
# SPACK_ADD_DEBUG_FLAGS
|
||||
|
||||
# If a custom flag is requested, it will be defined
|
||||
# SPACK_DEBUG_FLAGS
|
||||
|
||||
# The compiler input variables are checked for sanity later:
|
||||
# SPACK_CC, SPACK_CXX, SPACK_F77, SPACK_FC
|
||||
# The default compiler flags are passed from these variables:
|
||||
# SPACK_CFLAGS, SPACK_CXXFLAGS, SPACK_FFLAGS,
|
||||
# SPACK_LDFLAGS, SPACK_LDLIBS
|
||||
# Debug env var is optional; set to "TRUE" for debug logging:
|
||||
# SPACK_DEBUG
|
||||
# Test command is used to unit test the compiler script.
|
||||
# SPACK_TEST_COMMAND
|
||||
|
||||
# die MESSAGE
|
||||
# Print a message and exit with error code 1.
|
||||
die() {
|
||||
echo "[spack cc] ERROR: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# empty VARNAME
|
||||
# Return whether the variable VARNAME is unset or set to the empty string.
|
||||
empty() {
|
||||
eval "test -z \"\${$1}\""
|
||||
}
|
||||
|
||||
# setsep LISTNAME
|
||||
# Set the global variable 'sep' to the separator for a list with name LISTNAME.
|
||||
# There are three types of lists:
|
||||
# 1. regular lists end with _list and are separated by $lsep
|
||||
# 2. directory lists end with _dirs/_DIRS/PATH(S) and are separated by ':'
|
||||
# 3. any other list is assumed to be separated by spaces: " "
|
||||
setsep() {
|
||||
case "$1" in
|
||||
*_dirs|*_DIRS|*PATH|*PATHS)
|
||||
sep=':'
|
||||
;;
|
||||
*_list)
|
||||
sep="$lsep"
|
||||
;;
|
||||
*)
|
||||
sep=" "
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# prepend LISTNAME ELEMENT
|
||||
#
|
||||
# Prepend ELEMENT to the list stored in the variable LISTNAME.
|
||||
# Handles empty lists and single-element lists.
|
||||
prepend() {
|
||||
varname="$1"
|
||||
elt="$2"
|
||||
|
||||
if empty "$varname"; then
|
||||
eval "$varname=\"\${elt}\""
|
||||
else
|
||||
# Get the appropriate separator for the list we're appending to.
|
||||
setsep "$varname"
|
||||
eval "$varname=\"\${elt}${sep}\${$varname}\""
|
||||
fi
|
||||
}
|
||||
|
||||
# append LISTNAME ELEMENT [SEP]
|
||||
#
|
||||
# Append ELEMENT to the list stored in the variable LISTNAME,
|
||||
# assuming the list is separated by SEP.
|
||||
# Handles empty lists and single-element lists.
|
||||
append() {
|
||||
varname="$1"
|
||||
elt="$2"
|
||||
|
||||
if empty "$varname"; then
|
||||
eval "$varname=\"\${elt}\""
|
||||
else
|
||||
# Get the appropriate separator for the list we're appending to.
|
||||
setsep "$varname"
|
||||
eval "$varname=\"\${$varname}${sep}\${elt}\""
|
||||
fi
|
||||
}
|
||||
|
||||
# extend LISTNAME1 LISTNAME2 [PREFIX]
|
||||
#
|
||||
# Append the elements stored in the variable LISTNAME2
|
||||
# to the list stored in LISTNAME1.
|
||||
# If PREFIX is provided, prepend it to each element.
|
||||
extend() {
|
||||
# Figure out the appropriate IFS for the list we're reading.
|
||||
setsep "$2"
|
||||
if [ "$sep" != " " ]; then
|
||||
IFS="$sep"
|
||||
fi
|
||||
eval "for elt in \${$2}; do append $1 \"$3\${elt}\"; done"
|
||||
unset IFS
|
||||
}
|
||||
|
||||
# preextend LISTNAME1 LISTNAME2 [PREFIX]
|
||||
#
|
||||
# Prepend the elements stored in the list at LISTNAME2
|
||||
# to the list at LISTNAME1, preserving order.
|
||||
# If PREFIX is provided, prepend it to each element.
|
||||
preextend() {
|
||||
# Figure out the appropriate IFS for the list we're reading.
|
||||
setsep "$2"
|
||||
if [ "$sep" != " " ]; then
|
||||
IFS="$sep"
|
||||
fi
|
||||
|
||||
# first, reverse the list to prepend
|
||||
_reversed_list=""
|
||||
eval "for elt in \${$2}; do prepend _reversed_list \"$3\${elt}\"; done"
|
||||
|
||||
# prepend reversed list to preextend in order
|
||||
IFS="${lsep}"
|
||||
for elt in $_reversed_list; do prepend "$1" "$3${elt}"; done
|
||||
unset IFS
|
||||
}
|
||||
|
||||
execute() {
|
||||
# dump the full command if the caller supplies SPACK_TEST_COMMAND=dump-args
|
||||
if [ -n "${SPACK_TEST_COMMAND=}" ]; then
|
||||
case "$SPACK_TEST_COMMAND" in
|
||||
dump-args)
|
||||
IFS="$lsep"
|
||||
for arg in $full_command_list; do
|
||||
echo "$arg"
|
||||
done
|
||||
unset IFS
|
||||
exit
|
||||
;;
|
||||
dump-env-*)
|
||||
var=${SPACK_TEST_COMMAND#dump-env-}
|
||||
eval "printf '%s\n' \"\$0: \$var: \$$var\""
|
||||
;;
|
||||
*)
|
||||
die "Unknown test command: '$SPACK_TEST_COMMAND'"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#
|
||||
# Write the input and output commands to debug logs if it's asked for.
|
||||
#
|
||||
if [ "$SPACK_DEBUG" = TRUE ]; then
|
||||
input_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_DEBUG_LOG_ID.in.log"
|
||||
output_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_DEBUG_LOG_ID.out.log"
|
||||
echo "[$mode] $command $input_command" >> "$input_log"
|
||||
IFS="$lsep"
|
||||
echo "[$mode] "$full_command_list >> "$output_log"
|
||||
unset IFS
|
||||
fi
|
||||
|
||||
# Execute the full command, preserving spaces with IFS set
|
||||
# to the alarm bell separator.
|
||||
IFS="$lsep"; exec $full_command_list
|
||||
exit
|
||||
}
|
||||
|
||||
# Fail with a clear message if the input contains any bell characters.
|
||||
if eval "[ \"\${*#*${lsep}}\" != \"\$*\" ]"; then
|
||||
die "Compiler command line contains our separator ('${lsep}'). Cannot parse."
|
||||
fi
|
||||
|
||||
# ensure required variables are set
|
||||
for param in $params; do
|
||||
if eval "test -z \"\${${param}:-}\""; then
|
||||
die "Spack compiler must be run from Spack! Input '$param' is missing."
|
||||
fi
|
||||
done
|
||||
|
||||
# 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
|
||||
}
|
||||
"
|
||||
|
||||
# path_list functions. Path_lists have 3 parts: spack_store_<list>, <list> and system_<list>,
|
||||
# which are used to prioritize paths when assembling the final command line.
|
||||
|
||||
# init_path_lists LISTNAME
|
||||
# Set <LISTNAME>, spack_store_<LISTNAME>, and system_<LISTNAME> to "".
|
||||
init_path_lists() {
|
||||
eval "spack_store_$1=\"\""
|
||||
eval "$1=\"\""
|
||||
eval "system_$1=\"\""
|
||||
}
|
||||
|
||||
# assign_path_lists LISTNAME1 LISTNAME2
|
||||
# Copy contents of LISTNAME2 into LISTNAME1, for each path_list prefix.
|
||||
assign_path_lists() {
|
||||
eval "spack_store_$1=\"\${spack_store_$2}\""
|
||||
eval "$1=\"\${$2}\""
|
||||
eval "system_$1=\"\${system_$2}\""
|
||||
}
|
||||
|
||||
# append_path_lists LISTNAME ELT
|
||||
# Append the provided ELT to the appropriate list, based on the result of path_order().
|
||||
append_path_lists() {
|
||||
path_order "$2"
|
||||
case $? in
|
||||
0) eval "append spack_store_$1 \"\$2\"" ;;
|
||||
1) eval "append $1 \"\$2\"" ;;
|
||||
2) eval "append system_$1 \"\$2\"" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check if optional parameters are defined
|
||||
# If we aren't asking for debug flags, don't add them
|
||||
if [ -z "${SPACK_ADD_DEBUG_FLAGS:-}" ]; then
|
||||
SPACK_ADD_DEBUG_FLAGS="false"
|
||||
fi
|
||||
|
||||
# SPACK_ADD_DEBUG_FLAGS must be true/false/custom
|
||||
is_valid="false"
|
||||
for param in "true" "false" "custom"; do
|
||||
if [ "$param" = "$SPACK_ADD_DEBUG_FLAGS" ]; then
|
||||
is_valid="true"
|
||||
fi
|
||||
done
|
||||
|
||||
# Exit with error if we are given an incorrect value
|
||||
if [ "$is_valid" = "false" ]; then
|
||||
die "SPACK_ADD_DEBUG_FLAGS, if defined, must be one of 'true', 'false', or 'custom'."
|
||||
fi
|
||||
|
||||
# Figure out the type of compiler, the language, and the mode so that
|
||||
# the compiler script knows what to do.
|
||||
#
|
||||
# Possible languages are C, C++, Fortran 77, and Fortran 90.
|
||||
# 'command' is set based on the input command to $SPACK_[CC|CXX|F77|F90]
|
||||
#
|
||||
# 'mode' is set to one of:
|
||||
# vcheck version check
|
||||
# cpp preprocess
|
||||
# cc compile
|
||||
# as assemble
|
||||
# ld link
|
||||
# ccld compile & link
|
||||
|
||||
# Note. SPACK_ALWAYS_XFLAGS are applied for all compiler invocations,
|
||||
# including version checks (SPACK_XFLAGS variants are not applied
|
||||
# for version checks).
|
||||
command="${0##*/}"
|
||||
comp="CC"
|
||||
vcheck_flags=""
|
||||
case "$command" in
|
||||
cpp)
|
||||
mode=cpp
|
||||
debug_flags="-g"
|
||||
vcheck_flags="${SPACK_ALWAYS_CPPFLAGS}"
|
||||
;;
|
||||
cc|c89|c99|gcc|clang|armclang|icc|icx|pgcc|nvc|xlc|xlc_r|fcc|amdclang|cl.exe|craycc)
|
||||
command="$SPACK_CC"
|
||||
language="C"
|
||||
comp="CC"
|
||||
lang_flags=C
|
||||
debug_flags="-g"
|
||||
vcheck_flags="${SPACK_ALWAYS_CFLAGS}"
|
||||
;;
|
||||
c++|CC|g++|clang++|armclang++|icpc|icpx|pgc++|nvc++|xlc++|xlc++_r|FCC|amdclang++|crayCC)
|
||||
command="$SPACK_CXX"
|
||||
language="C++"
|
||||
comp="CXX"
|
||||
lang_flags=CXX
|
||||
debug_flags="-g"
|
||||
vcheck_flags="${SPACK_ALWAYS_CXXFLAGS}"
|
||||
;;
|
||||
ftn|f90|fc|f95|gfortran|flang|armflang|ifort|ifx|pgfortran|nvfortran|xlf90|xlf90_r|nagfor|frt|amdflang|crayftn)
|
||||
command="$SPACK_FC"
|
||||
language="Fortran 90"
|
||||
comp="FC"
|
||||
lang_flags=F
|
||||
debug_flags="-g"
|
||||
vcheck_flags="${SPACK_ALWAYS_FFLAGS}"
|
||||
;;
|
||||
f77|xlf|xlf_r|pgf77)
|
||||
command="$SPACK_F77"
|
||||
language="Fortran 77"
|
||||
comp="F77"
|
||||
lang_flags=F
|
||||
debug_flags="-g"
|
||||
vcheck_flags="${SPACK_ALWAYS_FFLAGS}"
|
||||
;;
|
||||
ld|ld.gold|ld.lld)
|
||||
mode=ld
|
||||
if [ -z "$SPACK_CC_RPATH_ARG" ]; then
|
||||
comp="CXX"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
die "Unknown compiler: $command"
|
||||
;;
|
||||
esac
|
||||
|
||||
# If any of the arguments below are present, then the mode is vcheck.
|
||||
# In vcheck mode, nothing is added in terms of extra search paths or
|
||||
# libraries.
|
||||
if [ -z "$mode" ] || [ "$mode" = ld ]; then
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
-v|-V|--version|-dumpversion)
|
||||
mode=vcheck
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# Finish setting up the mode.
|
||||
if [ -z "$mode" ]; then
|
||||
mode=ccld
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = "-E" ]; then
|
||||
mode=cpp
|
||||
break
|
||||
elif [ "$arg" = "-S" ]; then
|
||||
mode=as
|
||||
break
|
||||
elif [ "$arg" = "-c" ]; then
|
||||
mode=cc
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# This is needed to ensure we set RPATH instead of RUNPATH
|
||||
# (or the opposite, depending on the configuration in config.yaml)
|
||||
#
|
||||
# Documentation on this mechanism is lacking at best. A few sources
|
||||
# of information are (note that some of them take explicitly the
|
||||
# opposite stance that Spack does):
|
||||
#
|
||||
# http://blog.qt.io/blog/2011/10/28/rpath-and-runpath/
|
||||
# https://wiki.debian.org/RpathIssue
|
||||
#
|
||||
# The only discussion I could find on enabling new dynamic tags by
|
||||
# default on ld is the following:
|
||||
#
|
||||
# https://sourceware.org/ml/binutils/2013-01/msg00307.html
|
||||
#
|
||||
dtags_to_add="${SPACK_DTAGS_TO_ADD}"
|
||||
dtags_to_strip="${SPACK_DTAGS_TO_STRIP}"
|
||||
linker_arg="${SPACK_LINKER_ARG}"
|
||||
|
||||
# Set up rpath variable according to language.
|
||||
rpath="ERROR: RPATH ARG WAS NOT SET, MAYBE THE PACKAGE DOES NOT DEPEND ON ${comp}?"
|
||||
eval "rpath=\${SPACK_${comp}_RPATH_ARG:?${rpath}}"
|
||||
|
||||
# Dump the mode and exit if the command is dump-mode.
|
||||
if [ "$SPACK_TEST_COMMAND" = "dump-mode" ]; then
|
||||
echo "$mode"
|
||||
exit
|
||||
fi
|
||||
|
||||
#
|
||||
# Filter '.' and Spack environment directories out of PATH so that
|
||||
# this script doesn't just call itself
|
||||
#
|
||||
new_dirs=""
|
||||
IFS=':'
|
||||
for dir in $PATH; do
|
||||
addpath=true
|
||||
for spack_env_dir in $SPACK_ENV_PATH; do
|
||||
case "${dir%%/}" in
|
||||
"$spack_env_dir"|'.'|'')
|
||||
addpath=false
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ $addpath = true ]; then
|
||||
append new_dirs "$dir"
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
export PATH="$new_dirs"
|
||||
|
||||
if [ "$mode" = vcheck ]; then
|
||||
full_command_list="$command"
|
||||
args="$@"
|
||||
extend full_command_list vcheck_flags
|
||||
extend full_command_list args
|
||||
execute
|
||||
fi
|
||||
|
||||
# Darwin's linker has a -r argument that merges object files together.
|
||||
# It doesn't work with -rpath.
|
||||
# This variable controls whether they are added.
|
||||
add_rpaths=true
|
||||
if [ "$mode" = ld ] || [ "$mode" = ccld ]; then
|
||||
if [ "${SPACK_SHORT_SPEC#*darwin}" != "${SPACK_SHORT_SPEC}" ]; then
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = "-r" ]; then
|
||||
if [ "$mode" = ld ] || [ "$mode" = ccld ]; then
|
||||
add_rpaths=false
|
||||
break
|
||||
fi
|
||||
elif [ "$arg" = "-Wl,-r" ] && [ "$mode" = ccld ]; then
|
||||
add_rpaths=false
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Save original command for debug logging
|
||||
input_command="$*"
|
||||
|
||||
#
|
||||
# Parse the command line arguments.
|
||||
#
|
||||
# We extract -L, -I, -isystem and -Wl,-rpath arguments from the
|
||||
# command line and recombine them with Spack arguments later. We
|
||||
# parse these out so that we can make sure that system paths come
|
||||
# last, that package arguments come first, and that Spack arguments
|
||||
# are injected properly.
|
||||
#
|
||||
# All other arguments, including -l arguments, are treated as
|
||||
# 'other_args' and left in their original order. This ensures that
|
||||
# --start-group, --end-group, and other order-sensitive flags continue to
|
||||
# work as the caller expects.
|
||||
#
|
||||
# The libs variable is initialized here for completeness, and it is also
|
||||
# used later to inject flags supplied via `ldlibs` on the command
|
||||
# line. These come into the wrappers via SPACK_LDLIBS.
|
||||
|
||||
# The loop below breaks up the command line into these lists of components.
|
||||
# The lists are all bell-separated to be as flexible as possible, as their
|
||||
# contents may come from the command line, from ' '-separated lists,
|
||||
# ':'-separated lists, etc.
|
||||
|
||||
parse_Wl() {
|
||||
while [ $# -ne 0 ]; do
|
||||
if [ "$wl_expect_rpath" = yes ]; then
|
||||
append_path_lists return_rpath_dirs_list "$1"
|
||||
wl_expect_rpath=no
|
||||
else
|
||||
case "$1" in
|
||||
-rpath=*)
|
||||
arg="${1#-rpath=}"
|
||||
if [ -z "$arg" ]; then
|
||||
shift; continue
|
||||
fi
|
||||
append_path_lists return_rpath_dirs_list "$arg"
|
||||
;;
|
||||
--rpath=*)
|
||||
arg="${1#--rpath=}"
|
||||
if [ -z "$arg" ]; then
|
||||
shift; continue
|
||||
fi
|
||||
append_path_lists return_rpath_dirs_list "$arg"
|
||||
;;
|
||||
-rpath|--rpath)
|
||||
wl_expect_rpath=yes
|
||||
;;
|
||||
"$dtags_to_strip")
|
||||
;;
|
||||
-Wl)
|
||||
# Nested -Wl,-Wl means we're in NAG compiler territory. We don't support it.
|
||||
return 1
|
||||
;;
|
||||
*)
|
||||
append return_other_args_list "-Wl,$1"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
categorize_arguments() {
|
||||
|
||||
unset IFS
|
||||
|
||||
return_other_args_list=""
|
||||
return_isystem_was_used=""
|
||||
|
||||
init_path_lists return_isystem_include_dirs_list
|
||||
init_path_lists return_include_dirs_list
|
||||
init_path_lists return_lib_dirs_list
|
||||
init_path_lists return_rpath_dirs_list
|
||||
|
||||
# Global state for keeping track of -Wl,-rpath -Wl,/path
|
||||
wl_expect_rpath=no
|
||||
|
||||
# Same, but for -Xlinker -rpath -Xlinker /path
|
||||
xlinker_expect_rpath=no
|
||||
|
||||
while [ $# -ne 0 ]; do
|
||||
|
||||
# an RPATH to be added after the case statement.
|
||||
rp=""
|
||||
|
||||
# Multiple consecutive spaces in the command line can
|
||||
# result in blank arguments
|
||||
if [ -z "$1" ]; then
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -n "${SPACK_COMPILER_FLAGS_KEEP}" ] ; then
|
||||
# NOTE: the eval is required to allow `|` alternatives inside the variable
|
||||
eval "\
|
||||
case \"\$1\" in
|
||||
$SPACK_COMPILER_FLAGS_KEEP)
|
||||
append return_other_args_list \"\$1\"
|
||||
shift
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
"
|
||||
fi
|
||||
# the replace list is a space-separated list of pipe-separated pairs,
|
||||
# the first in each pair is the original prefix to be matched, the
|
||||
# second is the replacement prefix
|
||||
if [ -n "${SPACK_COMPILER_FLAGS_REPLACE}" ] ; then
|
||||
for rep in ${SPACK_COMPILER_FLAGS_REPLACE} ; do
|
||||
before=${rep%|*}
|
||||
after=${rep#*|}
|
||||
eval "\
|
||||
stripped=\"\${1##$before}\"
|
||||
"
|
||||
if [ "$stripped" = "$1" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
replaced="$after$stripped"
|
||||
|
||||
# it matched, remove it
|
||||
shift
|
||||
|
||||
if [ -z "$replaced" ] ; then
|
||||
# completely removed, continue OUTER loop
|
||||
continue 2
|
||||
fi
|
||||
|
||||
# re-build argument list with replacement
|
||||
set -- "$replaced" "$@"
|
||||
done
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
-isystem*)
|
||||
arg="${1#-isystem}"
|
||||
return_isystem_was_used=true
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
append_path_lists return_isystem_include_dirs_list "$arg"
|
||||
;;
|
||||
-I*)
|
||||
arg="${1#-I}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
append_path_lists return_include_dirs_list "$arg"
|
||||
;;
|
||||
-L*)
|
||||
arg="${1#-L}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
append_path_lists return_lib_dirs_list "$arg"
|
||||
;;
|
||||
-l*)
|
||||
# -loopopt=0 is generated erroneously in autoconf <= 2.69,
|
||||
# and passed by ifx to the linker, which confuses it with a
|
||||
# library. Filter it out.
|
||||
# TODO: generalize filtering of args with an env var, so that
|
||||
# TODO: we do not have to special case this here.
|
||||
if { [ "$mode" = "ccld" ] || [ $mode = "ld" ]; } \
|
||||
&& [ "$1" != "${1#-loopopt}" ]; then
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
arg="${1#-l}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
append return_other_args_list "-l$arg"
|
||||
;;
|
||||
-Wl,*)
|
||||
IFS=,
|
||||
if ! parse_Wl ${1#-Wl,}; then
|
||||
append return_other_args_list "$1"
|
||||
fi
|
||||
unset IFS
|
||||
;;
|
||||
-Xlinker)
|
||||
shift
|
||||
if [ $# -eq 0 ]; then
|
||||
# -Xlinker without value: let the compiler error about it.
|
||||
append return_other_args_list -Xlinker
|
||||
xlinker_expect_rpath=no
|
||||
break
|
||||
elif [ "$xlinker_expect_rpath" = yes ]; then
|
||||
# Register the path of -Xlinker -rpath <other args> -Xlinker <path>
|
||||
append_path_lists return_rpath_dirs_list "$1"
|
||||
xlinker_expect_rpath=no
|
||||
else
|
||||
case "$1" in
|
||||
-rpath=*)
|
||||
arg="${1#-rpath=}"
|
||||
append_path_lists return_rpath_dirs_list "$arg"
|
||||
;;
|
||||
--rpath=*)
|
||||
arg="${1#--rpath=}"
|
||||
append_path_lists return_rpath_dirs_list "$arg"
|
||||
;;
|
||||
-rpath|--rpath)
|
||||
xlinker_expect_rpath=yes
|
||||
;;
|
||||
"$dtags_to_strip")
|
||||
;;
|
||||
*)
|
||||
append return_other_args_list -Xlinker
|
||||
append return_other_args_list "$1"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
"$dtags_to_strip")
|
||||
;;
|
||||
*)
|
||||
# if mode is not ld, we can just add to other args
|
||||
if [ "$mode" != "ld" ]; then
|
||||
append return_other_args_list "$1"
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
|
||||
# if we're in linker mode, we need to parse raw RPATH args
|
||||
case "$1" in
|
||||
-rpath=*)
|
||||
arg="${1#-rpath=}"
|
||||
append_path_lists return_rpath_dirs_list "$arg"
|
||||
;;
|
||||
--rpath=*)
|
||||
arg="${1#--rpath=}"
|
||||
append_path_lists return_rpath_dirs_list "$arg"
|
||||
;;
|
||||
-rpath|--rpath)
|
||||
if [ $# -eq 1 ]; then
|
||||
# -rpath without value: let the linker raise an error.
|
||||
append return_other_args_list "$1"
|
||||
break
|
||||
fi
|
||||
shift
|
||||
append_path_lists return_rpath_dirs_list "$1"
|
||||
;;
|
||||
*)
|
||||
append return_other_args_list "$1"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We found `-Xlinker -rpath` but no matching value `-Xlinker /path`. Just append
|
||||
# `-Xlinker -rpath` again and let the compiler or linker handle the error during arg
|
||||
# parsing.
|
||||
if [ "$xlinker_expect_rpath" = yes ]; then
|
||||
append return_other_args_list -Xlinker
|
||||
append return_other_args_list -rpath
|
||||
fi
|
||||
|
||||
# Same, but for -Wl flags.
|
||||
if [ "$wl_expect_rpath" = yes ]; then
|
||||
append return_other_args_list -Wl,-rpath
|
||||
fi
|
||||
}
|
||||
|
||||
categorize_arguments "$@"
|
||||
|
||||
assign_path_lists isystem_include_dirs_list return_isystem_include_dirs_list
|
||||
assign_path_lists include_dirs_list return_include_dirs_list
|
||||
assign_path_lists lib_dirs_list return_lib_dirs_list
|
||||
assign_path_lists rpath_dirs_list return_rpath_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
|
||||
# ldflags. We stick to the order that gmake puts the flags in by default.
|
||||
#
|
||||
# See the gmake manual on implicit rules for details:
|
||||
# https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
|
||||
#
|
||||
flags_list=""
|
||||
|
||||
# Add debug flags
|
||||
if [ "${SPACK_ADD_DEBUG_FLAGS}" = "true" ]; then
|
||||
extend flags_list debug_flags
|
||||
|
||||
# If a custom flag is requested, derive from environment
|
||||
elif [ "$SPACK_ADD_DEBUG_FLAGS" = "custom" ]; then
|
||||
extend flags_list SPACK_DEBUG_FLAGS
|
||||
fi
|
||||
|
||||
spack_flags_list=""
|
||||
|
||||
# Fortran flags come before CPPFLAGS
|
||||
case "$mode" in
|
||||
cc|ccld)
|
||||
case $lang_flags in
|
||||
F)
|
||||
extend spack_flags_list SPACK_ALWAYS_FFLAGS
|
||||
extend spack_flags_list SPACK_FFLAGS
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# C preprocessor flags come before any C/CXX flags
|
||||
case "$mode" in
|
||||
cpp|as|cc|ccld)
|
||||
extend spack_flags_list SPACK_ALWAYS_CPPFLAGS
|
||||
extend spack_flags_list SPACK_CPPFLAGS
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Add C and C++ flags
|
||||
case "$mode" in
|
||||
cc|ccld)
|
||||
case $lang_flags in
|
||||
C)
|
||||
extend spack_flags_list SPACK_ALWAYS_CFLAGS
|
||||
extend spack_flags_list SPACK_CFLAGS
|
||||
preextend flags_list SPACK_TARGET_ARGS_CC
|
||||
;;
|
||||
CXX)
|
||||
extend spack_flags_list SPACK_ALWAYS_CXXFLAGS
|
||||
extend spack_flags_list SPACK_CXXFLAGS
|
||||
preextend flags_list SPACK_TARGET_ARGS_CXX
|
||||
;;
|
||||
F)
|
||||
preextend flags_list SPACK_TARGET_ARGS_FORTRAN
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Linker flags
|
||||
case "$mode" in
|
||||
ccld)
|
||||
extend spack_flags_list SPACK_LDFLAGS
|
||||
;;
|
||||
esac
|
||||
|
||||
IFS="$lsep"
|
||||
categorize_arguments $spack_flags_list
|
||||
unset IFS
|
||||
|
||||
assign_path_lists spack_flags_isystem_include_dirs_list return_isystem_include_dirs_list
|
||||
assign_path_lists spack_flags_include_dirs_list return_include_dirs_list
|
||||
assign_path_lists spack_flags_lib_dirs_list return_lib_dirs_list
|
||||
assign_path_lists 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
|
||||
if [ "$mode" = ld ] || [ "$mode" = ccld ]; then
|
||||
if [ "${SPACK_SHORT_SPEC#*darwin}" != "${SPACK_SHORT_SPEC}" ]; then
|
||||
case "$mode" in
|
||||
ld)
|
||||
append flags_list "-headerpad_max_install_names" ;;
|
||||
ccld)
|
||||
append flags_list "-Wl,-headerpad_max_install_names" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$mode" = ccld ] || [ "$mode" = ld ]; then
|
||||
if [ "$add_rpaths" != "false" ]; 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
|
||||
|
||||
libs_list=""
|
||||
|
||||
# add RPATHs if we're in in any linking mode
|
||||
case "$mode" in
|
||||
ld|ccld)
|
||||
# Set extra RPATHs
|
||||
extend lib_dirs_list SPACK_COMPILER_EXTRA_RPATHS
|
||||
if [ "$add_rpaths" != "false" ]; then
|
||||
extend rpath_dirs_list SPACK_COMPILER_EXTRA_RPATHS
|
||||
fi
|
||||
|
||||
# Set implicit RPATHs
|
||||
if [ "$add_rpaths" != "false" ]; then
|
||||
extend rpath_dirs_list SPACK_COMPILER_IMPLICIT_RPATHS
|
||||
fi
|
||||
|
||||
# Add SPACK_LDLIBS to args
|
||||
for lib in $SPACK_LDLIBS; do
|
||||
append libs_list "${lib#-l}"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$mode" in
|
||||
cpp|cc|as|ccld)
|
||||
if [ "$spack_flags_isystem_was_used" = "true" ] || [ "$isystem_was_used" = "true" ]; then
|
||||
extend spack_store_isystem_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"
|
||||
|
||||
# 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_store_spack_flags_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_store_spack_flags_isystem_include_dirs_list "-isystem${lsep}"
|
||||
extend args_list spack_store_isystem_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}"
|
||||
|
||||
extend args_list system_spack_flags_include_dirs_list -I
|
||||
extend args_list system_include_dirs_list -I
|
||||
|
||||
extend args_list system_spack_flags_isystem_include_dirs_list "-isystem${lsep}"
|
||||
extend args_list system_isystem_include_dirs_list "-isystem${lsep}"
|
||||
|
||||
# Library search paths partitioned by (in store, non-sytem, system)
|
||||
extend args_list spack_store_spack_flags_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 system_spack_flags_lib_dirs_list "-L"
|
||||
extend args_list system_lib_dirs_list "-L"
|
||||
|
||||
# RPATHs arguments
|
||||
rpath_prefix=""
|
||||
case "$mode" in
|
||||
ccld)
|
||||
if [ -n "$dtags_to_add" ] ; then
|
||||
append args_list "$linker_arg$dtags_to_add"
|
||||
fi
|
||||
rpath_prefix="$rpath"
|
||||
;;
|
||||
ld)
|
||||
if [ -n "$dtags_to_add" ] ; then
|
||||
append args_list "$dtags_to_add"
|
||||
fi
|
||||
rpath_prefix="-rpath${lsep}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# if mode is ccld or ld, extend RPATH lists with the prefix determined above
|
||||
if [ -n "$rpath_prefix" ]; then
|
||||
extend args_list spack_store_spack_flags_rpath_dirs_list "$rpath_prefix"
|
||||
extend args_list spack_store_rpath_dirs_list "$rpath_prefix"
|
||||
|
||||
extend args_list spack_flags_rpath_dirs_list "$rpath_prefix"
|
||||
extend args_list rpath_dirs_list "$rpath_prefix"
|
||||
|
||||
extend args_list system_spack_flags_rpath_dirs_list "$rpath_prefix"
|
||||
extend args_list system_rpath_dirs_list "$rpath_prefix"
|
||||
fi
|
||||
|
||||
# Other arguments from the input command
|
||||
extend args_list other_args_list
|
||||
extend args_list spack_flags_other_args_list
|
||||
|
||||
# Inject SPACK_LDLIBS, if supplied
|
||||
extend args_list libs_list "-l"
|
||||
|
||||
full_command_list="$command"
|
||||
extend full_command_list args_list
|
||||
|
||||
# prepend the ccache binary if we're using ccache
|
||||
if [ -n "$SPACK_CCACHE_BINARY" ]; then
|
||||
case "$lang_flags" in
|
||||
C|CXX) # ccache only supports C languages
|
||||
prepend full_command_list "${SPACK_CCACHE_BINARY}"
|
||||
# workaround for stage being a temp folder
|
||||
# see #3761#issuecomment-294352232
|
||||
export CCACHE_NOHASHDIR=yes
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
execute
|
1
lib/spack/env/cce/case-insensitive/CC
vendored
1
lib/spack/env/cce/case-insensitive/CC
vendored
@@ -1 +0,0 @@
|
||||
../../cc
|
1
lib/spack/env/cce/case-insensitive/crayCC
vendored
1
lib/spack/env/cce/case-insensitive/crayCC
vendored
@@ -1 +0,0 @@
|
||||
../../cc
|
1
lib/spack/env/cce/cc
vendored
1
lib/spack/env/cce/cc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cce/craycc
vendored
1
lib/spack/env/cce/craycc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cce/crayftn
vendored
1
lib/spack/env/cce/crayftn
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cce/ftn
vendored
1
lib/spack/env/cce/ftn
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/clang
vendored
1
lib/spack/env/clang/clang
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/clang++
vendored
1
lib/spack/env/clang/clang++
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/flang
vendored
1
lib/spack/env/clang/flang
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/gfortran
vendored
1
lib/spack/env/clang/gfortran
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cpp
vendored
1
lib/spack/env/cpp
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/f77
vendored
1
lib/spack/env/f77
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/f90
vendored
1
lib/spack/env/f90
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/f95
vendored
1
lib/spack/env/f95
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/fc
vendored
1
lib/spack/env/fc
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/fj/case-insensitive/FCC
vendored
1
lib/spack/env/fj/case-insensitive/FCC
vendored
@@ -1 +0,0 @@
|
||||
../../cc
|
1
lib/spack/env/fj/fcc
vendored
1
lib/spack/env/fj/fcc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/fj/frt
vendored
1
lib/spack/env/fj/frt
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/ftn
vendored
1
lib/spack/env/ftn
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/gcc/g++
vendored
1
lib/spack/env/gcc/g++
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/gcc/gcc
vendored
1
lib/spack/env/gcc/gcc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/gcc/gfortran
vendored
1
lib/spack/env/gcc/gfortran
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/intel/icc
vendored
1
lib/spack/env/intel/icc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/intel/icpc
vendored
1
lib/spack/env/intel/icpc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/intel/ifort
vendored
1
lib/spack/env/intel/ifort
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/ld
vendored
1
lib/spack/env/ld
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/ld.gold
vendored
1
lib/spack/env/ld.gold
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/ld.lld
vendored
1
lib/spack/env/ld.lld
vendored
@@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/nag/nagfor
vendored
1
lib/spack/env/nag/nagfor
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/nvhpc/nvc
vendored
1
lib/spack/env/nvhpc/nvc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/nvhpc/nvc++
vendored
1
lib/spack/env/nvhpc/nvc++
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/nvhpc/nvfortran
vendored
1
lib/spack/env/nvhpc/nvfortran
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/dpcpp
vendored
1
lib/spack/env/oneapi/dpcpp
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/icpx
vendored
1
lib/spack/env/oneapi/icpx
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/icx
vendored
1
lib/spack/env/oneapi/icx
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/ifx
vendored
1
lib/spack/env/oneapi/ifx
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/pgi/pgc++
vendored
1
lib/spack/env/pgi/pgc++
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/pgi/pgcc
vendored
1
lib/spack/env/pgi/pgcc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/pgi/pgfortran
vendored
1
lib/spack/env/pgi/pgfortran
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/rocmcc/amdclang
vendored
1
lib/spack/env/rocmcc/amdclang
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/rocmcc/amdclang++
vendored
1
lib/spack/env/rocmcc/amdclang++
vendored
@@ -1 +0,0 @@
|
||||
../cpp
|
1
lib/spack/env/rocmcc/amdflang
vendored
1
lib/spack/env/rocmcc/amdflang
vendored
@@ -1 +0,0 @@
|
||||
../fc
|
1
lib/spack/env/xl/xlc
vendored
1
lib/spack/env/xl/xlc
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl/xlc++
vendored
1
lib/spack/env/xl/xlc++
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl/xlf
vendored
1
lib/spack/env/xl/xlf
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl/xlf90
vendored
1
lib/spack/env/xl/xlf90
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlc++_r
vendored
1
lib/spack/env/xl_r/xlc++_r
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlc_r
vendored
1
lib/spack/env/xl_r/xlc_r
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlf90_r
vendored
1
lib/spack/env/xl_r/xlf90_r
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlf_r
vendored
1
lib/spack/env/xl_r/xlf_r
vendored
@@ -1 +0,0 @@
|
||||
../cc
|
@@ -21,6 +21,7 @@
|
||||
import spack.platforms
|
||||
import spack.spec
|
||||
import spack.traverse
|
||||
import spack.version
|
||||
|
||||
from .config import spec_for_current_python
|
||||
|
||||
@@ -126,6 +127,10 @@ def concretize(self) -> "spack.spec.Spec":
|
||||
if node.name == "gcc-runtime":
|
||||
node.versions = self.host_compiler.versions
|
||||
|
||||
# Can't use re2c@3.1 with Python 3.6
|
||||
if self.host_python.satisfies("@3.6"):
|
||||
s["re2c"].versions.versions = [spack.version.from_string("=2.2")]
|
||||
|
||||
for edge in spack.traverse.traverse_edges([s], cover="edges"):
|
||||
if edge.spec.name == "python":
|
||||
edge.spec = self.host_python
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -584,23 +584,6 @@ def set_package_py_globals(pkg, context: Context = Context.BUILD):
|
||||
# Don't use which for this; we want to find it in the current dir.
|
||||
module.configure = Executable("./configure")
|
||||
|
||||
# Put spack compiler paths in module scope. (Some packages use it
|
||||
# in setup_run_environment etc, so don't put it context == build)
|
||||
link_dir = spack.paths.build_env_path
|
||||
|
||||
# Set spack_cc, etc. for backward compatibility. This might change if the compiler wrapper
|
||||
# is modeled as a package.
|
||||
global_names = {
|
||||
"c": ("spack_cc",),
|
||||
"cxx": ("spack_cxx",),
|
||||
"fortran": ("spack_fc", "spack_f77"),
|
||||
}
|
||||
for language in ("c", "cxx", "fortran"):
|
||||
spec = pkg.spec.dependencies(virtuals=[language])
|
||||
value = None if not spec else os.path.join(link_dir, spec[0].package.link_paths[language])
|
||||
for name in global_names[language]:
|
||||
setattr(module, name, value)
|
||||
|
||||
# Useful directories within the prefix are encapsulated in
|
||||
# a Prefix object.
|
||||
module.prefix = pkg.prefix
|
||||
|
@@ -4,22 +4,16 @@
|
||||
import itertools
|
||||
import os
|
||||
import pathlib
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
from typing import Dict, List, Optional, Sequence, Tuple, Union
|
||||
|
||||
import archspec.cpu
|
||||
|
||||
import llnl.util.tty as tty
|
||||
from llnl.util.lang import classproperty, memoized
|
||||
|
||||
import spack
|
||||
import spack.compilers.error
|
||||
import spack.compilers.libraries
|
||||
import spack.config
|
||||
import spack.package_base
|
||||
import spack.paths
|
||||
import spack.util.executable
|
||||
|
||||
# Local "type" for type hints
|
||||
@@ -109,7 +103,7 @@ def determine_version(cls, exe: Path) -> str:
|
||||
|
||||
@classmethod
|
||||
def compiler_bindir(cls, prefix: Path) -> Path:
|
||||
"""Overridable method for the location of the compiler bindir within the preifx"""
|
||||
"""Overridable method for the location of the compiler bindir within the prefix"""
|
||||
return os.path.join(prefix, "bin")
|
||||
|
||||
@classmethod
|
||||
@@ -183,109 +177,6 @@ def standard_flag(self, *, language: str, standard: str) -> str:
|
||||
def _standard_flag(self, *, language: str, standard: str) -> str:
|
||||
raise NotImplementedError("Must be implemented by derived classes")
|
||||
|
||||
@property
|
||||
def disable_new_dtags(self) -> str:
|
||||
if platform.system() == "Darwin":
|
||||
return ""
|
||||
return "--disable-new-dtags"
|
||||
|
||||
@property
|
||||
def enable_new_dtags(self) -> str:
|
||||
if platform.system() == "Darwin":
|
||||
return ""
|
||||
return "--enable-new-dtags"
|
||||
|
||||
def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
# FIXME (compiler as nodes): check if this is good enough or should be made more general
|
||||
|
||||
# The package is not used as a compiler, so skip this setup
|
||||
if not any(
|
||||
lang in dependent_spec and dependent_spec[lang].name == self.spec.name
|
||||
for lang in ("c", "cxx", "fortran")
|
||||
):
|
||||
return
|
||||
|
||||
# Populate an object with the list of environment modifications and return it
|
||||
link_dir = pathlib.Path(spack.paths.build_env_path)
|
||||
env_paths = []
|
||||
|
||||
for language, attr_name, wrapper_var_name, spack_var_name in [
|
||||
("c", "cc", "CC", "SPACK_CC"),
|
||||
("cxx", "cxx", "CXX", "SPACK_CXX"),
|
||||
("fortran", "fortran", "F77", "SPACK_F77"),
|
||||
("fortran", "fortran", "FC", "SPACK_FC"),
|
||||
]:
|
||||
if language not in dependent_spec or dependent_spec[language].name != self.spec.name:
|
||||
continue
|
||||
|
||||
if not hasattr(self, attr_name):
|
||||
continue
|
||||
|
||||
compiler = getattr(self, attr_name)
|
||||
env.set(spack_var_name, compiler)
|
||||
|
||||
if language not in self.link_paths:
|
||||
continue
|
||||
|
||||
wrapper_path = link_dir / self.link_paths.get(language)
|
||||
env.set(wrapper_var_name, str(wrapper_path))
|
||||
env.set(f"SPACK_{wrapper_var_name}_RPATH_ARG", self.rpath_arg)
|
||||
|
||||
uarch = dependent_spec.architecture.target
|
||||
version_number, _ = archspec.cpu.version_components(
|
||||
self.spec.version.dotted_numeric_string
|
||||
)
|
||||
try:
|
||||
isa_arg = uarch.optimization_flags(self.archspec_name(), version_number)
|
||||
except (ValueError, archspec.cpu.UnsupportedMicroarchitecture):
|
||||
isa_arg = ""
|
||||
|
||||
if isa_arg:
|
||||
env.set(f"SPACK_TARGET_ARGS_{attr_name.upper()}", isa_arg)
|
||||
|
||||
# Add spack build environment path with compiler wrappers first in
|
||||
# the path. We add the compiler wrapper path, which includes default
|
||||
# wrappers (cc, c++, f77, f90), AND a subdirectory containing
|
||||
# compiler-specific symlinks. The latter ensures that builds that
|
||||
# are sensitive to the *name* of the compiler see the right name when
|
||||
# we're building with the wrappers.
|
||||
#
|
||||
# Conflicts on case-insensitive systems (like "CC" and "cc") are
|
||||
# handled by putting one in the <build_env_path>/case-insensitive
|
||||
# directory. Add that to the path too.
|
||||
compiler_specific = os.path.join(
|
||||
spack.paths.build_env_path, os.path.dirname(self.link_paths[language])
|
||||
)
|
||||
for item in [spack.paths.build_env_path, compiler_specific]:
|
||||
env_paths.append(item)
|
||||
ci = os.path.join(item, "case-insensitive")
|
||||
if os.path.isdir(ci):
|
||||
env_paths.append(ci)
|
||||
|
||||
# FIXME (compiler as nodes): make these paths language specific
|
||||
env.set("SPACK_LINKER_ARG", self.linker_arg)
|
||||
|
||||
paths = _implicit_rpaths(pkg=self)
|
||||
if paths:
|
||||
env.set("SPACK_COMPILER_IMPLICIT_RPATHS", ":".join(paths))
|
||||
|
||||
# Check whether we want to force RPATH or RUNPATH
|
||||
if spack.config.CONFIG.get("config:shared_linking:type") == "rpath":
|
||||
env.set("SPACK_DTAGS_TO_STRIP", self.enable_new_dtags)
|
||||
env.set("SPACK_DTAGS_TO_ADD", self.disable_new_dtags)
|
||||
else:
|
||||
env.set("SPACK_DTAGS_TO_STRIP", self.disable_new_dtags)
|
||||
env.set("SPACK_DTAGS_TO_ADD", self.enable_new_dtags)
|
||||
|
||||
spec = self.spec
|
||||
if spec.extra_attributes:
|
||||
extra_rpaths = spec.extra_attributes.get("extra_rpaths")
|
||||
if extra_rpaths:
|
||||
env.append_path("SPACK_COMPILER_EXTRA_RPATHS", ":".join(extra_rpaths))
|
||||
|
||||
for item in env_paths:
|
||||
env.prepend_path("SPACK_ENV_PATH", item)
|
||||
|
||||
def archspec_name(self) -> str:
|
||||
"""Name that archspec uses to refer to this compiler"""
|
||||
return self.spec.name
|
||||
@@ -324,12 +215,6 @@ def _fortran_path(self) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def _implicit_rpaths(pkg: spack.package_base.PackageBase) -> List[str]:
|
||||
detector = spack.compilers.libraries.CompilerPropertyDetector(pkg.spec)
|
||||
paths = detector.implicit_rpaths()
|
||||
return paths
|
||||
|
||||
|
||||
@memoized
|
||||
def _compiler_output(
|
||||
compiler_path: Path, *, version_argument: str, ignore_errors: Tuple[int, ...] = ()
|
||||
|
@@ -38,7 +38,6 @@
|
||||
r"^lib/spack/spack/.*\.sh$",
|
||||
r"^lib/spack/spack/.*\.lp$",
|
||||
r"^lib/spack/llnl/.*\.py$",
|
||||
r"^lib/spack/env/cc$",
|
||||
# special case some test data files that have license headers
|
||||
r"^lib/spack/spack/test/data/style/broken.dummy",
|
||||
r"^lib/spack/spack/test/data/unparse/.*\.txt",
|
||||
|
@@ -31,7 +31,6 @@
|
||||
# spack directory hierarchy
|
||||
lib_path = os.path.join(prefix, "lib", "spack")
|
||||
external_path = os.path.join(lib_path, "external")
|
||||
build_env_path = os.path.join(lib_path, "env")
|
||||
module_path = os.path.join(lib_path, "spack")
|
||||
command_path = os.path.join(module_path, "cmd")
|
||||
analyzers_path = os.path.join(module_path, "analyzers")
|
||||
|
@@ -3149,6 +3149,16 @@ def define_runtime_constraints(self):
|
||||
# Inject default flags for compilers
|
||||
recorder("*").default_flags(compiler)
|
||||
|
||||
# FIXME (compiler as nodes): think of using isinstance(compiler_cls, WrappedCompiler)
|
||||
# Add a dependency on the compiler wrapper
|
||||
if sys.platform != "win32":
|
||||
recorder("*").depends_on(
|
||||
"compiler-wrapper",
|
||||
when=f"%{compiler.name}@{compiler.versions}",
|
||||
type="build",
|
||||
description=f"Add the compiler wrapper when using {compiler}",
|
||||
)
|
||||
|
||||
if not using_libc_compatibility():
|
||||
continue
|
||||
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
import os
|
||||
import platform
|
||||
import posixpath
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -13,19 +13,16 @@
|
||||
from llnl.util.filesystem import HeaderList, LibraryList
|
||||
|
||||
import spack.build_environment
|
||||
import spack.build_systems.compiler
|
||||
import spack.concretize
|
||||
import spack.config
|
||||
import spack.deptypes as dt
|
||||
import spack.package_base
|
||||
import spack.paths
|
||||
import spack.spec
|
||||
import spack.util.environment
|
||||
import spack.util.spack_yaml as syaml
|
||||
from spack.build_environment import UseMode, _static_to_shared_library, dso_suffix
|
||||
from spack.context import Context
|
||||
from spack.installer import PackageInstaller
|
||||
from spack.paths import build_env_path
|
||||
from spack.util.environment import EnvironmentModifications
|
||||
from spack.util.executable import Executable
|
||||
|
||||
@@ -42,55 +39,41 @@ def prep_and_join(path, *pths):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def build_environment(working_env):
|
||||
cc = Executable(os.path.join(build_env_path, "cc"))
|
||||
cxx = Executable(os.path.join(build_env_path, "c++"))
|
||||
fc = Executable(os.path.join(build_env_path, "fc"))
|
||||
|
||||
def build_environment(monkeypatch, wrapper_dir, tmp_path):
|
||||
realcc = "/bin/mycc"
|
||||
prefix = "/spack-test-prefix"
|
||||
prefix = str(tmp_path)
|
||||
|
||||
os.environ["SPACK_CC"] = realcc
|
||||
os.environ["SPACK_CXX"] = realcc
|
||||
os.environ["SPACK_FC"] = realcc
|
||||
monkeypatch.setenv("SPACK_CC", realcc)
|
||||
monkeypatch.setenv("SPACK_CXX", realcc)
|
||||
monkeypatch.setenv("SPACK_FC", realcc)
|
||||
|
||||
os.environ["SPACK_PREFIX"] = prefix
|
||||
os.environ["SPACK_ENV_PATH"] = "test"
|
||||
os.environ["SPACK_DEBUG_LOG_DIR"] = "."
|
||||
os.environ["SPACK_DEBUG_LOG_ID"] = "foo-hashabc"
|
||||
os.environ["SPACK_SHORT_SPEC"] = "foo@1.2 arch=linux-rhel6-x86_64 /hashabc"
|
||||
monkeypatch.setenv("SPACK_PREFIX", prefix)
|
||||
monkeypatch.setenv("SPACK_ENV_PATH", "test")
|
||||
monkeypatch.setenv("SPACK_DEBUG_LOG_DIR", ".")
|
||||
monkeypatch.setenv("SPACK_DEBUG_LOG_ID", "foo-hashabc")
|
||||
monkeypatch.setenv("SPACK_SHORT_SPEC", "foo@1.2 arch=linux-rhel6-x86_64 /hashabc")
|
||||
|
||||
os.environ["SPACK_CC_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
os.environ["SPACK_CXX_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
os.environ["SPACK_F77_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
os.environ["SPACK_FC_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
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_MANAGED_DIRS"] = f"{prefix}/opt/spack"
|
||||
os.environ["SPACK_TARGET_ARGS"] = ""
|
||||
monkeypatch.setenv("SPACK_CC_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_CXX_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_F77_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_FC_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_CC_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_CXX_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_FC_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_F77_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_DTAGS_TO_ADD", "--disable-new-dtags")
|
||||
monkeypatch.setenv("SPACK_DTAGS_TO_STRIP", "--enable-new-dtags")
|
||||
monkeypatch.setenv("SPACK_SYSTEM_DIRS", "/usr/include|/usr/lib")
|
||||
monkeypatch.setenv("SPACK_MANAGED_DIRS", f"{prefix}/opt/spack")
|
||||
monkeypatch.setenv("SPACK_TARGET_ARGS", "")
|
||||
|
||||
if "SPACK_DEPENDENCIES" in os.environ:
|
||||
del os.environ["SPACK_DEPENDENCIES"]
|
||||
monkeypatch.delenv("SPACK_DEPENDENCIES", raising=False)
|
||||
|
||||
yield {"cc": cc, "cxx": cxx, "fc": fc}
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
cxx = Executable(str(wrapper_dir / "c++"))
|
||||
fc = Executable(str(wrapper_dir / "fc"))
|
||||
|
||||
for name in (
|
||||
"SPACK_CC",
|
||||
"SPACK_CXX",
|
||||
"SPACK_FC",
|
||||
"SPACK_PREFIX",
|
||||
"SPACK_ENV_PATH",
|
||||
"SPACK_DEBUG_LOG_DIR",
|
||||
"SPACK_SHORT_SPEC",
|
||||
"SPACK_CC_RPATH_ARG",
|
||||
"SPACK_CXX_RPATH_ARG",
|
||||
"SPACK_F77_RPATH_ARG",
|
||||
"SPACK_FC_RPATH_ARG",
|
||||
"SPACK_TARGET_ARGS",
|
||||
):
|
||||
del os.environ[name]
|
||||
return {"cc": cc, "cxx": cxx, "fc": fc}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -322,14 +305,14 @@ def test_external_config_env(mock_packages, mutable_config, working_env):
|
||||
@pytest.mark.regression("9107")
|
||||
@pytest.mark.not_on_windows("Windows does not support module files")
|
||||
def test_spack_paths_before_module_paths(
|
||||
mutable_config, mock_packages, compiler_factory, monkeypatch, working_env
|
||||
mutable_config, mock_packages, compiler_factory, monkeypatch, working_env, wrapper_dir
|
||||
):
|
||||
gcc_entry = compiler_factory(spec="gcc@14.0.1 languages=c,c++")
|
||||
gcc_entry["modules"] = ["some_module"]
|
||||
mutable_config.set("packages", {"gcc": {"externals": [gcc_entry]}})
|
||||
|
||||
module_path = os.path.join("path", "to", "module")
|
||||
spack_path = os.path.join(spack.paths.prefix, os.path.join("lib", "spack", "env"))
|
||||
monkeypatch.setenv("SPACK_ENV_PATH", wrapper_dir)
|
||||
|
||||
def _set_wrong_cc(x):
|
||||
os.environ["PATH"] = module_path + os.pathsep + os.environ["PATH"]
|
||||
@@ -341,7 +324,7 @@ def _set_wrong_cc(x):
|
||||
spack.build_environment.setup_package(s.package, dirty=False)
|
||||
|
||||
paths = os.environ["PATH"].split(os.pathsep)
|
||||
assert paths.index(spack_path) < paths.index(module_path)
|
||||
assert paths.index(str(wrapper_dir)) < paths.index(module_path)
|
||||
|
||||
|
||||
def test_package_inheritance_module_setup(config, mock_packages, working_env):
|
||||
@@ -484,11 +467,9 @@ def test_parallel_false_is_not_propagating(default_mock_concretization):
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config_setting,expected_flag",
|
||||
[
|
||||
("runpath", "" if platform.system() == "Darwin" else "--enable-new-dtags"),
|
||||
("rpath", "" if platform.system() == "Darwin" else "--disable-new-dtags"),
|
||||
],
|
||||
[("runpath", "--enable-new-dtags"), ("rpath", "--disable-new-dtags")],
|
||||
)
|
||||
@pytest.mark.skipif(sys.platform != "linux", reason="dtags make sense only on linux")
|
||||
def test_setting_dtags_based_on_config(
|
||||
config_setting, expected_flag, config, mock_packages, working_env
|
||||
):
|
||||
@@ -787,12 +768,11 @@ def test_optimization_flags_are_using_node_target(default_mock_concretization, m
|
||||
"""Tests that we are using the target on the node to be compiled to retrieve the uarch
|
||||
specific flags, and not the target of the compiler.
|
||||
"""
|
||||
monkeypatch.setattr(spack.build_systems.compiler, "_implicit_rpaths", lambda pkg: [])
|
||||
gcc = default_mock_concretization("gcc target=core2")
|
||||
compiler_wrapper_pkg = default_mock_concretization("compiler-wrapper target=core2").package
|
||||
mpileaks = default_mock_concretization("mpileaks target=x86_64")
|
||||
|
||||
env = EnvironmentModifications()
|
||||
gcc.package.setup_dependent_build_environment(env, mpileaks)
|
||||
compiler_wrapper_pkg.setup_dependent_build_environment(env, mpileaks)
|
||||
actions = env.group_by_name()["SPACK_TARGET_ARGS_CC"]
|
||||
|
||||
assert len(actions) == 1 and isinstance(actions[0], spack.util.environment.SetEnv)
|
||||
|
@@ -12,7 +12,6 @@
|
||||
|
||||
import spack.build_environment
|
||||
import spack.config
|
||||
from spack.paths import build_env_path
|
||||
from spack.util.environment import SYSTEM_DIR_CASE_ENTRY, set_env
|
||||
from spack.util.executable import Executable, ProcessError
|
||||
|
||||
@@ -110,12 +109,6 @@
|
||||
#: The prefix of the package being mock installed
|
||||
pkg_prefix = "/spack-test-prefix"
|
||||
|
||||
# Compilers to use during tests
|
||||
cc = Executable(os.path.join(build_env_path, "cc"))
|
||||
ld = Executable(os.path.join(build_env_path, "ld"))
|
||||
cpp = Executable(os.path.join(build_env_path, "cpp"))
|
||||
cxx = Executable(os.path.join(build_env_path, "c++"))
|
||||
fc = Executable(os.path.join(build_env_path, "fc"))
|
||||
|
||||
#: the "real" compiler the wrapper is expected to invoke
|
||||
real_cc = "/bin/mycc"
|
||||
@@ -169,7 +162,10 @@ def wrapper_environment(working_env):
|
||||
SPACK_TARGET_ARGS_CC="-march=znver2 -mtune=znver2",
|
||||
SPACK_TARGET_ARGS_CXX="-march=znver2 -mtune=znver2",
|
||||
SPACK_TARGET_ARGS_FORTRAN="-march=znver4 -mtune=znver4",
|
||||
SPACK_LINKER_ARG="-Wl,",
|
||||
SPACK_CC_LINKER_ARG="-Wl,",
|
||||
SPACK_CXX_LINKER_ARG="-Wl,",
|
||||
SPACK_FC_LINKER_ARG="-Wl,",
|
||||
SPACK_F77_LINKER_ARG="-Wl,",
|
||||
SPACK_DTAGS_TO_ADD="--disable-new-dtags",
|
||||
SPACK_DTAGS_TO_STRIP="--enable-new-dtags",
|
||||
SPACK_COMPILER_FLAGS_KEEP="",
|
||||
@@ -198,6 +194,7 @@ def check_args(cc, args, expected):
|
||||
per line, so that we see whether arguments that should (or shouldn't)
|
||||
contain spaces are parsed correctly.
|
||||
"""
|
||||
cc = Executable(str(cc))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
cc_modified_args = cc(*args, output=str).strip().split("\n")
|
||||
assert cc_modified_args == expected
|
||||
@@ -210,9 +207,9 @@ def check_args_contents(cc, args, must_contain, must_not_contain):
|
||||
per line, so that we see whether arguments that should (or shouldn't)
|
||||
contain spaces are parsed correctly.
|
||||
"""
|
||||
cc = Executable(str(cc))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
cc_modified_args = cc(*args, output=str).strip().split("\n")
|
||||
print(cc_modified_args)
|
||||
for a in must_contain:
|
||||
assert a in cc_modified_args
|
||||
for a in must_not_contain:
|
||||
@@ -225,6 +222,7 @@ def check_env_var(executable, var, expected):
|
||||
This assumes that cc will print debug output when it's environment
|
||||
contains SPACK_TEST_COMMAND=dump-env-<variable-to-debug>
|
||||
"""
|
||||
executable = Executable(str(executable))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-env-" + var):
|
||||
output = executable(*test_args, output=str).strip()
|
||||
assert executable.path + ": " + var + ": " + expected == output
|
||||
@@ -232,17 +230,25 @@ def check_env_var(executable, var, expected):
|
||||
|
||||
def dump_mode(cc, args):
|
||||
"""Make cc dump the mode it detects, and return it."""
|
||||
cc = Executable(str(cc))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-mode"):
|
||||
return cc(*args, output=str).strip()
|
||||
|
||||
|
||||
def test_no_wrapper_environment():
|
||||
def test_no_wrapper_environment(wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
with pytest.raises(ProcessError):
|
||||
output = cc(output=str)
|
||||
assert "Spack compiler must be run from Spack" in output
|
||||
|
||||
|
||||
def test_vcheck_mode(wrapper_environment):
|
||||
def test_modes(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
cxx = wrapper_dir / "c++"
|
||||
cpp = wrapper_dir / "cpp"
|
||||
ld = wrapper_dir / "ld"
|
||||
|
||||
# vcheck
|
||||
assert dump_mode(cc, ["-I/include", "--version"]) == "vcheck"
|
||||
assert dump_mode(cc, ["-I/include", "-V"]) == "vcheck"
|
||||
assert dump_mode(cc, ["-I/include", "-v"]) == "vcheck"
|
||||
@@ -250,38 +256,39 @@ def test_vcheck_mode(wrapper_environment):
|
||||
assert dump_mode(cc, ["-I/include", "--version", "-c"]) == "vcheck"
|
||||
assert dump_mode(cc, ["-I/include", "-V", "-o", "output"]) == "vcheck"
|
||||
|
||||
|
||||
def test_cpp_mode(wrapper_environment):
|
||||
# cpp
|
||||
assert dump_mode(cc, ["-E"]) == "cpp"
|
||||
assert dump_mode(cxx, ["-E"]) == "cpp"
|
||||
assert dump_mode(cpp, []) == "cpp"
|
||||
|
||||
|
||||
def test_as_mode(wrapper_environment):
|
||||
# as
|
||||
assert dump_mode(cc, ["-S"]) == "as"
|
||||
|
||||
|
||||
def test_ccld_mode(wrapper_environment):
|
||||
# ccld
|
||||
assert dump_mode(cc, []) == "ccld"
|
||||
assert dump_mode(cc, ["foo.c", "-o", "foo"]) == "ccld"
|
||||
assert dump_mode(cc, ["foo.c", "-o", "foo", "-Wl,-rpath,foo"]) == "ccld"
|
||||
assert dump_mode(cc, ["foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath,foo"]) == "ccld"
|
||||
|
||||
|
||||
def test_ld_mode(wrapper_environment):
|
||||
# ld
|
||||
assert dump_mode(ld, []) == "ld"
|
||||
assert dump_mode(ld, ["foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath,foo"]) == "ld"
|
||||
|
||||
|
||||
def test_ld_unterminated_rpath(wrapper_environment):
|
||||
@pytest.mark.regression("37179")
|
||||
def test_expected_args(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
fc = wrapper_dir / "fc"
|
||||
ld = wrapper_dir / "ld"
|
||||
|
||||
# ld_unterminated_rpath
|
||||
check_args(
|
||||
ld,
|
||||
["foo.o", "bar.o", "baz.o", "-o", "foo", "-rpath"],
|
||||
["ld", "--disable-new-dtags", "foo.o", "bar.o", "baz.o", "-o", "foo", "-rpath"],
|
||||
)
|
||||
|
||||
|
||||
def test_xlinker_unterminated_rpath(wrapper_environment):
|
||||
# xlinker_unterminated_rpath
|
||||
check_args(
|
||||
cc,
|
||||
["foo.o", "bar.o", "baz.o", "-o", "foo", "-Xlinker", "-rpath"],
|
||||
@@ -299,8 +306,7 @@ def test_xlinker_unterminated_rpath(wrapper_environment):
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_wl_unterminated_rpath(wrapper_environment):
|
||||
# wl_unterminated_rpath
|
||||
check_args(
|
||||
cc,
|
||||
["foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath"],
|
||||
@@ -309,99 +315,7 @@ def test_wl_unterminated_rpath(wrapper_environment):
|
||||
+ ["-Wl,--disable-new-dtags", "foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath"],
|
||||
)
|
||||
|
||||
|
||||
def test_ld_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
ld,
|
||||
test_args,
|
||||
["ld"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ ["--disable-new-dtags"]
|
||||
+ test_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_cpp_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
cpp,
|
||||
test_args,
|
||||
["cpp"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags,
|
||||
)
|
||||
|
||||
|
||||
def test_cc_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
cc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ spack_cflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_cxx_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
cxx,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_fc_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
fc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args_fc
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_fflags
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_always_cflags(wrapper_environment, wrapper_flags):
|
||||
with set_env(SPACK_ALWAYS_CFLAGS="-always1 -always2"):
|
||||
check_args(
|
||||
cc,
|
||||
["-v", "--cmd-line-v-opt"],
|
||||
[real_cc] + ["-always1", "-always2"] + ["-v", "--cmd-line-v-opt"],
|
||||
)
|
||||
|
||||
|
||||
def test_Wl_parsing(wrapper_environment):
|
||||
# Wl_parsing
|
||||
check_args(
|
||||
cc,
|
||||
["-Wl,-rpath,/a,--enable-new-dtags,-rpath=/b,--rpath", "-Wl,/c"],
|
||||
@@ -410,26 +324,22 @@ def test_Wl_parsing(wrapper_environment):
|
||||
+ ["-Wl,--disable-new-dtags", "-Wl,-rpath,/a", "-Wl,-rpath,/b", "-Wl,-rpath,/c"],
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.regression("37179")
|
||||
def test_Wl_parsing_with_missing_value(wrapper_environment):
|
||||
# Wl_parsing_with_missing_value
|
||||
check_args(
|
||||
cc,
|
||||
["-Wl,-rpath=/a,-rpath=", "-Wl,--rpath="],
|
||||
[real_cc] + target_args + ["-Wl,--disable-new-dtags", "-Wl,-rpath,/a"],
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.regression("37179")
|
||||
def test_Wl_parsing_NAG_is_ignored(wrapper_environment):
|
||||
# Wl_parsing_NAG_is_ignored
|
||||
check_args(
|
||||
fc,
|
||||
["-Wl,-Wl,,x,,y,,z"],
|
||||
[real_cc] + target_args_fc + ["-Wl,--disable-new-dtags", "-Wl,-Wl,,x,,y,,z"],
|
||||
)
|
||||
|
||||
|
||||
def test_Xlinker_parsing(wrapper_environment):
|
||||
# Xlinker_parsing
|
||||
#
|
||||
# -Xlinker <x> ... -Xlinker <y> may have compiler flags inbetween, like -O3 in this
|
||||
# example. Also check that a trailing -Xlinker (which is a compiler error) is not
|
||||
# dropped or given an empty argument.
|
||||
@@ -460,8 +370,8 @@ def test_Xlinker_parsing(wrapper_environment):
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_rpath_without_value(wrapper_environment):
|
||||
# rpath_without_value
|
||||
#
|
||||
# cc -Wl,-rpath without a value shouldn't drop -Wl,-rpath;
|
||||
# same for -Xlinker
|
||||
check_args(
|
||||
@@ -475,14 +385,10 @@ def test_rpath_without_value(wrapper_environment):
|
||||
[real_cc] + target_args + ["-Wl,--disable-new-dtags", "-O3", "-g", "-Xlinker", "-rpath"],
|
||||
)
|
||||
|
||||
|
||||
def test_dep_rpath(wrapper_environment):
|
||||
"""Ensure RPATHs for root package are added."""
|
||||
# dep_rapth
|
||||
check_args(cc, test_args, [real_cc] + target_args + common_compile_args)
|
||||
|
||||
|
||||
def test_dep_include(wrapper_environment):
|
||||
"""Ensure a single dependency include directory is added."""
|
||||
# dep_include
|
||||
with set_env(SPACK_INCLUDE_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@@ -497,29 +403,9 @@ def test_dep_include(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_system_path_cleanup(wrapper_environment):
|
||||
"""Ensure SPACK_ENV_PATH is removed from PATH, even with trailing /
|
||||
|
||||
The compiler wrapper has to ensure that it is not called nested
|
||||
like it would happen when gcc's collect2 looks in PATH for ld.
|
||||
|
||||
To prevent nested calls, the compiler wrapper removes the elements
|
||||
of SPACK_ENV_PATH from PATH. Autotest's generated testsuite appends
|
||||
a / to each element of PATH when adding AUTOTEST_PATH.
|
||||
Thus, ensure that PATH cleanup works even with trailing /.
|
||||
"""
|
||||
system_path = "/bin:/usr/bin:/usr/local/bin"
|
||||
cc_dir = os.path.dirname(cc.path)
|
||||
with set_env(SPACK_ENV_PATH=cc_dir, SPACK_CC="true"):
|
||||
with set_env(PATH=cc_dir + ":" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
with set_env(PATH=cc_dir + "/:" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
|
||||
|
||||
def test_dep_lib(wrapper_environment):
|
||||
"""Ensure a single dependency RPATH is added."""
|
||||
# dep_lib
|
||||
#
|
||||
# Ensure a single dependency RPATH is added
|
||||
with set_env(SPACK_LINK_DIRS="x", SPACK_RPATH_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@@ -535,9 +421,9 @@ def test_dep_lib(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_dep_lib_no_rpath(wrapper_environment):
|
||||
"""Ensure a single dependency link flag is added with no dep RPATH."""
|
||||
# dep_lib_no_rpath
|
||||
#
|
||||
# Ensure a single dependency link flag is added with no dep RPATH
|
||||
with set_env(SPACK_LINK_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@@ -552,9 +438,8 @@ def test_dep_lib_no_rpath(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_dep_lib_no_lib(wrapper_environment):
|
||||
"""Ensure a single dependency RPATH is added with no -L."""
|
||||
# dep_lib_no_lib
|
||||
# Ensure a single dependency RPATH is added with no -L
|
||||
with set_env(SPACK_RPATH_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@@ -569,9 +454,8 @@ def test_dep_lib_no_lib(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_deps(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode."""
|
||||
# ccld_deps
|
||||
# Ensure all flags are added in ccld mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@@ -592,13 +476,13 @@ def test_ccld_deps(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_deps_isystem(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode.
|
||||
When a build uses -isystem, Spack should inject it's
|
||||
include paths using -isystem. Spack will insert these
|
||||
after any provided -isystem includes, but before any
|
||||
system directories included using -isystem"""
|
||||
# ccld_deps_isystem
|
||||
#
|
||||
# Ensure all flags are added in ccld mode.
|
||||
# When a build uses -isystem, Spack should inject it's
|
||||
# include paths using -isystem. Spack will insert these
|
||||
# after any provided -isystem includes, but before any
|
||||
# system directories included using -isystem
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@@ -620,9 +504,8 @@ def test_ccld_deps_isystem(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_cc_deps(wrapper_environment):
|
||||
"""Ensure -L and RPATHs are not added in cc mode."""
|
||||
# cc_deps
|
||||
# Ensure -L and RPATHs are not added in cc mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@@ -640,9 +523,8 @@ def test_cc_deps(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_with_system_dirs(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode."""
|
||||
# ccld_with_system_dirs
|
||||
# Ensure all flags are added in ccld mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@@ -673,12 +555,11 @@ def test_ccld_with_system_dirs(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_with_system_dirs_isystem(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode.
|
||||
Ensure that includes are in the proper
|
||||
place when a build uses -isystem, and uses
|
||||
system directories in the include paths"""
|
||||
# ccld_with_system_dirs_isystem
|
||||
# Ensure all flags are added in ccld mode.
|
||||
# Ensure that includes are in the proper
|
||||
# place when a build uses -isystem, and uses
|
||||
# system directories in the include paths
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@@ -711,9 +592,8 @@ def test_ccld_with_system_dirs_isystem(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps(wrapper_environment):
|
||||
"""Ensure no (extra) -I args or -Wl, are passed in ld mode."""
|
||||
# ld_deps
|
||||
# Ensure no (extra) -I args or -Wl, are passed in ld mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@@ -732,9 +612,8 @@ def test_ld_deps(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps_no_rpath(wrapper_environment):
|
||||
"""Ensure SPACK_LINK_DEPS controls -L for ld."""
|
||||
# ld_deps_no_rpath
|
||||
# Ensure SPACK_LINK_DEPS controls -L for ld
|
||||
with set_env(SPACK_INCLUDE_DIRS="xinc:yinc:zinc", SPACK_LINK_DIRS="xlib:ylib:zlib"):
|
||||
check_args(
|
||||
ld,
|
||||
@@ -748,9 +627,8 @@ def test_ld_deps_no_rpath(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps_no_link(wrapper_environment):
|
||||
"""Ensure SPACK_RPATH_DEPS controls -rpath for ld."""
|
||||
# ld_deps_no_link
|
||||
# Ensure SPACK_RPATH_DEPS controls -rpath for ld
|
||||
with set_env(SPACK_INCLUDE_DIRS="xinc:yinc:zinc", SPACK_RPATH_DIRS="xlib:ylib:zlib"):
|
||||
check_args(
|
||||
ld,
|
||||
@@ -765,10 +643,124 @@ def test_ld_deps_no_link(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps_partial(wrapper_environment):
|
||||
def test_expected_args_with_flags(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
cxx = wrapper_dir / "c++"
|
||||
cpp = wrapper_dir / "cpp"
|
||||
fc = wrapper_dir / "fc"
|
||||
ld = wrapper_dir / "ld"
|
||||
|
||||
# ld_flags
|
||||
check_args(
|
||||
ld,
|
||||
test_args,
|
||||
["ld"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ ["--disable-new-dtags"]
|
||||
+ test_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# cpp_flags
|
||||
check_args(
|
||||
cpp,
|
||||
test_args,
|
||||
["cpp"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags,
|
||||
)
|
||||
|
||||
# cc_flags
|
||||
check_args(
|
||||
cc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ spack_cflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# cxx_flags
|
||||
check_args(
|
||||
cxx,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# fc_flags
|
||||
check_args(
|
||||
fc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args_fc
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_fflags
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# always_cflags
|
||||
with set_env(SPACK_ALWAYS_CFLAGS="-always1 -always2"):
|
||||
check_args(
|
||||
cc,
|
||||
["-v", "--cmd-line-v-opt"],
|
||||
[real_cc] + ["-always1", "-always2"] + ["-v", "--cmd-line-v-opt"],
|
||||
)
|
||||
|
||||
|
||||
def test_system_path_cleanup(wrapper_environment, wrapper_dir):
|
||||
"""Ensure SPACK_ENV_PATH is removed from PATH, even with trailing /
|
||||
|
||||
The compiler wrapper has to ensure that it is not called nested
|
||||
like it would happen when gcc's collect2 looks in PATH for ld.
|
||||
|
||||
To prevent nested calls, the compiler wrapper removes the elements
|
||||
of SPACK_ENV_PATH from PATH. Autotest's generated testsuite appends
|
||||
a / to each element of PATH when adding AUTOTEST_PATH.
|
||||
Thus, ensure that PATH cleanup works even with trailing /.
|
||||
"""
|
||||
cc = wrapper_dir / "cc"
|
||||
system_path = "/bin:/usr/bin:/usr/local/bin"
|
||||
with set_env(SPACK_ENV_PATH=str(wrapper_dir), SPACK_CC="true"):
|
||||
with set_env(PATH=str(wrapper_dir) + ":" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
with set_env(PATH=str(wrapper_dir) + "/:" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
|
||||
|
||||
def test_ld_deps_partial(wrapper_environment, wrapper_dir):
|
||||
"""Make sure ld -r (partial link) is handled correctly on OS's where it
|
||||
doesn't accept rpaths.
|
||||
"""
|
||||
ld = wrapper_dir / "ld"
|
||||
with set_env(SPACK_INCLUDE_DIRS="xinc", SPACK_RPATH_DIRS="xlib", SPACK_LINK_DIRS="xlib"):
|
||||
# TODO: do we need to add RPATHs on other platforms like Linux?
|
||||
# TODO: Can't we treat them the same?
|
||||
@@ -805,7 +797,8 @@ def test_ld_deps_partial(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_ccache_prepend_for_cc(wrapper_environment):
|
||||
def test_ccache_prepend_for_cc(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
with set_env(SPACK_CCACHE_BINARY="ccache"):
|
||||
os.environ["SPACK_SHORT_SPEC"] = "foo@1.2=linux-x86_64"
|
||||
check_args(
|
||||
@@ -828,7 +821,8 @@ def test_ccache_prepend_for_cc(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_no_ccache_prepend_for_fc(wrapper_environment):
|
||||
def test_no_ccache_prepend_for_fc(wrapper_environment, wrapper_dir):
|
||||
fc = wrapper_dir / "fc"
|
||||
os.environ["SPACK_SHORT_SPEC"] = "foo@1.2=linux-x86_64"
|
||||
check_args(
|
||||
fc,
|
||||
@@ -845,7 +839,8 @@ def test_no_ccache_prepend_for_fc(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_keep_and_replace(wrapper_environment):
|
||||
def test_keep_and_replace(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
werror_specific = ["-Werror=meh"]
|
||||
werror = ["-Werror"]
|
||||
werror_all = werror_specific + werror
|
||||
@@ -906,7 +901,8 @@ def test_keep_and_replace(wrapper_environment):
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("wrapper_environment", "mutable_config")
|
||||
def test_flag_modification(cfg_override, initial, expected, must_be_gone):
|
||||
def test_flag_modification(cfg_override, initial, expected, must_be_gone, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
spack.config.add(cfg_override)
|
||||
env = spack.build_environment.clean_environment()
|
||||
|
||||
@@ -917,7 +913,9 @@ def test_flag_modification(cfg_override, initial, expected, must_be_gone):
|
||||
|
||||
|
||||
@pytest.mark.regression("9160")
|
||||
def test_disable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
def test_disable_new_dtags(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
ld = Executable(str(wrapper_dir / "ld"))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
result = ld(*test_args, output=str).strip().split("\n")
|
||||
assert "--disable-new-dtags" in result
|
||||
@@ -926,7 +924,9 @@ def test_disable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
|
||||
|
||||
@pytest.mark.regression("9160")
|
||||
def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
ld = Executable(str(wrapper_dir / "ld"))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
result = ld(*(test_args + ["--enable-new-dtags"]), output=str)
|
||||
result = result.strip().split("\n")
|
||||
@@ -938,7 +938,9 @@ def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
|
||||
|
||||
@pytest.mark.regression("22643")
|
||||
def test_linker_strips_loopopt(wrapper_environment, wrapper_flags):
|
||||
def test_linker_strips_loopopt(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
ld = Executable(str(wrapper_dir / "ld"))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
# ensure that -loopopt=0 is not present in ld mode
|
||||
result = ld(*(test_args + ["-loopopt=0"]), output=str)
|
||||
@@ -958,7 +960,9 @@ def test_linker_strips_loopopt(wrapper_environment, wrapper_flags):
|
||||
assert "-loopopt=0" in result
|
||||
|
||||
|
||||
def test_spack_managed_dirs_are_prioritized(wrapper_environment):
|
||||
def test_spack_managed_dirs_are_prioritized(wrapper_environment, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
|
||||
# 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"
|
||||
|
@@ -344,10 +344,20 @@ def test_get_spec_filter_list(mutable_mock_env_path, mutable_mock_repo):
|
||||
"libelf",
|
||||
"gcc",
|
||||
"gcc-runtime",
|
||||
"compiler-wrapper",
|
||||
}
|
||||
depth_2_set = {"mpich", "callpath", "dyninst", "libdwarf", "libelf", "gcc", "gcc-runtime"}
|
||||
depth_1_set = {"dyninst", "libdwarf", "libelf", "gcc", "gcc-runtime"}
|
||||
depth_0_set = {"libdwarf", "libelf", "gcc", "gcc-runtime"}
|
||||
depth_2_set = {
|
||||
"mpich",
|
||||
"callpath",
|
||||
"dyninst",
|
||||
"libdwarf",
|
||||
"libelf",
|
||||
"gcc",
|
||||
"gcc-runtime",
|
||||
"compiler-wrapper",
|
||||
}
|
||||
depth_1_set = {"dyninst", "libdwarf", "libelf", "gcc", "gcc-runtime", "compiler-wrapper"}
|
||||
depth_0_set = {"libdwarf", "libelf", "gcc", "gcc-runtime", "compiler-wrapper"}
|
||||
|
||||
expectations = {
|
||||
None: full_set,
|
||||
|
@@ -223,7 +223,7 @@ def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
||||
for dep in ("mpileaks", "callpath", "dyninst", "libelf", "libdwarf", "mpich")
|
||||
)
|
||||
assert all(
|
||||
len([diff for diff in result["intersect"] if diff[0] == attr]) == 7
|
||||
len([diff for diff in result["intersect"] if diff[0] == attr]) == 8
|
||||
for attr in (
|
||||
"version",
|
||||
"node_target",
|
||||
|
@@ -170,7 +170,7 @@ def _check_json_output(spec_list):
|
||||
|
||||
|
||||
def _check_json_output_deps(spec_list):
|
||||
assert len(spec_list) == 15
|
||||
assert len(spec_list) == 16
|
||||
|
||||
names = [spec["name"] for spec in spec_list]
|
||||
assert names.count("mpileaks") == 3
|
||||
@@ -272,6 +272,7 @@ def test_find_format_deps(database, config):
|
||||
dyninst-8.2
|
||||
libdwarf-20130729
|
||||
libelf-0.8.13
|
||||
compiler-wrapper-1.0
|
||||
gcc-10.2.1
|
||||
gcc-runtime-10.2.1
|
||||
zmpi-1.0
|
||||
@@ -293,6 +294,7 @@ def test_find_format_deps_paths(database, config):
|
||||
dyninst-8.2 {mpileaks['dyninst'].prefix}
|
||||
libdwarf-20130729 {mpileaks['libdwarf'].prefix}
|
||||
libelf-0.8.13 {mpileaks['libelf'].prefix}
|
||||
compiler-wrapper-1.0 {mpileaks['compiler-wrapper'].prefix}
|
||||
gcc-10.2.1 {mpileaks['gcc'].prefix}
|
||||
gcc-runtime-10.2.1 {mpileaks['gcc-runtime'].prefix}
|
||||
zmpi-1.0 {mpileaks['zmpi'].prefix}
|
||||
|
@@ -61,7 +61,7 @@ def test_install_package_and_dependency(
|
||||
assert filename in files
|
||||
|
||||
content = filename.open().read()
|
||||
assert 'tests="3"' in content
|
||||
assert 'tests="4"' in content
|
||||
assert 'failures="0"' in content
|
||||
assert 'errors="0"' in content
|
||||
|
||||
@@ -106,12 +106,12 @@ def test_install_package_already_installed(
|
||||
|
||||
content = filename.open().read()
|
||||
print(content)
|
||||
assert 'tests="4"' in content
|
||||
assert 'tests="5"' in content
|
||||
assert 'failures="0"' in content
|
||||
assert 'errors="0"' in content
|
||||
|
||||
skipped = [line for line in content.split("\n") if "skipped" in line]
|
||||
assert len(skipped) == 4
|
||||
assert len(skipped) == 5
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -448,16 +448,16 @@ def just_throw(*args, **kwargs):
|
||||
|
||||
# Only libelf error is reported (through libdwarf root spec). libdwarf
|
||||
# install is skipped and it is not an error.
|
||||
assert 'tests="1"' in content
|
||||
assert 'tests="0"' not in content
|
||||
assert 'failures="0"' in content
|
||||
assert 'errors="1"' in content
|
||||
assert 'errors="0"' not in content
|
||||
|
||||
# Nothing should have succeeded
|
||||
assert 'errors="0"' not in content
|
||||
|
||||
# We want to have both stdout and stderr
|
||||
assert "<system-out>" in content
|
||||
assert 'error message="{0}"'.format(msg) in content
|
||||
assert f'error message="{msg}"' in content
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("noop_install", "mock_packages", "config")
|
||||
|
@@ -30,7 +30,7 @@ def test_mark_all_explicit(mutable_database):
|
||||
mark("-e", "-a")
|
||||
gc("-y")
|
||||
all_specs = spack.store.STORE.layout.all_specs()
|
||||
assert len(all_specs) == 16
|
||||
assert len(all_specs) == 17
|
||||
|
||||
|
||||
@pytest.mark.db
|
||||
@@ -64,4 +64,4 @@ def test_mark_all_implicit_then_explicit(mutable_database):
|
||||
mark("-e", "-a")
|
||||
gc("-y")
|
||||
all_specs = spack.store.STORE.layout.all_specs()
|
||||
assert len(all_specs) == 16
|
||||
assert len(all_specs) == 17
|
||||
|
@@ -90,7 +90,7 @@ def test_recursive_uninstall(mutable_database):
|
||||
|
||||
@pytest.mark.db
|
||||
@pytest.mark.regression("3690")
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 9), ("libelf", 7)])
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 10), ("libelf", 8)])
|
||||
def test_uninstall_spec_with_multiple_roots(
|
||||
constraint, expected_number_of_specs, mutable_database
|
||||
):
|
||||
@@ -100,7 +100,7 @@ def test_uninstall_spec_with_multiple_roots(
|
||||
|
||||
|
||||
@pytest.mark.db
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 15), ("libelf", 15)])
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 16), ("libelf", 16)])
|
||||
def test_force_uninstall_spec_with_ref_count_not_zero(
|
||||
constraint, expected_number_of_specs, mutable_database
|
||||
):
|
||||
@@ -170,7 +170,7 @@ def db_specs():
|
||||
|
||||
all_specs, mpileaks_specs, callpath_specs, mpi_specs = db_specs()
|
||||
total_specs = len(all_specs)
|
||||
assert total_specs == 15
|
||||
assert total_specs == 16
|
||||
assert len(mpileaks_specs) == 3
|
||||
assert len(callpath_specs) == 2
|
||||
assert len(mpi_specs) == 3
|
||||
|
@@ -466,7 +466,7 @@ def test_architecture_deep_inheritance(self, mock_targets, compiler_factory):
|
||||
with spack.config.override("packages", {"gcc": {"externals": [cnl_compiler]}}):
|
||||
spec_str = "mpileaks %gcc@4.5.0 os=CNL target=nocona ^dyninst os=CNL ^callpath os=CNL"
|
||||
spec = spack.concretize.concretize_one(spec_str)
|
||||
for s in spec.traverse(root=False):
|
||||
for s in spec.traverse(root=False, deptype=("link", "run")):
|
||||
assert s.architecture.target == spec.architecture.target
|
||||
|
||||
def test_compiler_flags_from_user_are_grouped(self):
|
||||
@@ -1991,17 +1991,17 @@ def test_installed_specs_disregard_conflicts(self, mutable_database, monkeypatch
|
||||
assert s.satisfies("~debug"), s
|
||||
|
||||
@pytest.mark.regression("32471")
|
||||
def test_require_targets_are_allowed(self, mutable_database):
|
||||
def test_require_targets_are_allowed(self, mutable_config, mutable_database):
|
||||
"""Test that users can set target constraints under the require attribute."""
|
||||
# Configuration to be added to packages.yaml
|
||||
required_target = archspec.cpu.TARGETS[spack.platforms.test.Test.default].family
|
||||
external_conf = {"all": {"require": f"target={required_target}"}}
|
||||
spack.config.set("packages", external_conf)
|
||||
mutable_config.set("packages", external_conf)
|
||||
|
||||
with spack.config.override("concretizer:reuse", False):
|
||||
spec = spack.concretize.concretize_one("mpich")
|
||||
|
||||
for s in spec.traverse():
|
||||
for s in spec.traverse(deptype=("link", "run")):
|
||||
assert s.satisfies(f"target={required_target}")
|
||||
|
||||
def test_external_python_extensions_have_dependency(self):
|
||||
@@ -2994,7 +2994,7 @@ def test_filtering_reused_specs(
|
||||
@pytest.mark.usefixtures("mutable_database", "mock_store")
|
||||
@pytest.mark.parametrize(
|
||||
"reuse_yaml,expected_length",
|
||||
[({"from": [{"type": "local"}]}, 19), ({"from": [{"type": "buildcache"}]}, 0)],
|
||||
[({"from": [{"type": "local"}]}, 20), ({"from": [{"type": "buildcache"}]}, 0)],
|
||||
)
|
||||
@pytest.mark.not_on_windows("Expected length is different on Windows")
|
||||
def test_selecting_reused_sources(
|
||||
|
@@ -2154,3 +2154,12 @@ def info(self):
|
||||
@pytest.fixture()
|
||||
def mock_runtimes(config, mock_packages):
|
||||
return mock_packages.packages_with_tags("runtime")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def wrapper_dir(install_mockery):
|
||||
"""Installs the compiler wrapper and returns the prefix where the script is installed."""
|
||||
wrapper = spack.spec.Spec("compiler-wrapper").concretized()
|
||||
wrapper_pkg = wrapper.package
|
||||
PackageInstaller([wrapper_pkg], explicit=True).install()
|
||||
return wrapper_pkg.bin_dir()
|
||||
|
@@ -95,11 +95,11 @@ def upstream_and_downstream_db(tmpdir, gen_mock_layout):
|
||||
@pytest.mark.parametrize(
|
||||
"install_tree,result",
|
||||
[
|
||||
("all", ["pkg-b", "pkg-c", "gcc-runtime", "gcc"]),
|
||||
("all", ["pkg-b", "pkg-c", "gcc-runtime", "gcc", "compiler-wrapper"]),
|
||||
("upstream", ["pkg-c"]),
|
||||
("local", ["pkg-b", "gcc-runtime", "gcc"]),
|
||||
("local", ["pkg-b", "gcc-runtime", "gcc", "compiler-wrapper"]),
|
||||
("{u}", ["pkg-c"]),
|
||||
("{d}", ["pkg-b", "gcc-runtime", "gcc"]),
|
||||
("{d}", ["pkg-b", "gcc-runtime", "gcc", "compiler-wrapper"]),
|
||||
],
|
||||
ids=["all", "upstream", "local", "upstream_path", "downstream_path"],
|
||||
)
|
||||
@@ -491,7 +491,7 @@ def test_005_db_exists(database):
|
||||
def test_010_all_install_sanity(database):
|
||||
"""Ensure that the install layout reflects what we think it does."""
|
||||
all_specs = spack.store.STORE.layout.all_specs()
|
||||
assert len(all_specs) == 16
|
||||
assert len(all_specs) == 17
|
||||
|
||||
# Query specs with multiple configurations
|
||||
mpileaks_specs = [s for s in all_specs if s.satisfies("mpileaks")]
|
||||
@@ -608,7 +608,7 @@ def test_050_basic_query(database):
|
||||
"""Ensure querying database is consistent with what is installed."""
|
||||
# query everything
|
||||
total_specs = len(spack.store.STORE.db.query())
|
||||
assert total_specs == 19
|
||||
assert total_specs == 20
|
||||
|
||||
# query specs with multiple configurations
|
||||
mpileaks_specs = database.query("mpileaks")
|
||||
@@ -827,11 +827,11 @@ def check_unused(roots, deptype, expected):
|
||||
assert set(u.name for u in unused) == set(expected)
|
||||
|
||||
default_dt = dt.LINK | dt.RUN
|
||||
check_unused(None, default_dt, ["cmake", "gcc"])
|
||||
check_unused(None, default_dt, ["cmake", "gcc", "compiler-wrapper"])
|
||||
check_unused(
|
||||
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
||||
default_dt,
|
||||
["trivial-smoke-test", "cmake", "gcc"],
|
||||
["trivial-smoke-test", "cmake", "gcc", "compiler-wrapper"],
|
||||
)
|
||||
check_unused(
|
||||
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
||||
@@ -846,7 +846,15 @@ def check_unused(roots, deptype, expected):
|
||||
check_unused(
|
||||
[si, ml_mpich, ml_mpich2, ml_zmpi],
|
||||
default_dt,
|
||||
["trivial-smoke-test", "cmake", "externaltest", "externaltool", "externalvirtual", "gcc"],
|
||||
[
|
||||
"trivial-smoke-test",
|
||||
"cmake",
|
||||
"externaltest",
|
||||
"externaltool",
|
||||
"externalvirtual",
|
||||
"gcc",
|
||||
"compiler-wrapper",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1080,7 +1088,7 @@ def test_check_parents(spec_str, parent_name, expected_nparents, database):
|
||||
def test_db_all_hashes(database):
|
||||
# ensure we get the right number of hashes without a read transaction
|
||||
hashes = database.all_hashes()
|
||||
assert len(hashes) == 19
|
||||
assert len(hashes) == 20
|
||||
|
||||
# and make sure the hashes match
|
||||
with database.read_transaction():
|
||||
|
@@ -54,25 +54,34 @@ def test_ascii_graph_mpileaks(config, mock_packages, monkeypatch):
|
||||
|\
|
||||
| |\
|
||||
| | |\
|
||||
| | | o callpath
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/|
|
||||
o | | | mpich
|
||||
|\| | |
|
||||
| |/ /
|
||||
|/| |
|
||||
| | o dyninst
|
||||
| |/|
|
||||
|/|/|
|
||||
| | |\
|
||||
| | | o libdwarf
|
||||
| | | |\
|
||||
| | | | o callpath
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/|
|
||||
| | | | o dyninst
|
||||
| | |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/|
|
||||
| | | | |\
|
||||
o | | | | | mpich
|
||||
|\| | | | |
|
||||
|\ \ \ \ \ \
|
||||
| |_|/ / / /
|
||||
|/| | | | |
|
||||
| |/ / / /
|
||||
| | | | o libdwarf
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/
|
||||
| | | o libelf
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/
|
||||
| | o libelf
|
||||
| |/|
|
||||
|/|/
|
||||
| o | compiler-wrapper
|
||||
| /
|
||||
| o gcc-runtime
|
||||
|/
|
||||
o gcc
|
||||
|
@@ -1022,7 +1022,7 @@ def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
|
||||
b, c = spack.concretize.concretize_one("pkg-b"), spack.concretize.concretize_one("pkg-c")
|
||||
b_id, c_id = inst.package_id(b), inst.package_id(c)
|
||||
|
||||
installer = create_installer([b, c], {"fail_fast": True})
|
||||
installer = create_installer([c, b], {"fail_fast": True})
|
||||
|
||||
# Make sure all packages are identified as failed
|
||||
# This will prevent b from installing, which will cause the build of c to be skipped.
|
||||
@@ -1031,7 +1031,7 @@ def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
|
||||
with pytest.raises(spack.error.InstallError, match="after first install failure"):
|
||||
installer.install()
|
||||
|
||||
assert c_id in installer.failed, "Expected b to be marked as failed"
|
||||
assert c_id in installer.failed
|
||||
assert b_id not in installer.failed, "Expected no attempt to install pkg-c"
|
||||
assert f"{c_id} failed to install" in capsys.readouterr().err
|
||||
|
||||
|
@@ -15,12 +15,15 @@
|
||||
|
||||
import pytest
|
||||
|
||||
import spack
|
||||
import spack.binary_distribution
|
||||
import spack.database
|
||||
import spack.deptypes as dt
|
||||
import spack.environment as ev
|
||||
import spack.error
|
||||
import spack.oci.opener
|
||||
import spack.spec
|
||||
import spack.traverse
|
||||
from spack.main import SpackCommand
|
||||
from spack.oci.image import Digest, ImageReference, default_config, default_manifest
|
||||
from spack.oci.oci import blob_exists, get_manifest_and_config, upload_blob, upload_manifest
|
||||
@@ -82,7 +85,13 @@ def test_buildcache_tag(install_mockery, mock_fetch, mutable_mock_env_path):
|
||||
name = ImageReference.from_string("example.com/image:full_env")
|
||||
|
||||
with ev.read("test") as e:
|
||||
specs = [x for x in e.all_specs() if not x.external]
|
||||
specs = [
|
||||
x
|
||||
for x in spack.traverse.traverse_nodes(
|
||||
e.concrete_roots(), deptype=dt.LINK | dt.RUN
|
||||
)
|
||||
if not x.external
|
||||
]
|
||||
|
||||
manifest, config = get_manifest_and_config(name)
|
||||
|
||||
@@ -99,7 +108,9 @@ def test_buildcache_tag(install_mockery, mock_fetch, mutable_mock_env_path):
|
||||
|
||||
name = ImageReference.from_string("example.com/image:single_spec")
|
||||
manifest, config = get_manifest_and_config(name)
|
||||
assert len(manifest["layers"]) == len([x for x in libelf.traverse() if not x.external])
|
||||
assert len(manifest["layers"]) == len(
|
||||
[x for x in libelf.traverse(deptype=dt.LINK | dt.RUN) if not x.external]
|
||||
)
|
||||
|
||||
|
||||
def test_buildcache_push_with_base_image_command(mutable_database, tmpdir):
|
||||
|
@@ -184,6 +184,7 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
[
|
||||
(0, "mpileaks"),
|
||||
(1, "callpath"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "dyninst"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
@@ -199,23 +200,29 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
[
|
||||
(0, "mpileaks"),
|
||||
(1, "callpath"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "dyninst"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "gcc"),
|
||||
(3, "libdwarf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(3, "libelf"),
|
||||
(2, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
(2, "zmpi"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(1, "zmpi"),
|
||||
@@ -227,19 +234,24 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
[
|
||||
(0, "mpileaks"),
|
||||
(1, "callpath"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "dyninst"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "gcc"),
|
||||
(3, "libdwarf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "gcc"),
|
||||
(4, "libelf"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(6, "gcc"),
|
||||
(3, "libelf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "gcc"),
|
||||
@@ -247,14 +259,17 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
(2, "gcc-runtime"),
|
||||
(3, "gcc"),
|
||||
(2, "zmpi"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "gcc"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(2, "gcc"),
|
||||
(1, "zmpi"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "fake"),
|
||||
(2, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
@@ -265,6 +280,7 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
# Postorder node traversal
|
||||
(
|
||||
[
|
||||
(2, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
@@ -280,11 +296,15 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
# Postorder edge traversal
|
||||
(
|
||||
[
|
||||
(2, "compiler-wrapper"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(4, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
@@ -293,11 +313,13 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
(2, "dyninst"),
|
||||
(2, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(2, "zmpi"),
|
||||
(1, "callpath"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(1, "zmpi"),
|
||||
@@ -308,17 +330,22 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
# Postorder path traversal
|
||||
(
|
||||
[
|
||||
(2, "compiler-wrapper"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(4, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(5, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(6, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
(3, "libdwarf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(5, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
@@ -327,15 +354,18 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
(2, "gcc"),
|
||||
(3, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(4, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(2, "zmpi"),
|
||||
(1, "callpath"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(2, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "fake"),
|
||||
(2, "gcc"),
|
||||
(3, "gcc"),
|
||||
@@ -350,47 +380,53 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
def test_traversal(self, pairs, traverse_kwargs, default_mock_concretization):
|
||||
r"""Tests different traversals of the following graph
|
||||
|
||||
o mpileaks
|
||||
o mpileaks@2.3/3qeg7jx
|
||||
|\
|
||||
| |\
|
||||
| | |\
|
||||
| | | |\
|
||||
| | | | o callpath
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/|
|
||||
o | | | | zmpi
|
||||
|\| | | |
|
||||
|\ \ \ \ \
|
||||
| |_|/ / /
|
||||
|/| | | |
|
||||
| |\ \ \ \
|
||||
| | |_|/ /
|
||||
| |/| | |
|
||||
| | o | | fake
|
||||
| | / /
|
||||
| | | o dyninst
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/|
|
||||
| | | |\
|
||||
| | | | o libdwarf
|
||||
| | | | |\
|
||||
| | | | | o callpath@1.0/4gilijr
|
||||
| |_|_|_|/|
|
||||
|/| |_|_|/|
|
||||
| |/| |_|/|
|
||||
| | |/| |/|
|
||||
| | | |/|/|
|
||||
| | | | | o dyninst@8.2/u4oymb3
|
||||
| | |_|_|/|
|
||||
| |/| |_|/|
|
||||
| | |/| |/|
|
||||
| | | |/|/|
|
||||
| | | | | |\
|
||||
o | | | | | | mpich@3.0.4/g734fu6
|
||||
|\| | | | | |
|
||||
|\ \ \ \ \ \ \
|
||||
| |_|/ / / / /
|
||||
|/| | | | | |
|
||||
| |\ \ \ \ \ \
|
||||
| | |_|/ / / /
|
||||
| |/| | | | |
|
||||
| | |/ / / /
|
||||
| | | | | o libdwarf@20130729/q5r7l2r
|
||||
| |_|_|_|/|
|
||||
|/| |_|_|/|
|
||||
| |/| |_|/|
|
||||
| | |/| |/|
|
||||
| | | |/|/
|
||||
| | | | o libelf@0.8.13/i2x6pya
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/
|
||||
| | | o libel
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/
|
||||
o | | gcc-runtime
|
||||
| | o | compiler-wrapper@1.0/njdili2
|
||||
| | /
|
||||
o | | gcc-runtime@10.5.0/iyytqeo
|
||||
|\| |
|
||||
| |/
|
||||
|/|
|
||||
o | glibc
|
||||
/
|
||||
o gcc
|
||||
| o gcc@10.5.0/ljeisd4
|
||||
|
|
||||
o glibc@2.31/tbyn33w
|
||||
"""
|
||||
dag = default_mock_concretization("mpileaks ^zmpi")
|
||||
names = [x for _, x in pairs]
|
||||
@@ -843,10 +879,10 @@ def test_spec_tree_respect_deptypes(self):
|
||||
"query,expected_length,expected_satisfies",
|
||||
[
|
||||
({"virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
||||
({"depflag": dt.BUILD}, 3, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD}, 4, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD, "virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
||||
({"depflag": dt.LINK}, 3, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD | dt.LINK}, 4, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD | dt.LINK}, 5, ["mpich", "mpi", "callpath"]),
|
||||
({"virtuals": ["lapack"]}, 0, []),
|
||||
],
|
||||
)
|
||||
@@ -928,7 +964,7 @@ def test_synthetic_construction_of_split_dependencies_from_same_package(mock_pac
|
||||
root.add_dependency_edge(build_spec, depflag=dt.BUILD, virtuals=())
|
||||
|
||||
# Check dependencies from the perspective of root
|
||||
assert len(root.dependencies()) == 4
|
||||
assert len(root.dependencies()) == 5
|
||||
assert len([x for x in root.dependencies() if x.name == "pkg-c"]) == 2
|
||||
|
||||
assert "@2.0" in root.dependencies(name="pkg-c", deptype=dt.BUILD)[0]
|
||||
|
@@ -1697,6 +1697,7 @@ def test_spec_trim(mock_packages, config):
|
||||
top.trim("dt-diamond-left")
|
||||
remaining = {x.name for x in top.traverse()}
|
||||
assert {
|
||||
"compiler-wrapper",
|
||||
"dt-diamond",
|
||||
"dt-diamond-right",
|
||||
"dt-diamond-bottom",
|
||||
@@ -1706,7 +1707,7 @@ def test_spec_trim(mock_packages, config):
|
||||
|
||||
top.trim("dt-diamond-right")
|
||||
remaining = {x.name for x in top.traverse()}
|
||||
assert {"dt-diamond", "gcc-runtime", "gcc"} == remaining
|
||||
assert {"compiler-wrapper", "dt-diamond", "gcc-runtime", "gcc"} == remaining
|
||||
|
||||
|
||||
@pytest.mark.regression("30861")
|
||||
|
Reference in New Issue
Block a user