cc: refactor flag adding so that it's not in reverse order

- flags were prepended in reverse order to args, but this makes it hard
  to see what order they'll be in on the final command line.

- add them in the order they'll appear to make cc easier to maintain.

- simplify code for assembling the command line

- fix separator used in SPACK_SYSTEM_DIRS test
This commit is contained in:
Todd Gamblin 2018-08-07 22:58:13 -07:00
parent 4210f839e2
commit bb5d83890d
2 changed files with 59 additions and 32 deletions

77
lib/spack/env/cc vendored
View File

@ -80,7 +80,7 @@ IFS=':' read -ra SPACK_SYSTEM_DIRS <<< "${SPACK_SYSTEM_DIRS}"
# test whether a path is a system directory # test whether a path is a system directory
function system_dir { function system_dir {
path="$1" path="$1"
for sd in ${SPACK_SYSTEM_DIRS[@]}; do for sd in "${SPACK_SYSTEM_DIRS[@]}"; do
if [ "${path}" == "${sd}" ] || [ "${path}" == "${sd}/" ]; then if [ "${path}" == "${sd}" ] || [ "${path}" == "${sd}/" ]; then
# success if path starts with a system prefix # success if path starts with a system prefix
return 0 return 0
@ -89,7 +89,7 @@ function system_dir {
return 1 # fail if path starts no system prefix return 1 # fail if path starts no system prefix
} }
for param in ${parameters[@]}; do for param in "${parameters[@]}"; do
if [[ -z ${!param} ]]; then if [[ -z ${!param} ]]; then
die "Spack compiler must be run from Spack! Input '$param' is missing." die "Spack compiler must be run from Spack! Input '$param' is missing."
fi fi
@ -248,7 +248,6 @@ fi
# Save original command for debug logging # Save original command for debug logging
input_command="$*" input_command="$*"
args=()
# #
# Parse the command line arguments. # Parse the command line arguments.
@ -277,7 +276,9 @@ libs=()
other_args=() other_args=()
while [ -n "$1" ]; do while [ -n "$1" ]; do
# an RPATH to be added after the case statement.
rp="" rp=""
case "$1" in case "$1" in
-I*) -I*)
arg="${1#-I}" arg="${1#-I}"
@ -362,37 +363,53 @@ while [ -n "$1" ]; do
done done
# #
# Prepend flags from Spack's cppflags, cflags, cxxflags, fcflags, fflags, # Add flags from Spack's cppflags, cflags, cxxflags, fcflags, fflags, and
# and ldflags. # 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=()
# Add ldflags # Fortran flags come before CPPFLAGS
case "$mode" in
ld|ccld)
args=(${SPACK_LDFLAGS[@]} "${args[@]}") ;;
esac
# Add C, C++, and Fortran flags
case "$mode" in case "$mode" in
cc|ccld) cc|ccld)
case $lang_flags in case $lang_flags in
C)
args=(${SPACK_CFLAGS[@]} "${args[@]}") ;;
CXX)
args=(${SPACK_CXXFLAGS[@]} "${args[@]}") ;;
F) F)
args=(${SPACK_FFLAGS[@]} "${args[@]}") ;; flags=("${flags[@]}" "${SPACK_FFLAGS[@]}") ;;
esac esac
;; ;;
esac esac
# Add cppflags # C preprocessor flags come before any C/CXX flags
case "$mode" in case "$mode" in
cpp|as|cc|ccld) cpp|as|cc|ccld)
args=(${SPACK_CPPFLAGS[@]} "${args[@]}") ;; flags=("${flags[@]}" "${SPACK_CPPFLAGS[@]}") ;;
esac esac
# Include all -L's and prefix/whatever dirs in rpath
# Add C and C++ flags
case "$mode" in
cc|ccld)
case $lang_flags in
C)
flags=("${flags[@]}" "${SPACK_CFLAGS[@]}") ;;
CXX)
flags=("${flags[@]}" "${SPACK_CXXFLAGS[@]}") ;;
esac
;;
esac
# Linker flags
case "$mode" in
ld|ccld)
flags=("${flags[@]}" "${SPACK_LDFLAGS[@]}") ;;
esac
# Include the package's prefix/lib[64] dirs in rpath. We don't know until
# *after* installation which one's correct, so we include both lib and
# lib64, assuming that only one will be present.
case "$mode" in case "$mode" in
ld|ccld) ld|ccld)
$add_rpaths && rpaths+=("$SPACK_PREFIX/lib") $add_rpaths && rpaths+=("$SPACK_PREFIX/lib")
@ -400,10 +417,10 @@ case "$mode" in
;; ;;
esac esac
# Read spack dependencies from the path environment variable # Read spack dependencies from the environment. This is a list of prefixes.
IFS=':' read -ra deps <<< "$SPACK_DEPENDENCIES" IFS=':' read -ra deps <<< "$SPACK_DEPENDENCIES"
for dep in "${deps[@]}"; do for dep in "${deps[@]}"; do
# Append include directories # Append include directories in any compilation mode
case "$mode" in case "$mode" in
cpp|cc|as|ccld) cpp|cc|as|ccld)
if [[ -d $dep/include ]]; then if [[ -d $dep/include ]]; then
@ -412,7 +429,7 @@ for dep in "${deps[@]}"; do
;; ;;
esac esac
# Append lib/lib64 and RPATH directories # Append lib/lib64 and RPATH directories, but only if we're linking
case "$mode" in case "$mode" in
ld|ccld) ld|ccld)
if [[ -d $dep/lib ]]; then if [[ -d $dep/lib ]]; then
@ -436,6 +453,7 @@ for dep in "${deps[@]}"; do
esac esac
done done
# add RPATHs if we're in in any linking mode
case "$mode" in case "$mode" in
ld|ccld) ld|ccld)
# Set extra RPATHs # Set extra RPATHs
@ -446,14 +464,23 @@ case "$mode" in
done done
# Add SPACK_LDLIBS to args # Add SPACK_LDLIBS to args
for lib in ${SPACK_LDLIBS[@]}; do for lib in "${SPACK_LDLIBS[@]}"; do
libs+=("${lib#-l}") libs+=("${lib#-l}")
done done
;; ;;
esac esac
# Put the arguments back together in one list #
# Finally, reassemble the command line.
#
# Includes and system includes first # Includes and system includes first
args=()
# flags assembled earlier
args+=("${flags[@]}")
# include directory search paths
for dir in "${includes[@]}"; do args+=("-I$dir"); done for dir in "${includes[@]}"; do args+=("-I$dir"); done
for dir in "${system_includes[@]}"; do args+=("-I$dir"); done for dir in "${system_includes[@]}"; do args+=("-I$dir"); done

