 f80e839ff4
			
		
	
	f80e839ff4
	
	
	
		
			
			- ld -r doesn't work with RPATH on OS X. - for GNU ld, the -r option only means 'relocatable', and doesn't affect RPATH. - This adds special handling to omit RPATHs for ld -r on OS X
		
			
				
	
	
		
			268 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| ##############################################################################
 | |
| # Copyright (c) 2013, Lawrence Livermore National Security, LLC.
 | |
| # Produced at the Lawrence Livermore National Laboratory.
 | |
| #
 | |
| # This file is part of Spack.
 | |
| # Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
 | |
| # LLNL-CODE-647188
 | |
| #
 | |
| # For details, see https://github.com/llnl/spack
 | |
| # Please also see the LICENSE file for our notice and the LGPL.
 | |
| #
 | |
| # This program is free software; you can redistribute it and/or modify
 | |
| # it under the terms of the GNU General Public License (as published by
 | |
| # the Free Software Foundation) version 2.1 dated February 1999.
 | |
| #
 | |
| # This program is distributed in the hope that it will be useful, but
 | |
| # WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
 | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
 | |
| # conditions of the GNU General Public License for more details.
 | |
| #
 | |
| # You should have received a copy of the GNU Lesser General Public License
 | |
| # along with this program; if not, write to the Free Software Foundation,
 | |
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | |
| ##############################################################################
 | |
| #
 | |
| # 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           arguments for dependency /include directories.
 | |
| #      -L           arguments for dependency /lib directories.
 | |
| #      -Wl,-rpath   arguments for dependency /lib directories.
 | |
| #
 | |
| 
 | |
| # This is the list of environment variables that need to be set before
 | |
| # the script runs.  They are set by routines in spack.build_environment
 | |
| # as part of spack.package.Package.do_install().
 | |
| parameters="
 | |
| SPACK_PREFIX
 | |
| SPACK_ENV_PATH
 | |
| SPACK_DEBUG_LOG_DIR
 | |
| SPACK_COMPILER_SPEC
 | |
| SPACK_SHORT_SPEC"
 | |
| 
 | |
| # The compiler input variables are checked for sanity later:
 | |
| #   SPACK_CC, SPACK_CXX, SPACK_F77, SPACK_FC
 | |
| # Debug flag is optional; set to true for debug logging:
 | |
| #   SPACK_DEBUG
 | |
| # Test command is used to unit test the compiler script.
 | |
| #   SPACK_TEST_COMMAND
 | |
| # Dependencies can be empty for pkgs with no deps:
 | |
| #   SPACK_DEPENDENCIES
 | |
| 
 | |
| # die()
 | |
| # Prints a message and exits with error 1.
 | |
| function die {
 | |
|     echo "$@"
 | |
|     exit 1
 | |
| }
 | |
| 
 | |
| for param in $parameters; do
 | |
|     if [[ -z ${!param} ]]; then
 | |
|         die "Spack compiler must be run from spack!  Input $param was missing!"
 | |
|     fi
 | |
| done
 | |
| 
 | |
| #
 | |
| # 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:
 | |
| #    cpp     preprocess
 | |
| #    cc      compile
 | |
| #    as      assemble
 | |
| #    ld      link
 | |
| #    ccld    compile & link
 | |
| #    vcheck  version check
 | |
| #
 | |
| # Depending on the mode, we may or may not add extra rpaths.
 | |
| # This variable controls whether they are added.
 | |
| add_rpaths=true
 | |
| 
 | |
| command=$(basename "$0")
 | |
| case "$command" in
 | |
|     cc|c89|c99|gcc|clang|icc|pgcc|xlc)
 | |
|         command="$SPACK_CC"
 | |
|         language="C"
 | |
|         ;;
 | |
|     c++|CC|g++|clang++|icpc|pgc++|xlc++)
 | |
|         command="$SPACK_CXX"
 | |
|         language="C++"
 | |
|         ;;
 | |
|     f90|fc|f95|gfortran|ifort|pgfortran|xlf90|nagfor)
 | |
|         command="$SPACK_FC"
 | |
|         language="Fortran 90"
 | |
|         ;;
 | |
|     f77|gfortran|ifort|pgfortran|xlf|nagfor)
 | |
|         command="$SPACK_F77"
 | |
|         language="Fortran 77"
 | |
|         ;;
 | |
|     cpp)
 | |
|         mode=cpp
 | |
|         ;;
 | |
|     ld)
 | |
|         mode=ld
 | |
| 
 | |
|         # Darwin's linker has a -r argument that merges object files
 | |
|         # together. It doesn't work with -rpath.
 | |
|         if [[ $OSTYPE = darwin* ]]; then
 | |
|             for arg in "$@"; do
 | |
|                 if [ "$arg" = -r ]; then
 | |
|                     add_rpaths=false
 | |
|                     break
 | |
| 	            fi
 | |
|             done
 | |
|         fi
 | |
|         ;;
 | |
|     *)
 | |
|         die "Unkown compiler: $command"
 | |
|         ;;
 | |
| esac
 | |
| 
 | |
| # If any of the arguments below is present then the mode is vcheck. In
 | |
| # vcheck mode nothing is added in terms of extra search paths or
 | |
| # libraries
 | |
| if [ -z "$mode" ]; then
 | |
