From 4ed22ad932b440eb6088e31f9bc317aef56f83f1 Mon Sep 17 00:00:00 2001 From: Gregory Becker Date: Fri, 18 Sep 2015 10:38:47 -0700 Subject: [PATCH] partial commit of cflags work --- lib/spack/env/cc | 12 ++-- lib/spack/spack/build_environment.py | 11 ++++ lib/spack/spack/compiler.py | 25 +++++++- lib/spack/spack/compilers/__init__.py | 16 +++-- lib/spack/spack/test/__init__.py | 3 +- lib/spack/spack/test/cflags.py | 91 +++++++++++++++++++++++++++ 6 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 lib/spack/spack/test/cflags.py diff --git a/lib/spack/env/cc b/lib/spack/env/cc index fa85bb595e..b39d91b5f0 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -50,6 +50,8 @@ SPACK_SHORT_SPEC" # The compiler input variables are checked for sanity later: # SPACK_CC, SPACK_CXX, SPACK_F77, SPACK_FC +# The default compiler flags are passed from the config files: +# SPACK_CFLAGS, SPACK_CXXFLAGS, SPACK_FFLAGS, SPACK_LDFLAGS # Debug flag is optional; set to true for debug logging: # SPACK_DEBUG # Test command is used to unit test the compiler script. @@ -87,19 +89,19 @@ done command=$(basename "$0") case "$command" in cc|gcc|c89|c99|clang|xlc) - command="$SPACK_CC" + command="$SPACK_CC $SPACK_CFLAGS" language="C" ;; c++|CC|g++|clang++|xlC) - command="$SPACK_CXX" + command="$SPACK_CXX SPACK_CXXFLAGS" language="C++" ;; f77|xlf) - command="$SPACK_F77" + command="$SPACK_F77 $SPACK_FFLAGS" language="Fortran 77" ;; fc|f90|f95|xlf90) - command="$SPACK_FC" + command="$SPACK_FC $SPACK_FFLAGS" language="Fortran 90" ;; cpp) @@ -107,6 +109,7 @@ case "$command" in ;; ld) mode=ld + command+=" $LDFLAGS" ;; *) die "Unkown compiler: $command" @@ -116,6 +119,7 @@ esac # Finish setting up the mode. if [ -z "$mode" ]; then mode=ccld + command+=" $SPACK_LDFLAGS" for arg in "$@"; do if [ "$arg" = -v -o "$arg" = -V -o "$arg" = --version -o "$arg" = -dumpversion ]; then mode=vcheck diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index dac25d9940..afd987c702 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -103,6 +103,17 @@ def set_compiler_environment_variables(pkg): if compiler.fc: os.environ['SPACK_FC'] = compiler.fc + # Set SPACK compiler flags so our wrapper can add default flags + if compiler.cflags: + os.environ['SPACK_CFLAGS'] = compiler.cflags + if compiler.cxxflags: + os.environ['SPACK_CXXFLAGS'] = compiler.cxxflags + if compiler.cflags: + os.environ['SPACK_FFLAGS'] = compiler.fflags + if compiler.ldflags: + os.environ['SPACK_LDFLAGS'] = compiler.ldflags + + os.environ['SPACK_COMPILER_SPEC'] = str(pkg.spec.compiler) diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index 1e800a8979..83221d6ac0 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -98,7 +98,7 @@ class Compiler(object): cxx11_flag = "-std=c++11" - def __init__(self, cspec, cc, cxx, f77, fc): + def __init__(self, cspec, cc, cxx, f77, fc, cflags=None, cxxflags=None, fflags=None, ldflags=None): def check(exe): if exe is None: return None @@ -110,6 +110,11 @@ def check(exe): self.f77 = check(f77) self.fc = check(fc) + self.cflags = cflags + self.cxxflags = cxxflags + self.fflags = fflags + self.ldflags = ldflags + self.spec = cspec @@ -254,6 +259,24 @@ def find(cls, *path): return list(compilers.values()) + def update_flags(self,c=None,cxx=None,f=None,ld=None): + """Update any flag values provided. Cannot be used to erase values""" + if c: + self.cflags=c + if cxx: + self.cxxflags=cxx + if f: + self.fflags=f + if ld: + self.ldflags=ld + + def erase_flags(self): + """Erase the flag settings""" + self.cflags=None + self.cxxflags=None + self.fflags=None + self.ldflags=None + def __repr__(self): """Return a string represntation of the compiler toolchain.""" diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py index b7b021a1ac..62e8b6b172 100644 --- a/lib/spack/spack/compilers/__init__.py +++ b/lib/spack/spack/compilers/__init__.py @@ -44,6 +44,7 @@ _imported_compilers_module = 'spack.compilers' _required_instance_vars = ['cc', 'cxx', 'f77', 'fc'] +_optional_flag_vars = ['cflags', 'cxxflags', 'fflags', 'ldflags'] _default_order = ['gcc', 'intel', 'pgi', 'clang', 'xlc'] @@ -163,7 +164,7 @@ def all_compilers(): @_auto_compiler_spec def find(compiler_spec): """Return specs of available compilers that match the supplied - compiler spec. Return an list if nothing found.""" + compiler spec. Return an empty list if nothing found.""" return [c for c in all_compilers() if c.satisfies(compiler_spec)] @@ -181,15 +182,20 @@ def get_compiler(cspec): raise InvalidCompilerConfigurationError(cspec) cls = class_for_compiler_name(cspec.name) - compiler_paths = [] + compiler_params = [] for c in _required_instance_vars: compiler_path = items[c] if compiler_path != "None": - compiler_paths.append(compiler_path) + compiler_params.append(compiler_path) else: - compiler_paths.append(None) + compiler_params.append(None) - return cls(cspec, *compiler_paths) + for c in _optional_flag_vars: + if c not in items: + items[c]=None + compiler_params.append(items[c]) + + return cls(cspec, *compiler_params) matches = find(compiler_spec) return [get_compiler(cspec) for cspec in matches] diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py index 0f776bfea4..2c4517d343 100644 --- a/lib/spack/spack/test/__init__.py +++ b/lib/spack/spack/test/__init__.py @@ -59,7 +59,8 @@ 'configure_guess', 'unit_install', 'lock', - 'database'] + 'database', + 'cflags'] def list_tests(): diff --git a/lib/spack/spack/test/cflags.py b/lib/spack/spack/test/cflags.py new file mode 100644 index 0000000000..18fc643d7f --- /dev/null +++ b/lib/spack/spack/test/cflags.py @@ -0,0 +1,91 @@ +############################################################################## +# 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://scalability-llnl.github.io/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 +############################################################################## +import os +import unittest +import shutil +import tempfile + +from llnl.util.filesystem import * + +import spack +from spack.stage import Stage +from spack.fetch_strategy import URLFetchStrategy +from spack.directory_layout import YamlDirectoryLayout +from spack.util.executable import which +from spack.test.mock_packages_test import * +from spack.test.mock_repo import MockArchive + + +class CflagsTest(MockPackagesTest): + """Tests install and uninstall on a trivial package.""" + + def setUp(self): + super(CflagsTest, self).setUp() + + # create a simple installable package directory and tarball + self.repo = MockArchive() + + # We use a fake package, so skip the checksum. + spack.do_checksum = False + + # Use a fake install directory to avoid conflicts bt/w + # installed pkgs and mock packages. + self.tmpdir = tempfile.mkdtemp() + self.orig_layout = spack.install_layout + spack.install_layout = YamlDirectoryLayout(self.tmpdir) + + + def tearDown(self): + super(CflagsTest, self).tearDown() + + if self.repo.stage is not None: + self.repo.stage.destroy() + + # Turn checksumming back on + spack.do_checksum = True + + # restore spack's layout. + spack.install_layout = self.orig_layout + shutil.rmtree(self.tmpdir, ignore_errors=True) + + + def test_compiler_calls(self): + # Get a basic concrete spec for the trivial install package. + spec = Spec('cflags_test_package') + spec.concretize() + self.assertTrue(spec.concrete) + + # Get the package + pkg = spack.db.get(spec) + + # Fake the URL for the package so it downloads from a file. + pkg.fetcher = URLFetchStrategy(self.repo.url) + + try: + pkg.do_install() + pkg.do_uninstall() + except Exception, e: + pkg.remove_prefix() + raise