View File

@ -124,7 +124,7 @@ def wrapper_environment():
SPACK_DEBUG_LOG_ID='foo-hashabc', SPACK_DEBUG_LOG_ID='foo-hashabc',
SPACK_COMPILER_SPEC='gcc@4.4.7', SPACK_COMPILER_SPEC='gcc@4.4.7',
SPACK_SHORT_SPEC='foo@1.2 arch=linux-rhel6-x86_64 /hashabc', SPACK_SHORT_SPEC='foo@1.2 arch=linux-rhel6-x86_64 /hashabc',
SPACK_SYSTEM_DIRS=' '.join(system_dirs), SPACK_SYSTEM_DIRS=':'.join(system_dirs),
SPACK_CC_RPATH_ARG='-Wl,-rpath,', SPACK_CC_RPATH_ARG='-Wl,-rpath,',
SPACK_CXX_RPATH_ARG='-Wl,-rpath,', SPACK_CXX_RPATH_ARG='-Wl,-rpath,',
SPACK_F77_RPATH_ARG='-Wl,-rpath,', SPACK_F77_RPATH_ARG='-Wl,-rpath,',
@ -180,27 +180,27 @@ def dep4(tmpdir_factory):
def check_cc(command, args, expected): def check_cc(command, args, expected):
with set_env(SPACK_TEST_COMMAND=command): with set_env(SPACK_TEST_COMMAND=command):
assert cc(*args, output=str).strip().split() == expected assert expected == cc(*args, output=str).strip().split()
def check_cxx(command, args, expected): def check_cxx(command, args, expected):
with set_env(SPACK_TEST_COMMAND=command): with set_env(SPACK_TEST_COMMAND=command):
assert cxx(*args, output=str).strip().split() == expected assert expected == cxx(*args, output=str).strip().split()
def check_fc(command, args, expected): def check_fc(command, args, expected):
with set_env(SPACK_TEST_COMMAND=command): with set_env(SPACK_TEST_COMMAND=command):
assert fc(*args, output=str).strip().split() == expected assert expected == fc(*args, output=str).strip().split()
def check_ld(command, args, expected): def check_ld(command, args, expected):
with set_env(SPACK_TEST_COMMAND=command): with set_env(SPACK_TEST_COMMAND=command):
assert ld(*args, output=str).strip().split() == expected assert expected == ld(*args, output=str).strip().split()
def check_cpp(command, args, expected): def check_cpp(command, args, expected):
with set_env(SPACK_TEST_COMMAND=command): with set_env(SPACK_TEST_COMMAND=command):
assert cpp(*args, output=str).strip().split() == expected assert expected == cpp(*args, output=str).strip().split()
def test_vcheck_mode(): def test_vcheck_mode():
@ -303,8 +303,8 @@ def test_fc_flags(wrapper_flags):
check_fc( check_fc(
'dump-args', test_args, 'dump-args', test_args,
[real_cc] + [real_cc] +
spack_cppflags +
spack_fflags + spack_fflags +
spack_cppflags +
spack_ldflags + spack_ldflags +
test_include_paths + test_include_paths +
test_library_paths + test_library_paths +