|     for arg in "$@"; do
 | |
|         if [ "$arg" = -v -o "$arg" = -V -o "$arg" = --version -o "$arg" = -dumpversion ]; then
 | |
|             mode=vcheck
 | |
|             break
 | |
|     fi
 | |
|     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
 | |
| 
 | |
| # Dump the version and exit if we're in testing mode.
 | |
| if [ "$SPACK_TEST_COMMAND" = "dump-mode" ]; then
 | |
|     echo "$mode"
 | |
|     exit
 | |
| fi
 | |
| 
 | |
| # Check that at least one of the real commands was actually selected,
 | |
| # otherwise we don't know what to execute.
 | |
| if [[ -z $command ]]; then
 | |
|     die "ERROR: Compiler '$SPACK_COMPILER_SPEC' does not support compiling $language programs."
 | |
| fi
 | |
| 
 | |
| if [ "$mode" == vcheck ] ; then
 | |
|     exec ${command} "$@"
 | |
| fi
 | |
| 
 | |
| # Save original command for debug logging
 | |
| input_command="$@"
 | |
| args=("$@")
 | |
| 
 | |
| # Read spack dependencies from the path environment variable
 | |
| IFS=':' read -ra deps <<< "$SPACK_DEPENDENCIES"
 | |
| for dep in "${deps[@]}"; do
 | |
|     # Prepend include directories
 | |
|     if [[ -d $dep/include ]]; then
 | |
|         if [[ $mode = cpp || $mode = cc || $mode = as || $mode = ccld ]]; then
 | |
|             args=("-I$dep/include" "${args[@]}")
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     # Prepend lib and RPATH directories
 | |
|     if [[ -d $dep/lib ]]; then
 | |
|         if [[ $mode = ccld ]]; then
 | |
|             $add_rpaths && args=("-Wl,-rpath,$dep/lib" "${args[@]}")
 | |
|             args=("-L$dep/lib" "${args[@]}")
 | |
|         elif [[ $mode = ld ]]; then
 | |
|             $add_rpaths && args=("-rpath" "$dep/lib" "${args[@]}")
 | |
|             args=("-L$dep/lib" "${args[@]}")
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     # Prepend lib64 and RPATH directories
 | |
|     if [[ -d $dep/lib64 ]]; then
 | |
|         if [[ $mode = ccld ]]; then
 | |
|             $add_rpaths && args=("-Wl,-rpath,$dep/lib64" "${args[@]}")
 | |
|             args=("-L$dep/lib64" "${args[@]}")
 | |
|         elif [[ $mode = ld ]]; then
 | |
|             $add_rpaths && args=("-rpath" "$dep/lib64" "${args[@]}")
 | |
|             args=("-L$dep/lib64" "${args[@]}")
 | |
|         fi
 | |
|     fi
 | |
| done
 | |
| 
 | |
| # Include all -L's and prefix/whatever dirs in rpath
 | |
| if [[ $mode = ccld ]]; then
 | |
|     $add_rpaths && args=("-Wl,-rpath,$SPACK_PREFIX/lib" "-Wl,-rpath,$SPACK_PREFIX/lib64" "${args[@]}")
 | |
| elif [[ $mode = ld ]]; then
 | |
|     $add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib" "-rpath" "$SPACK_PREFIX/lib64" "${args[@]}")
 | |
| fi
 | |
| 
 | |
| #
 | |
| # Unset pesky environment variables that could affect build sanity.
 | |
| #
 | |
| unset LD_LIBRARY_PATH
 | |
| unset LD_RUN_PATH
 | |
| unset DYLD_LIBRARY_PATH
 | |
| 
 | |
| #
 | |
| # Filter '.' and Spack environment directories out of PATH so that
 | |
| # this script doesn't just call itself
 | |
| #
 | |
| IFS=':' read -ra env_path <<< "$PATH"
 | |
| IFS=':' read -ra spack_env_dirs <<< "$SPACK_ENV_PATH"
 | |
| spack_env_dirs+=("" ".")
 | |
| PATH=""
 | |
| for dir in "${env_path[@]}"; do
 | |
|     remove=""
 | |
|     for rm_dir in "${spack_env_dirs[@]}"; do
 | |
|         if [[ $dir = $rm_dir ]]; then remove=True; fi
 | |
|     done
 | |
|     if [[ -z $remove ]]; then
 | |
|         PATH="${PATH:+$PATH:}$dir"
 | |
|     fi
 | |
| done
 | |
| export PATH
 | |
| 
 | |
| full_command=("$command" "${args[@]}")
 | |
| 
 | |
| # In test command mode, write out full command for Spack tests.
 | |
| if [[ $SPACK_TEST_COMMAND = dump-args ]]; then
 | |
|     echo "${full_command[@]}"
 | |
|     exit
 | |
| elif [[ -n $SPACK_TEST_COMMAND ]]; then
 | |
|     die "ERROR: Unknown test command"
 | |
| 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_SHORT_SPEC.in.log"
 | |
|     output_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_SHORT_SPEC.out.log"
 | |
|     echo "[$mode] $command $input_command" >> $input_log
 | |
|     echo "[$mode] ${full_command[@]}" >> $output_log
 | |
| fi
 | |
| 
 | |
| exec "${full_command[@]}"
 |