compiler wrappers: don't override -isystem with -I (#16077)
If the Spack compiler wrapper encounters any "-isystem" option, then when adding include directories for Spack dependencies, Spack will use "-isystem" instead of "-I". This prevents Spack-generated "-I" options from overriding the "-isystem" options generated by the build system. To ensure that build-system "-isystem" directories are searched first, Spack places all of its inserted "-isystem" directories after. The new ordering of -isystem includes is: * -isystem from build system (not system directories) * -isystem from Spack * -isystem from build system (for directories like /usr/include) The prior order of "-I" arguments is preserved (although as of this commit Spack no longer generates -I if -isystem is detected): * -I from build system (not system directories) * -I from Spack (only if there are no "-isystem" options) * -I from build system (for directories like /usr/include)
This commit is contained in:
		
							
								
								
									
										44
									
								
								lib/spack/env/cc
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								lib/spack/env/cc
									
									
									
									
										vendored
									
									
								
							@@ -15,7 +15,7 @@
 | 
			
		||||
# 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           arguments for dependency /include directories.
 | 
			
		||||
#      -I and/or -isystem arguments for dependency /include directories.
 | 
			
		||||
#      -L                 arguments for dependency /lib directories.
 | 
			
		||||
#      -Wl,-rpath         arguments for dependency /lib directories.
 | 
			
		||||
#
 | 
			
		||||
@@ -251,10 +251,11 @@ input_command="$*"
 | 
			
		||||
#
 | 
			
		||||
# Parse the command line arguments.
 | 
			
		||||
#
 | 
			
		||||
# We extract -L, -I, 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.
 | 
			
		||||
# 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
 | 
			
		||||
@@ -273,12 +274,24 @@ system_libdirs=()
 | 
			
		||||
system_rpaths=()
 | 
			
		||||
libs=()
 | 
			
		||||
other_args=()
 | 
			
		||||
isystem_system_includes=()
 | 
			
		||||
isystem_includes=()
 | 
			
		||||
 | 
			
		||||
while [ -n "$1" ]; do
 | 
			
		||||
    # an RPATH to be added after the case statement.
 | 
			
		||||
    rp=""
 | 
			
		||||
 | 
			
		||||
    case "$1" in
 | 
			
		||||
        -isystem*)
 | 
			
		||||
            arg="${1#-isystem}"
 | 
			
		||||
	    isystem_was_used=true
 | 
			
		||||
            if [ -z "$arg" ]; then shift; arg="$1"; fi
 | 
			
		||||
            if system_dir "$arg"; then
 | 
			
		||||
                isystem_system_includes+=("$arg")
 | 
			
		||||
            else
 | 
			
		||||
                isystem_includes+=("$arg")
 | 
			
		||||
            fi
 | 
			
		||||
            ;;
 | 
			
		||||
        -I*)
 | 
			
		||||
            arg="${1#-I}"
 | 
			
		||||
            if [ -z "$arg" ]; then shift; arg="$1"; fi
 | 
			
		||||
@@ -425,12 +438,6 @@ then
 | 
			
		||||
    esac
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Prepend include directories
 | 
			
		||||
IFS=':' read -ra include_dirs <<< "$SPACK_INCLUDE_DIRS"
 | 
			
		||||
if [[ $mode == cpp || $mode == cc || $mode == as || $mode == ccld ]]; then
 | 
			
		||||
    includes=("${includes[@]}" "${include_dirs[@]}")
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
IFS=':' read -ra rpath_dirs <<< "$SPACK_RPATH_DIRS"
 | 
			
		||||
if [[ $mode == ccld || $mode == ld ]]; then
 | 
			
		||||
 | 
			
		||||
@@ -481,9 +488,22 @@ args=()
 | 
			
		||||
# flags assembled earlier
 | 
			
		||||
args+=("${flags[@]}")
 | 
			
		||||
 | 
			
		||||
# include directory search paths
 | 
			
		||||
# Insert include directories just prior to any system include directories
 | 
			
		||||
 | 
			
		||||
for dir in "${includes[@]}";         do args+=("-I$dir"); done
 | 
			
		||||
for dir in "${isystem_includes[@]}";         do args+=("-isystem$dir"); done
 | 
			
		||||
 | 
			
		||||
IFS=':' read -ra spack_include_dirs <<< "$SPACK_INCLUDE_DIRS"
 | 
			
		||||
