summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--var/spack/repos/builtin/packages/llvm-doe/package.py319
1 files changed, 202 insertions, 117 deletions
diff --git a/var/spack/repos/builtin/packages/llvm-doe/package.py b/var/spack/repos/builtin/packages/llvm-doe/package.py
index c384210561..88303fae7d 100644
--- a/var/spack/repos/builtin/packages/llvm-doe/package.py
+++ b/var/spack/repos/builtin/packages/llvm-doe/package.py
@@ -2,12 +2,14 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import os
import os.path
import re
import sys
import llnl.util.tty as tty
+import spack.build_environment
import spack.util.executable
@@ -20,14 +22,20 @@ class LlvmDoe(CMakePackage, CudaPackage):
url = "https://github.com/llvm-doe-org/llvm-project/archive/llvmorg-10.0.0.zip"
git = "https://github.com/llvm-doe-org/llvm-project"
maintainers = ['shintaro-iwasaki']
+
tags = ['e4s']
+ generator = 'Ninja'
+
+ family = "compiler" # Used by lmod
+
version('doe', branch='doe', preferred=True)
version('upstream', branch='llvm.org/main')
version('bolt', branch='bolt/main')
version('clacc', branch='clacc/master')
version('pragma-clang-loop', branch='sollve/pragma-clang-loop')
version('pragma-omp-tile', branch='sollve/pragma-omp-tile')
+ version('13.0.0', branch='llvm.org/llvmorg-13.0.0')
# NOTE: The debug version of LLVM is an order of magnitude larger than
# the release version, and may take up 20-30 GB of space. If you want
@@ -95,6 +103,11 @@ class LlvmDoe(CMakePackage, CudaPackage):
"components in a single shared library",
)
variant(
+ "link_llvm_dylib",
+ default=False,
+ description="Link LLVM tools against the LLVM shared library",
+ )
+ variant(
"all_targets",
default=False,
description="Build all supported targets, default targets "
@@ -112,6 +125,11 @@ class LlvmDoe(CMakePackage, CudaPackage):
description="Build with OpenMP capable thread sanitizer",
)
variant(
+ "omp_as_runtime",
+ default=True,
+ description="Build OpenMP runtime via ENABLE_RUNTIME by just-built Clang",
+ )
+ variant(
"argobots",
default=False,
description="Build BOLT/OpenMP with Argobots. Effective when @bolt",
@@ -120,16 +138,21 @@ class LlvmDoe(CMakePackage, CudaPackage):
description="Enable code-signing on macOS")
variant("python", default=False, description="Install python bindings")
+ variant('version_suffix', default='none', description="Add a symbol suffix")
+ variant('z3', default=False, description='Use Z3 for the clang static analyzer')
+
extends("python", when="+python")
# Build dependency
depends_on("cmake@3.4.3:", type="build")
+ depends_on('cmake@3.13.4:', type='build', when='@12:')
+ depends_on("ninja", type="build")
depends_on("python", when="~python", type="build")
depends_on("pkgconfig", type="build")
# Universal dependency
depends_on("python", when="+python")
- depends_on("z3")
+ depends_on("z3", when='+clang+z3')
# openmp dependencies
depends_on("perl-data-dumper", type=("build"))
@@ -146,22 +169,56 @@ class LlvmDoe(CMakePackage, CudaPackage):
depends_on("py-six", when="+lldb +python")
# gold support, required for some features
- depends_on("binutils+gold", when="+gold")
+ depends_on("binutils+gold+ld+plugins", when="+gold")
conflicts("+llvm_dylib", when="+shared_libs")
+ conflicts("+link_llvm_dylib", when="~llvm_dylib")
conflicts("+lldb", when="~clang")
conflicts("+libcxx", when="~clang")
conflicts("+internal_unwind", when="~clang")
conflicts("+compiler-rt", when="~clang")
+ conflicts("+flang", when="~clang")
- conflicts("%gcc@:5.0")
+ conflicts('~mlir', when='+flang', msg='Flang requires MLIR')
+
+ # Older LLVM do not build with newer compilers, and vice versa
+ conflicts("%gcc@8:", when="@:5")
+ conflicts("%gcc@:5.0", when="@8:")
+ # clang/lib: a lambda parameter cannot shadow an explicitly captured entity
+ conflicts("%clang@8:", when="@:4")
+
+ # When these versions are concretized, but not explicitly with +libcxx, these
+ # conflicts will enable clingo to set ~libcxx, making the build successful:
+
+ # libc++ of LLVM13, see https://libcxx.llvm.org/#platform-and-compiler-support
+ # @13 does not support %gcc@:10 https://bugs.llvm.org/show_bug.cgi?id=51359#c1
+ # GCC 11 - latest stable release per GCC release page
+ # Clang: 11, 12 - latest two stable releases per LLVM release page
+ # AppleClang 12 - latest stable release per Xcode release page
+ conflicts("%gcc@:10", when="@13:+libcxx")
+ conflicts("%clang@:10", when="@13:+libcxx")
+ conflicts("%apple-clang@:11", when="@13:+libcxx")
+
+ # libcxx-4 and compiler-rt-4 fail to build with "newer" clang and gcc versions:
+ conflicts('%gcc@7:', when='@:4+libcxx')
+ conflicts('%clang@6:', when='@:4+libcxx')
+ conflicts('%apple-clang@6:', when='@:4+libcxx')
+ conflicts('%gcc@7:', when='@:4+compiler-rt')
+ conflicts('%clang@6:', when='@:4+compiler-rt')
+ conflicts('%apple-clang@6:', when='@:4+compiler-rt')
+
+ # OMP TSAN exists in > 5.x
+ conflicts("+omp_tsan", when="@:5")
+
+ # OpenMP via ENABLE_RUNTIME restrictions
+ conflicts("+omp_as_runtime", when="~clang", msg="omp_as_runtime requires clang being built.")
+ conflicts("+omp_as_runtime", when="@:11.1", msg="omp_as_runtime works since LLVM 12.")
# cuda_arch value must be specified
conflicts("cuda_arch=none", when="+cuda", msg="A value for cuda_arch must be specified.")
- conflicts("+mlir")
-
- conflicts("+flang", when="~clang")
+ # MLIR exists in > 10.x
+ conflicts("+mlir", when="@:9")
# code signing is only necessary on macOS",
conflicts('+code_signing', when='platform=linux')
@@ -348,8 +405,25 @@ class LlvmDoe(CMakePackage, CudaPackage):
'create this identity.'
)
+ def flag_handler(self, name, flags):
+ if name == 'cxxflags':
+ flags.append(self.compiler.cxx11_flag)
+ return(None, flags, None)
+ elif name == 'ldflags' and self.spec.satisfies('%intel'):
+ flags.append('-shared-intel')
+ return(None, flags, None)
+ return(flags, None, None)
+
def setup_build_environment(self, env):
- env.append_flags("CXXFLAGS", self.compiler.cxx11_flag)
+ """When using %clang, add only its ld.lld-$ver and/or ld.lld to our PATH"""
+ if self.compiler.name in ['clang', 'apple-clang']:
+ for lld in 'ld.lld-{0}'.format(self.compiler.version.version[0]), 'ld.lld':
+ bin = os.path.join(os.path.dirname(self.compiler.cc), lld)
+ sym = os.path.join(self.stage.path, 'ld.lld')
+ if os.path.exists(bin) and not os.path.exists(sym):
+ mkdirp(self.stage.path)
+ os.symlink(bin, sym)
+ env.prepend_path('PATH', self.stage.path)
def setup_run_environment(self, env):
if "+clang" in self.spec:
@@ -363,71 +437,87 @@ class LlvmDoe(CMakePackage, CudaPackage):
def cmake_args(self):
spec = self.spec
+ define = CMakePackage.define
+ from_variant = self.define_from_variant
+
python = spec['python']
cmake_args = [
- "-DLLVM_REQUIRES_RTTI:BOOL=ON",
- "-DLLVM_ENABLE_RTTI:BOOL=ON",
- "-DLLVM_ENABLE_EH:BOOL=ON",
- "-DCLANG_DEFAULT_OPENMP_RUNTIME:STRING=libomp",
- "-DPYTHON_EXECUTABLE:PATH={0}".format(python.command.path),
- "-DLIBOMP_USE_HWLOC:BOOL=ON",
- "-DLIBOMP_HWLOC_INSTALL_DIR={0}".format(spec["hwloc"].prefix),
+ define("LLVM_REQUIRES_RTTI", True),
+ define("LLVM_ENABLE_RTTI", True),
+ define("LLVM_ENABLE_EH", True),
+ define("CLANG_DEFAULT_OPENMP_RUNTIME", "libomp"),
+ define("PYTHON_EXECUTABLE", python.command.path),
+ define("LIBOMP_USE_HWLOC", True),
+ define("LIBOMP_HWLOC_INSTALL_DIR", spec["hwloc"].prefix),
]
- if python.version >= Version("3.0.0"):
- cmake_args.append("-DPython3_EXECUTABLE={0}".format(
- python.command.path))
+ version_suffix = spec.variants['version_suffix'].value
+ if version_suffix != 'none':
+ cmake_args.append(define('LLVM_VERSION_SUFFIX', version_suffix))
+
+ if python.version >= Version("3"):
+ cmake_args.append(define("Python3_EXECUTABLE", python.command.path))
else:
- cmake_args.append("-DPython2_EXECUTABLE={0}".format(
- python.command.path))
+ cmake_args.append(define("Python2_EXECUTABLE", python.command.path))
projects = []
+ runtimes = []
if "+cuda" in spec:
- cmake_args.extend(
- [
- "-DCUDA_TOOLKIT_ROOT_DIR:PATH=" + spec["cuda"].prefix,
- "-DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES={0}".format(
- ",".join(spec.variants["cuda_arch"].value)
- ),
- "-DCLANG_OPENMP_NVPTX_DEFAULT_ARCH=sm_{0}".format(
- spec.variants["cuda_arch"].value[-1]
- ),
- ]
- )
+ cmake_args.extend([
+ define("CUDA_TOOLKIT_ROOT_DIR", spec["cuda"].prefix),
+ define("LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES",
+ ",".join(spec.variants["cuda_arch"].value)),
+ define("CLANG_OPENMP_NVPTX_DEFAULT_ARCH",
+ "sm_{0}".format(spec.variants["cuda_arch"].value[-1])),
+ ])
+ if "+omp_as_runtime" in spec:
+ cmake_args.extend([
+ define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
+ # work around bad libelf detection in libomptarget
+ define("LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR",
+ spec["libelf"].prefix.include),
+ ])
else:
# still build libomptarget but disable cuda
- cmake_args.extend(
- [
- "-DCUDA_TOOLKIT_ROOT_DIR:PATH=IGNORE",
- "-DCUDA_SDK_ROOT_DIR:PATH=IGNORE",
- "-DCUDA_NVCC_EXECUTABLE:FILEPATH=IGNORE",
- "-DLIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES:STRING=IGNORE",
- ]
- )
-
- if "+omp_debug" in spec:
- cmake_args.append("-DLIBOMPTARGET_ENABLE_DEBUG:Bool=ON")
+ cmake_args.extend([
+ define("CUDA_TOOLKIT_ROOT_DIR", "IGNORE"),
+ define("CUDA_SDK_ROOT_DIR", "IGNORE"),
+ define("CUDA_NVCC_EXECUTABLE", "IGNORE"),
+ define("LIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES", "IGNORE"),
+ ])
- if "+python" in spec and "+lldb" in spec:
- cmake_args.append("-DLLDB_USE_SYSTEM_SIX:Bool=TRUE")
+ cmake_args.append(from_variant("LIBOMPTARGET_ENABLE_DEBUG", "omp_debug"))
- if "+lldb" in spec and spec.satisfies("@10.0.0:,doe"):
- cmake_args.append("-DLLDB_ENABLE_PYTHON:Bool={0}".format(
- 'ON' if '+python' in spec else 'OFF'))
- if "+lldb" in spec and spec.satisfies("@:9.9.9"):
- cmake_args.append("-DLLDB_DISABLE_PYTHON:Bool={0}".format(
- 'ON' if '~python' in spec else 'OFF'))
+ if "+lldb" in spec:
+ if spec.version >= Version('10'):
+ cmake_args.append(from_variant("LLDB_ENABLE_PYTHON", 'python'))
+ else:
+ cmake_args.append(define("LLDB_DISABLE_PYTHON",
+ '~python' in spec))
+ if spec.satisfies("@5.0.0: +python"):
+ cmake_args.append(define("LLDB_USE_SYSTEM_SIX", True))
if "+gold" in spec:
cmake_args.append(
- "-DLLVM_BINUTILS_INCDIR=" + spec["binutils"].prefix.include
+ define("LLVM_BINUTILS_INCDIR", spec["binutils"].prefix.include)
)
if "+clang" in spec:
projects.append("clang")
projects.append("clang-tools-extra")
- projects.append("openmp")
+ if "+omp_as_runtime" in spec:
+ runtimes.append("openmp")
+ else:
+ projects.append("openmp")
+
+ if self.spec.satisfies("@8"):
+ cmake_args.append(define('CLANG_ANALYZER_ENABLE_Z3_SOLVER',
+ self.spec.satisfies('@8+z3')))
+ if self.spec.satisfies("@9:"):
+ cmake_args.append(define('LLVM_ENABLE_Z3_SOLVER',
+ self.spec.satisfies('@9:+z3')))
+
if "+flang" in spec:
projects.append("flang")
if "+lldb" in spec:
@@ -439,53 +529,48 @@ class LlvmDoe(CMakePackage, CudaPackage):
if "+libcxx" in spec:
projects.append("libcxx")
projects.append("libcxxabi")
- cmake_args.append("-DCLANG_DEFAULT_CXX_STDLIB=libc++")
if "+mlir" in spec:
projects.append("mlir")
if "+internal_unwind" in spec:
projects.append("libunwind")
if "+polly" in spec:
projects.append("polly")
- cmake_args.append("-DLINK_POLLY_INTO_TOOLS:Bool=ON")
-
- if "+shared_libs" in spec:
- cmake_args.append("-DBUILD_SHARED_LIBS:Bool=ON")
- if "+llvm_dylib" in spec:
- cmake_args.append("-DLLVM_BUILD_LLVM_DYLIB:Bool=ON")
- if "+omp_debug" in spec:
- cmake_args.append("-DLIBOMPTARGET_ENABLE_DEBUG:Bool=ON")
-
- if "+split_dwarf" in spec:
- cmake_args.append("-DLLVM_USE_SPLIT_DWARF:Bool=ON")
+ cmake_args.append(define("LINK_POLLY_INTO_TOOLS", True))
+
+ cmake_args.extend([
+ from_variant("BUILD_SHARED_LIBS", "shared_libs"),
+ from_variant("LLVM_BUILD_LLVM_DYLIB", "llvm_dylib"),
+ from_variant("LLVM_LINK_LLVM_DYLIB", "link_llvm_dylib"),
+ from_variant("LLVM_USE_SPLIT_DWARF", "split_dwarf"),
+ # By default on Linux, libc++.so is a ldscript. CMake fails to add
+ # CMAKE_INSTALL_RPATH to it, which fails. Statically link libc++abi.a
+ # into libc++.so, linking with -lc++ or -stdlib=libc++ is enough.
+ define('LIBCXX_ENABLE_STATIC_ABI_LIBRARY', True)
+ ])
if "+all_targets" not in spec: # all is default on cmake
targets = ["NVPTX", "AMDGPU"]
- if spec.target.family == "x86" or spec.target.family == "x86_64":
+ if spec.version < Version("3.9.0"):
+ # Starting in 3.9.0 CppBackend is no longer a target (see
+ # LLVM_ALL_TARGETS in llvm's top-level CMakeLists.txt for
+ # the complete list of targets)
+ targets.append("CppBackend")
+
+ if spec.target.family in ("x86", "x86_64"):
targets.append("X86")
elif spec.target.family == "arm":
targets.append("ARM")
elif spec.target.family == "aarch64":
targets.append("AArch64")
- elif (
- spec.target.family == "sparc"
- or spec.target.family == "sparc64"
- ):
+ elif spec.target.family in ("sparc", "sparc64"):
targets.append("Sparc")
- elif (
- spec.target.family == "ppc64"
- or spec.target.family == "ppc64le"
- or spec.target.family == "ppc"
- or spec.target.family == "ppcle"
- ):
+ elif spec.target.family in ("ppc64", "ppc64le", "ppc", "ppcle"):
targets.append("PowerPC")
- cmake_args.append(
- "-DLLVM_TARGETS_TO_BUILD:STRING=" + ";".join(targets)
- )
+ cmake_args.append(define("LLVM_TARGETS_TO_BUILD", targets))
- if "+omp_tsan" in spec:
- cmake_args.append("-DLIBOMP_TSAN_SUPPORT=ON")
+ cmake_args.append(from_variant("LIBOMP_TSAN_SUPPORT", "omp_tsan"))
if spec.satisfies("@bolt"):
projects.remove("openmp")
@@ -495,64 +580,64 @@ class LlvmDoe(CMakePackage, CudaPackage):
cmake_args.append("-DLIBOMP_USE_ARGOBOTS=ON")
if self.compiler.name == "gcc":
- gcc_prefix = ancestor(self.compiler.cc, 2)
- cmake_args.append("-DGCC_INSTALL_PREFIX=" + gcc_prefix)
+ compiler = Executable(self.compiler.cc)
+ gcc_output = compiler('-print-search-dirs', output=str, error=str)
+
+ for line in gcc_output.splitlines():
+ if line.startswith("install:"):
+ # Get path and strip any whitespace
+ # (causes oddity with ancestor)
+ gcc_prefix = line.split(":")[1].strip()
+ gcc_prefix = ancestor(gcc_prefix, 4)
+ break
+ cmake_args.append(define("GCC_INSTALL_PREFIX", gcc_prefix))
- if spec.satisfies("platform=cray") or spec.satisfies("platform=linux"):
- cmake_args.append("-DCMAKE_BUILD_WITH_INSTALL_RPATH=1")
+ # if spec.satisfies("platform=cray") or spec.satisfies("platform=linux"):
+ # cmake_args.append("-DCMAKE_BUILD_WITH_INSTALL_RPATH=1")
if self.spec.satisfies("~code_signing platform=darwin"):
- cmake_args.append('-DLLDB_USE_SYSTEM_DEBUGSERVER=ON')
+ cmake_args.append(define('LLDB_USE_SYSTEM_DEBUGSERVER', True))
# Semicolon seperated list of projects to enable
- cmake_args.append(
- "-DLLVM_ENABLE_PROJECTS:STRING={0}".format(";".join(projects))
- )
+ cmake_args.append(define("LLVM_ENABLE_PROJECTS", projects))
- return cmake_args
+ # Semicolon seperated list of runtimes to enable
+ if runtimes:
+ cmake_args.append(define("LLVM_ENABLE_RUNTIMES", runtimes))
- @run_before("build")
- def pre_install(self):
- with working_dir(self.build_directory):
- # When building shared libraries these need to be installed first
- make("install-LLVMTableGen")
- make("install-LLVMDemangle")
- make("install-LLVMSupport")
+ return cmake_args
@run_after("install")
def post_install(self):
spec = self.spec
+ define = CMakePackage.define
- # unnecessary if we get bootstrap builds in here
- if "+cuda" in self.spec:
+ # unnecessary if we build openmp via LLVM_ENABLE_RUNTIMES
+ if "+cuda ~omp_as_runtime" in self.spec:
ompdir = "build-bootstrapped-omp"
+ prefix_paths = spack.build_environment.get_cmake_prefix_path(self)
+ prefix_paths.append(str(spec.prefix))
# rebuild libomptarget to get bytecode runtime library files
with working_dir(ompdir, create=True):
cmake_args = [
- self.stage.source_path + "/openmp",
- "-DCMAKE_C_COMPILER:PATH={0}".format(
- spec.prefix.bin + "/clang"
- ),
- "-DCMAKE_CXX_COMPILER:PATH={0}".format(
- spec.prefix.bin + "/clang++"
- ),
- "-DCMAKE_INSTALL_PREFIX:PATH={0}".format(spec.prefix),
+ '-G', 'Ninja',
+ define('CMAKE_BUILD_TYPE', spec.variants['build_type'].value),
+ define("CMAKE_C_COMPILER", spec.prefix.bin + "/clang"),
+ define("CMAKE_CXX_COMPILER", spec.prefix.bin + "/clang++"),
+ define("CMAKE_INSTALL_PREFIX", spec.prefix),
+ define('CMAKE_PREFIX_PATH', prefix_paths)
]
cmake_args.extend(self.cmake_args())
- cmake_args.append(
- "-DLIBOMPTARGET_NVPTX_ENABLE_BCLIB:BOOL=TRUE"
- )
-
- # work around bad libelf detection in libomptarget
- cmake_args.append(
- "-DLIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR:String={0}".format(
- spec["libelf"].prefix.include
- )
- )
+ cmake_args.extend([
+ define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
+ define("LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR",
+ spec["libelf"].prefix.include),
+ self.stage.source_path + "/openmp",
+ ])
cmake(*cmake_args)
- make()
- make("install")
+ ninja()
+ ninja("install")
if "+python" in self.spec:
install_tree("llvm/bindings/python", site_packages_dir)