summaryrefslogtreecommitdiff
path: root/lib/spack/env/cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/env/cc')
-rwxr-xr-xlib/spack/env/cc377
1 files changed, 216 insertions, 161 deletions
diff --git a/lib/spack/env/cc b/lib/spack/env/cc
index f72a6663a3..88969d3f30 100755
--- a/lib/spack/env/cc
+++ b/lib/spack/env/cc
@@ -47,7 +47,8 @@ SPACK_F77_RPATH_ARG
SPACK_FC_RPATH_ARG
SPACK_LINKER_ARG
SPACK_SHORT_SPEC
-SPACK_SYSTEM_DIRS"
+SPACK_SYSTEM_DIRS
+SPACK_MANAGED_DIRS"
# Optional parameters that aren't required to be set
@@ -100,10 +101,9 @@ setsep() {
esac
}
-# prepend LISTNAME ELEMENT [SEP]
+# prepend LISTNAME ELEMENT
#
-# Prepend ELEMENT to the list stored in the variable LISTNAME,
-# assuming the list is separated by SEP.
+# Prepend ELEMENT to the list stored in the variable LISTNAME.
# Handles empty lists and single-element lists.
prepend() {
varname="$1"
@@ -173,20 +173,44 @@ preextend() {
unset IFS
}
-# system_dir PATH
-# test whether a path is a system directory
-system_dir() {
- IFS=':' # SPACK_SYSTEM_DIRS is colon-separated
- path="$1"
- for sd in $SPACK_SYSTEM_DIRS; do
- if [ "${path}" = "${sd}" ] || [ "${path}" = "${sd}/" ]; then
- # success if path starts with a system prefix
- unset IFS
- return 0
- fi
- done
- unset IFS
- return 1 # fail if path starts no system prefix
+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.
@@ -201,6 +225,48 @@ for param in $params; do
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
@@ -234,12 +300,17 @@ fi
# 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"
@@ -247,13 +318,15 @@ case "$command" in
comp="CC"
lang_flags=C
debug_flags="-g"
+ vcheck_flags="${SPACK_ALWAYS_CFLAGS}"
;;
- c++|CC|g++|clang++|armclang++|icpc|icpx|dpcpp|pgc++|nvc++|xlc++|xlc++_r|FCC|amdclang++|crayCC)
+ 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"
@@ -261,6 +334,7 @@ case "$command" in
comp="FC"
lang_flags=F
debug_flags="-g"
+ vcheck_flags="${SPACK_ALWAYS_FFLAGS}"
;;
f77|xlf|xlf_r|pgf77)
command="$SPACK_F77"
@@ -268,6 +342,7 @@ case "$command" in
comp="F77"
lang_flags=F
debug_flags="-g"
+ vcheck_flags="${SPACK_ALWAYS_FFLAGS}"
;;
ld|ld.gold|ld.lld)
mode=ld
@@ -368,7 +443,11 @@ unset IFS
export PATH="$new_dirs"
if [ "$mode" = vcheck ]; then
- exec "${command}" "$@"
+ 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.
@@ -420,11 +499,7 @@ input_command="$*"
parse_Wl() {
while [ $# -ne 0 ]; do
if [ "$wl_expect_rpath" = yes ]; then
- if system_dir "$1"; then
- append return_system_rpath_dirs_list "$1"
- else
- append return_rpath_dirs_list "$1"
- fi
+ append_path_lists return_rpath_dirs_list "$1"
wl_expect_rpath=no
else
case "$1" in
@@ -432,21 +507,15 @@ parse_Wl() {
arg="${1#-rpath=}"
if [ -z "$arg" ]; then
shift; continue
- elif system_dir "$arg"; then
- append return_system_rpath_dirs_list "$arg"
- else
- append return_rpath_dirs_list "$arg"
fi
+ append_path_lists return_rpath_dirs_list "$arg"
;;
--rpath=*)
arg="${1#--rpath=}"
if [ -z "$arg" ]; then
shift; continue
- elif system_dir "$arg"; then
- append return_system_rpath_dirs_list "$arg"
- else
- append return_rpath_dirs_list "$arg"
fi
+ append_path_lists return_rpath_dirs_list "$arg"
;;
-rpath|--rpath)
wl_expect_rpath=yes
@@ -454,8 +523,7 @@ parse_Wl() {
"$dtags_to_strip")
;;
-Wl)
- # Nested -Wl,-Wl means we're in NAG compiler territory, we don't support
- # it.
+ # Nested -Wl,-Wl means we're in NAG compiler territory. We don't support it.
return 1
;;
*)
@@ -473,14 +541,11 @@ categorize_arguments() {
return_other_args_list=""
return_isystem_was_used=""
- return_isystem_system_include_dirs_list=""
- return_isystem_include_dirs_list=""
- return_system_include_dirs_list=""
- return_include_dirs_list=""
- return_system_lib_dirs_list=""
- return_lib_dirs_list=""
- return_system_rpath_dirs_list=""
- return_rpath_dirs_list=""
+
+ 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
@@ -526,7 +591,7 @@ categorize_arguments() {
continue
fi
- replaced="$after$stripped"
+ replaced="$after$stripped"
# it matched, remove it
shift
@@ -546,29 +611,17 @@ categorize_arguments() {
arg="${1#-isystem}"
return_isystem_was_used=true
if [ -z "$arg" ]; then shift; arg="$1"; fi
- if system_dir "$arg"; then
- append return_isystem_system_include_dirs_list "$arg"
- else
- append return_isystem_include_dirs_list "$arg"
- fi
+ append_path_lists return_isystem_include_dirs_list "$arg"
;;
-I*)
arg="${1#-I}"
if [ -z "$arg" ]; then shift; arg="$1"; fi
- if system_dir "$arg"; then
- append return_system_include_dirs_list "$arg"
- else
- append return_include_dirs_list "$arg"
- fi
+ append_path_lists return_include_dirs_list "$arg"
;;
-L*)
arg="${1#-L}"
if [ -z "$arg" ]; then shift; arg="$1"; fi
- if system_dir "$arg"; then
- append return_system_lib_dirs_list "$arg"
- else
- append return_lib_dirs_list "$arg"
- fi
+ append_path_lists return_lib_dirs_list "$arg"
;;
-l*)
# -loopopt=0 is generated erroneously in autoconf <= 2.69,
@@ -601,29 +654,17 @@ categorize_arguments() {
break
elif [ "$xlinker_expect_rpath" = yes ]; then
# Register the path of -Xlinker -rpath <other args> -Xlinker <path>
- if system_dir "$1"; then
- append return_system_rpath_dirs_list "$1"
- else
- append return_rpath_dirs_list "$1"
- fi
+ append_path_lists return_rpath_dirs_list "$1"
xlinker_expect_rpath=no
else
case "$1" in
-rpath=*)
arg="${1#-rpath=}"
- if system_dir "$arg"; then
- append return_system_rpath_dirs_list "$arg"
- else
- append return_rpath_dirs_list "$arg"
- fi
+ append_path_lists return_rpath_dirs_list "$arg"
;;
--rpath=*)
arg="${1#--rpath=}"
- if system_dir "$arg"; then
- append return_system_rpath_dirs_list "$arg"
- else
- append return_rpath_dirs_list "$arg"
- fi
+ append_path_lists return_rpath_dirs_list "$arg"
;;
-rpath|--rpath)
xlinker_expect_rpath=yes
@@ -640,7 +681,36 @@ categorize_arguments() {
"$dtags_to_strip")
;;
*)
- append return_other_args_list "$1"
+ # 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
@@ -661,16 +731,14 @@ categorize_arguments() {
}
categorize_arguments "$@"
- include_dirs_list="$return_include_dirs_list"
- lib_dirs_list="$return_lib_dirs_list"
- rpath_dirs_list="$return_rpath_dirs_list"
- system_include_dirs_list="$return_system_include_dirs_list"
- system_lib_dirs_list="$return_system_lib_dirs_list"
- system_rpath_dirs_list="$return_system_rpath_dirs_list"
- isystem_was_used="$return_isystem_was_used"
- isystem_system_include_dirs_list="$return_isystem_system_include_dirs_list"
- isystem_include_dirs_list="$return_isystem_include_dirs_list"
- other_args_list="$return_other_args_list"
+
+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
@@ -697,6 +765,7 @@ case "$mode" in
cc|ccld)
case $lang_flags in
F)
+ extend spack_flags_list SPACK_ALWAYS_FFLAGS
extend spack_flags_list SPACK_FFLAGS
;;
esac
@@ -706,6 +775,7 @@ 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
@@ -716,9 +786,11 @@ case "$mode" in
cc|ccld)
case $lang_flags in
C)
+ extend spack_flags_list SPACK_ALWAYS_CFLAGS
extend spack_flags_list SPACK_CFLAGS
;;
CXX)
+ extend spack_flags_list SPACK_ALWAYS_CXXFLAGS
extend spack_flags_list SPACK_CXXFLAGS
;;
esac
@@ -730,7 +802,7 @@ esac
# Linker flags
case "$mode" in
- ld|ccld)
+ ccld)
extend spack_flags_list SPACK_LDFLAGS
;;
esac
@@ -738,16 +810,14 @@ esac
IFS="$lsep"
categorize_arguments $spack_flags_list
unset IFS
- spack_flags_include_dirs_list="$return_include_dirs_list"
- spack_flags_lib_dirs_list="$return_lib_dirs_list"
- spack_flags_rpath_dirs_list="$return_rpath_dirs_list"
- spack_flags_system_include_dirs_list="$return_system_include_dirs_list"
- spack_flags_system_lib_dirs_list="$return_system_lib_dirs_list"
- spack_flags_system_rpath_dirs_list="$return_system_rpath_dirs_list"
- spack_flags_isystem_was_used="$return_isystem_was_used"
- spack_flags_isystem_system_include_dirs_list="$return_isystem_system_include_dirs_list"
- spack_flags_isystem_include_dirs_list="$return_isystem_include_dirs_list"
- spack_flags_other_args_list="$return_other_args_list"
+
+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
@@ -767,11 +837,13 @@ if [ "$mode" = ccld ] || [ "$mode" = ld ]; then
# Append RPATH directories. Note that in the case of the
# top-level package these directories may not exist yet. For dependencies
# it is assumed that paths have already been confirmed.
+ extend spack_store_rpath_dirs_list SPACK_STORE_RPATH_DIRS
extend rpath_dirs_list SPACK_RPATH_DIRS
fi
fi
if [ "$mode" = ccld ] || [ "$mode" = ld ]; then
+ extend spack_store_lib_dirs_list SPACK_STORE_LINK_DIRS
extend lib_dirs_list SPACK_LINK_DIRS
fi
@@ -798,63 +870,82 @@ case "$mode" in
;;
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"
-# Insert include directories just prior to any system include directories
+# Include search paths partitioned by (in store, non-sytem, system)
# NOTE: adding ${lsep} to the prefix here turns every added element into two
-extend args_list spack_flags_include_dirs_list "-I"
-extend args_list include_dirs_list "-I"
+extend args_list spack_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}"
-case "$mode" in
- cpp|cc|as|ccld)
- if [ "$spack_flags_isystem_was_used" = "true" ]; then
- extend args_list SPACK_INCLUDE_DIRS "-isystem${lsep}"
- elif [ "$isystem_was_used" = "true" ]; then
- extend args_list SPACK_INCLUDE_DIRS "-isystem${lsep}"
- else
- extend args_list SPACK_INCLUDE_DIRS "-I"
- fi
- ;;
-esac
-
-extend args_list spack_flags_system_include_dirs_list -I
+extend args_list system_spack_flags_include_dirs_list -I
extend args_list system_include_dirs_list -I
-extend args_list spack_flags_isystem_system_include_dirs_list "-isystem${lsep}"
-extend args_list isystem_system_include_dirs_list "-isystem${lsep}"
-# Library search paths
+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 spack_flags_system_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
- extend args_list spack_flags_rpath_dirs_list "$rpath"
- extend args_list rpath_dirs_list "$rpath"
- extend args_list spack_flags_system_rpath_dirs_list "$rpath"
- extend args_list system_rpath_dirs_list "$rpath"
+ rpath_prefix="$rpath"
;;
ld)
if [ -n "$dtags_to_add" ] ; then
append args_list "$dtags_to_add"
fi
- extend args_list spack_flags_rpath_dirs_list "-rpath${lsep}"
- extend args_list rpath_dirs_list "-rpath${lsep}"
- extend args_list spack_flags_system_rpath_dirs_list "-rpath${lsep}"
- extend args_list system_rpath_dirs_list "-rpath${lsep}"
+ 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
@@ -877,40 +968,4 @@ if [ -n "$SPACK_CCACHE_BINARY" ]; then
esac
fi
-# 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
-
+execute