if [[ $mode == cpp || $mode == cc || $mode == as || $mode == ccld ]]; then
 | 
			
		||||
    if [[ "$isystem_was_used" == "true" ]] ; then
 | 
			
		||||
	for dir in "${spack_include_dirs[@]}";  do args+=("-isystem$dir"); done
 | 
			
		||||
    else
 | 
			
		||||
	for dir in "${spack_include_dirs[@]}";  do args+=("-I$dir"); done
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
for dir in "${system_includes[@]}";  do args+=("-I$dir"); done
 | 
			
		||||
for dir in "${isystem_system_includes[@]}";  do args+=("-isystem$dir"); done
 | 
			
		||||
 | 
			
		||||
# Library search paths
 | 
			
		||||
for dir in "${libdirs[@]}";          do args+=("-L$dir"); done
 | 
			
		||||
 
 | 
			
		||||
@@ -338,6 +338,36 @@ def test_ccld_deps():
 | 
			
		||||
            test_args_without_paths)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_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',
 | 
			
		||||
                 SPACK_LINK_DIRS='xlib:ylib:zlib'):
 | 
			
		||||
        mytest_args = test_args + ['-isystemfooinc']
 | 
			
		||||
        check_args(
 | 
			
		||||
            cc, mytest_args,
 | 
			
		||||
            [real_cc] +
 | 
			
		||||
            test_include_paths +
 | 
			
		||||
            ['-isystemfooinc',
 | 
			
		||||
             '-isystemxinc',
 | 
			
		||||
             '-isystemyinc',
 | 
			
		||||
             '-isystemzinc'] +
 | 
			
		||||
            test_library_paths +
 | 
			
		||||
            ['-Lxlib',
 | 
			
		||||
             '-Lylib',
 | 
			
		||||
             '-Lzlib'] +
 | 
			
		||||
            ['-Wl,--disable-new-dtags'] +
 | 
			
		||||
            test_wl_rpaths +
 | 
			
		||||
            ['-Wl,-rpath,xlib',
 | 
			
		||||
             '-Wl,-rpath,ylib',
 | 
			
		||||
             '-Wl,-rpath,zlib'] +
 | 
			
		||||
            test_args_without_paths)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_cc_deps():
 | 
			
		||||
    """Ensure -L and RPATHs are not added in cc mode."""
 | 
			
		||||
    with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc',
 | 
			
		||||
@@ -390,6 +420,44 @@ def test_ccld_with_system_dirs():
 | 
			
		||||
            test_args_without_paths)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_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',
 | 
			
		||||
                 SPACK_LINK_DIRS='xlib:ylib:zlib'):
 | 
			
		||||
 | 
			
		||||
        sys_path_args = ['-isystem/usr/include',
 | 
			
		||||
                         '-L/usr/local/lib',
 | 
			
		||||
                         '-Wl,-rpath,/usr/lib64',
 | 
			
		||||
                         '-isystem/usr/local/include',
 | 
			
		||||
                         '-L/lib64/']
 | 
			
		||||
        check_args(
 | 
			
		||||
            cc, sys_path_args + test_args,
 | 
			
		||||
            [real_cc] +
 | 
			
		||||
            test_include_paths +
 | 
			
		||||
            ['-isystemxinc',
 | 
			
		||||
             '-isystemyinc',
 | 
			
		||||
             '-isystemzinc'] +
 | 
			
		||||
            ['-isystem/usr/include',
 | 
			
		||||
             '-isystem/usr/local/include'] +
 | 
			
		||||
            test_library_paths +
 | 
			
		||||
            ['-Lxlib',
 | 
			
		||||
             '-Lylib',
 | 
			
		||||
             '-Lzlib'] +
 | 
			
		||||
            ['-L/usr/local/lib',
 | 
			
		||||
             '-L/lib64/'] +
 | 
			
		||||
            ['-Wl,--disable-new-dtags'] +
 | 
			
		||||
            test_wl_rpaths +
 | 
			
		||||
            ['-Wl,-rpath,xlib',
 | 
			
		||||
             '-Wl,-rpath,ylib',
 | 
			
		||||
             '-Wl,-rpath,zlib'] +
 | 
			
		||||
            ['-Wl,-rpath,/usr/lib64'] +
 | 
			
		||||
            test_args_without_paths)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_ld_deps():
 | 
			
		||||
    """Ensure no (extra) -I args or -Wl, are passed in ld mode."""
 | 
			
		||||
    with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user