clang : solve the issue with missing default include paths for OpenMP and libc++

resource : support for finer grained linking of resources
This commit is contained in:
alalazo 2015-12-09 13:06:39 +01:00
parent 50bd4d2e4e
commit 20e67bc5e6
5 changed files with 56 additions and 18 deletions

View File

@ -269,19 +269,20 @@ def variant(pkg, name, default=False, description=""):
def resource(pkg, **kwargs): def resource(pkg, **kwargs):
""" """
Define an external resource to be fetched and staged when building the package. Based on the keywords present in the Define an external resource to be fetched and staged when building the package. Based on the keywords present in the
dictionary the appropriate FetchStrategy will be used for the resource. dictionary the appropriate FetchStrategy will be used for the resource. Resources are fetched and staged in their
own folder inside spack stage area, and then linked into the stage area of the package that needs them.
List of recognized keywords: List of recognized keywords:
* 'when' : represents the condition upon which the resource is needed (optional) * 'when' : (optional) represents the condition upon which the resource is needed
* 'destination' : path where to extract / checkout the resource (optional). This path must be a relative path, * 'destination' : (optional) path where to link the resource. This path must be relative to the main package stage
and it must fall inside the stage area of the main package. area.
* 'basename' : basename of the resource source folder within destination (optional). * 'placement' : (optional) gives the possibility to fine tune how the resource is linked into the main package stage
area.
""" """
when = kwargs.get('when', pkg.name) when = kwargs.get('when', pkg.name)
destination = kwargs.get('destination', "") destination = kwargs.get('destination', "")
basename = kwargs.get('basename', None) placement = kwargs.get('placement', None)
# Check if the path is relative # Check if the path is relative
if os.path.isabs(destination): if os.path.isabs(destination):
message = "The destination keyword of a resource directive can't be an absolute path.\n" message = "The destination keyword of a resource directive can't be an absolute path.\n"
@ -298,7 +299,7 @@ def resource(pkg, **kwargs):
resources = pkg.resources.setdefault(when_spec, []) resources = pkg.resources.setdefault(when_spec, [])
fetcher = from_kwargs(**kwargs) fetcher = from_kwargs(**kwargs)
name = kwargs.get('name') name = kwargs.get('name')
resources.append(Resource(name, fetcher, destination, basename)) resources.append(Resource(name, fetcher, destination, placement))
class DirectiveError(spack.error.SpackError): class DirectiveError(spack.error.SpackError):

View File

@ -683,11 +683,17 @@ def _expand_archive(stage, name=self.name):
for resource in resources: for resource in resources:
stage = resource.fetcher.stage stage = resource.fetcher.stage
_expand_archive(stage, resource.name) _expand_archive(stage, resource.name)
basename = os.path.basename(stage.source_path) if resource.basename is None else resource.basename # Turn placement into a dict with relative paths
link_path = join_path(self.stage.source_path, resource.destination, basename) placement = os.path.basename(stage.source_path) if resource.placement is None else resource.placement
if not isinstance(placement, dict):
placement = {'': placement}
# Make the paths in the dictionary absolute and link
for key, value in placement.iteritems():
link_path = join_path(self.stage.source_path, resource.destination, value)
source_path = join_path(stage.source_path, key)
if not os.path.exists(link_path): if not os.path.exists(link_path):
# Create a symlink # Create a symlink
os.symlink(stage.source_path, link_path) os.symlink(source_path, link_path)
########## ##########
self.stage.chdir_to_source() self.stage.chdir_to_source()

View File

@ -30,10 +30,10 @@
class Resource(object): class Resource(object):
""" """
Represents an optional resource. Aggregates a name, a fetcher and a destination. Represents an optional resource. Aggregates a name, a fetcher, a destination and a placement
""" """
def __init__(self, name, fetcher, destination, basename): def __init__(self, name, fetcher, destination, placement):
self.name = name self.name = name
self.fetcher = fetcher self.fetcher = fetcher
self.destination = destination self.destination = destination
self.basename = basename self.placement = placement

View File

@ -22,8 +22,13 @@
# along with this program; if not, write to the Free Software Foundation, # along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
from spack import * from spack import *
import os
import os.path
class Clang(Package): class Clang(Package):
"""The goal of the Clang project is to create a new C, C++, """The goal of the Clang project is to create a new C, C++,
Objective C and Objective C++ front-end for the LLVM compiler. Objective C and Objective C++ front-end for the LLVM compiler.
@ -62,3 +67,29 @@ def install(self, spec, prefix):
*options) *options)
make() make()
make("install") make("install")
# CLang doesn't look in llvm folders for system headers...
self.link_llvm_directories(spec)
def link_llvm_directories(self, spec):
def clang_include_dir_at(root):
return join_path(root, 'include')
def clang_lib_dir_at(root):
return join_path(root, 'lib/clang/', str(self.version), 'include')
def do_link(source_dir, destination_dir):
if os.path.exists(source_dir):
for name in os.listdir(source_dir):
source = join_path(source_dir, name)
link = join_path(destination_dir, name)
os.symlink(source, link)
# Link folder and files in include
llvm_dir = clang_include_dir_at(spec['llvm'].prefix)
clang_dir = clang_include_dir_at(self.prefix)
do_link(llvm_dir, clang_dir)
# Link folder and files in lib
llvm_dir = clang_lib_dir_at(spec['llvm'].prefix)
clang_dir = clang_lib_dir_at(self.prefix)
do_link(llvm_dir, clang_dir)

View File

@ -53,10 +53,10 @@ class Llvm(Package):
destination='projects', when='@3.7.0') destination='projects', when='@3.7.0')
resource(name='libcxx', resource(name='libcxx',
url='http://llvm.org/releases/3.7.0/libcxx-3.7.0.src.tar.xz', md5='46aa5175cbe1ad42d6e9c995968e56dd', url='http://llvm.org/releases/3.7.0/libcxx-3.7.0.src.tar.xz', md5='46aa5175cbe1ad42d6e9c995968e56dd',
destination='projects', basename='libcxx', when='+libcxx@3.7.0') destination='projects', placement='libcxx', when='+libcxx@3.7.0')
resource(name='libcxxabi', resource(name='libcxxabi',
url='http://llvm.org/releases/3.7.0/libcxxabi-3.7.0.src.tar.xz', md5='5aa769e2fca79fa5335cfae8f6258772', url='http://llvm.org/releases/3.7.0/libcxxabi-3.7.0.src.tar.xz', md5='5aa769e2fca79fa5335cfae8f6258772',
destination='projects', basename='libcxxabi', when='+libcxx@3.7.0') destination='projects', placement='libcxxabi', when='+libcxx@3.7.0')
########## ##########
def install(self, spec, prefix): def install(self, spec, prefix):