llvm-doe: incorporate updates to official llvm Spack package (#27866)

* llvm-doe: incorporate select configurations from llvm package

* add newline at end of file
This commit is contained in:
eugeneswalker 2021-12-08 16:21:11 -08:00 committed by GitHub
parent b9a2e71a8b
commit c930f871f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,12 +2,14 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import os.path import os.path
import re import re
import sys import sys
import llnl.util.tty as tty import llnl.util.tty as tty
import spack.build_environment
import spack.util.executable 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" url = "https://github.com/llvm-doe-org/llvm-project/archive/llvmorg-10.0.0.zip"
git = "https://github.com/llvm-doe-org/llvm-project" git = "https://github.com/llvm-doe-org/llvm-project"
maintainers = ['shintaro-iwasaki'] maintainers = ['shintaro-iwasaki']
tags = ['e4s'] tags = ['e4s']
generator = 'Ninja'
family = "compiler" # Used by lmod
version('doe', branch='doe', preferred=True) version('doe', branch='doe', preferred=True)
version('upstream', branch='llvm.org/main') version('upstream', branch='llvm.org/main')
version('bolt', branch='bolt/main') version('bolt', branch='bolt/main')
version('clacc', branch='clacc/master') version('clacc', branch='clacc/master')
version('pragma-clang-loop', branch='sollve/pragma-clang-loop') version('pragma-clang-loop', branch='sollve/pragma-clang-loop')
version('pragma-omp-tile', branch='sollve/pragma-omp-tile') 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 # 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 # the release version, and may take up 20-30 GB of space. If you want
@ -94,6 +102,11 @@ class LlvmDoe(CMakePackage, CudaPackage):
description="Build LLVM shared library, containing all " description="Build LLVM shared library, containing all "
"components in a single shared library", "components in a single shared library",
) )
variant(
"link_llvm_dylib",
default=False,
description="Link LLVM tools against the LLVM shared library",
)
variant( variant(
"all_targets", "all_targets",
default=False, default=False,
@ -111,6 +124,11 @@ class LlvmDoe(CMakePackage, CudaPackage):
default=False, default=False,
description="Build with OpenMP capable thread sanitizer", 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( variant(
"argobots", "argobots",
default=False, default=False,
@ -120,16 +138,21 @@ class LlvmDoe(CMakePackage, CudaPackage):
description="Enable code-signing on macOS") description="Enable code-signing on macOS")
variant("python", default=False, description="Install python bindings") 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") extends("python", when="+python")
# Build dependency # Build dependency
depends_on("cmake@3.4.3:", type="build") 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("python", when="~python", type="build")
depends_on("pkgconfig", type="build") depends_on("pkgconfig", type="build")
# Universal dependency # Universal dependency
depends_on("python", when="+python") depends_on("python", when="+python")
depends_on("z3") depends_on("z3", when='+clang+z3')
# openmp dependencies # openmp dependencies
depends_on("perl-data-dumper", type=("build")) depends_on("perl-data-dumper", type=("build"))
@ -146,22 +169,56 @@ class LlvmDoe(CMakePackage, CudaPackage):
depends_on("py-six", when="+lldb +python") depends_on("py-six", when="+lldb +python")
# gold support, required for some features # 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("+llvm_dylib", when="+shared_libs")
conflicts("+link_llvm_dylib", when="~llvm_dylib")
conflicts("+lldb", when="~clang") conflicts("+lldb", when="~clang")
conflicts("+libcxx", when="~clang") conflicts("+libcxx", when="~clang")
conflicts("+internal_unwind", when="~clang") conflicts("+internal_unwind", when="~clang")
conflicts("+compiler-rt", 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 # cuda_arch value must be specified
conflicts("cuda_arch=none", when="+cuda", msg="A value for cuda_arch must be specified.") conflicts("cuda_arch=none", when="+cuda", msg="A value for cuda_arch must be specified.")
conflicts("+mlir") # MLIR exists in > 10.x
conflicts("+mlir", when="@:9")
conflicts("+flang", when="~clang")
# code signing is only necessary on macOS", # code signing is only necessary on macOS",
conflicts('+code_signing', when='platform=linux') conflicts('+code_signing', when='platform=linux')
@ -348,8 +405,25 @@ def codesign_check(self):
'create this identity.' '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): 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): def setup_run_environment(self, env):
if "+clang" in self.spec: if "+clang" in self.spec:
@ -363,71 +437,87 @@ def setup_run_environment(self, env):
def cmake_args(self): def cmake_args(self):
spec = self.spec spec = self.spec
define = CMakePackage.define
from_variant = self.define_from_variant
python = spec['python'] python = spec['python']
cmake_args = [ cmake_args = [
"-DLLVM_REQUIRES_RTTI:BOOL=ON", define("LLVM_REQUIRES_RTTI", True),
"-DLLVM_ENABLE_RTTI:BOOL=ON", define("LLVM_ENABLE_RTTI", True),
"-DLLVM_ENABLE_EH:BOOL=ON", define("LLVM_ENABLE_EH", True),
"-DCLANG_DEFAULT_OPENMP_RUNTIME:STRING=libomp", define("CLANG_DEFAULT_OPENMP_RUNTIME", "libomp"),
"-DPYTHON_EXECUTABLE:PATH={0}".format(python.command.path), define("PYTHON_EXECUTABLE", python.command.path),
"-DLIBOMP_USE_HWLOC:BOOL=ON", define("LIBOMP_USE_HWLOC", True),
"-DLIBOMP_HWLOC_INSTALL_DIR={0}".format(spec["hwloc"].prefix), define("LIBOMP_HWLOC_INSTALL_DIR", spec["hwloc"].prefix),
] ]
if python.version >= Version("3.0.0"): version_suffix = spec.variants['version_suffix'].value
cmake_args.append("-DPython3_EXECUTABLE={0}".format( if version_suffix != 'none':
python.command.path)) cmake_args.append(define('LLVM_VERSION_SUFFIX', version_suffix))
if python.version >= Version("3"):
cmake_args.append(define("Python3_EXECUTABLE", python.command.path))
else: else:
cmake_args.append("-DPython2_EXECUTABLE={0}".format( cmake_args.append(define("Python2_EXECUTABLE", python.command.path))
python.command.path))
projects = [] projects = []
runtimes = []
if "+cuda" in spec: if "+cuda" in spec:
cmake_args.extend( cmake_args.extend([
[ define("CUDA_TOOLKIT_ROOT_DIR", spec["cuda"].prefix),
"-DCUDA_TOOLKIT_ROOT_DIR:PATH=" + spec["cuda"].prefix, define("LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES",
"-DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES={0}".format( ",".join(spec.variants["cuda_arch"].value)),
",".join(spec.variants["cuda_arch"].value) define("CLANG_OPENMP_NVPTX_DEFAULT_ARCH",
), "sm_{0}".format(spec.variants["cuda_arch"].value[-1])),
"-DCLANG_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: else:
# still build libomptarget but disable cuda # still build libomptarget but disable cuda
cmake_args.extend( cmake_args.extend([
[ define("CUDA_TOOLKIT_ROOT_DIR", "IGNORE"),
"-DCUDA_TOOLKIT_ROOT_DIR:PATH=IGNORE", define("CUDA_SDK_ROOT_DIR", "IGNORE"),
"-DCUDA_SDK_ROOT_DIR:PATH=IGNORE", define("CUDA_NVCC_EXECUTABLE", "IGNORE"),
"-DCUDA_NVCC_EXECUTABLE:FILEPATH=IGNORE", define("LIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES", "IGNORE"),
"-DLIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES:STRING=IGNORE", ])
]
)
if "+omp_debug" in spec: cmake_args.append(from_variant("LIBOMPTARGET_ENABLE_DEBUG", "omp_debug"))
cmake_args.append("-DLIBOMPTARGET_ENABLE_DEBUG:Bool=ON")
if "+python" in spec and "+lldb" in spec: if "+lldb" in spec:
cmake_args.append("-DLLDB_USE_SYSTEM_SIX:Bool=TRUE") if spec.version >= Version('10'):
cmake_args.append(from_variant("LLDB_ENABLE_PYTHON", 'python'))
if "+lldb" in spec and spec.satisfies("@10.0.0:,doe"): else:
cmake_args.append("-DLLDB_ENABLE_PYTHON:Bool={0}".format( cmake_args.append(define("LLDB_DISABLE_PYTHON",
'ON' if '+python' in spec else 'OFF')) '~python' in spec))
if "+lldb" in spec and spec.satisfies("@:9.9.9"): if spec.satisfies("@5.0.0: +python"):
cmake_args.append("-DLLDB_DISABLE_PYTHON:Bool={0}".format( cmake_args.append(define("LLDB_USE_SYSTEM_SIX", True))
'ON' if '~python' in spec else 'OFF'))
if "+gold" in spec: if "+gold" in spec:
cmake_args.append( cmake_args.append(
"-DLLVM_BINUTILS_INCDIR=" + spec["binutils"].prefix.include define("LLVM_BINUTILS_INCDIR", spec["binutils"].prefix.include)
) )
if "+clang" in spec: if "+clang" in spec:
projects.append("clang") projects.append("clang")
projects.append("clang-tools-extra") 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: if "+flang" in spec:
projects.append("flang") projects.append("flang")
if "+lldb" in spec: if "+lldb" in spec:
@ -439,53 +529,48 @@ def cmake_args(self):
if "+libcxx" in spec: if "+libcxx" in spec:
projects.append("libcxx") projects.append("libcxx")
projects.append("libcxxabi") projects.append("libcxxabi")
cmake_args.append("-DCLANG_DEFAULT_CXX_STDLIB=libc++")
if "+mlir" in spec: if "+mlir" in spec:
projects.append("mlir") projects.append("mlir")
if "+internal_unwind" in spec: if "+internal_unwind" in spec:
projects.append("libunwind") projects.append("libunwind")
if "+polly" in spec: if "+polly" in spec:
projects.append("polly") projects.append("polly")
cmake_args.append("-DLINK_POLLY_INTO_TOOLS:Bool=ON") cmake_args.append(define("LINK_POLLY_INTO_TOOLS", True))
if "+shared_libs" in spec: cmake_args.extend([
cmake_args.append("-DBUILD_SHARED_LIBS:Bool=ON") from_variant("BUILD_SHARED_LIBS", "shared_libs"),
if "+llvm_dylib" in spec: from_variant("LLVM_BUILD_LLVM_DYLIB", "llvm_dylib"),
cmake_args.append("-DLLVM_BUILD_LLVM_DYLIB:Bool=ON") from_variant("LLVM_LINK_LLVM_DYLIB", "link_llvm_dylib"),
if "+omp_debug" in spec: from_variant("LLVM_USE_SPLIT_DWARF", "split_dwarf"),
cmake_args.append("-DLIBOMPTARGET_ENABLE_DEBUG:Bool=ON") # 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
if "+split_dwarf" in spec: # into libc++.so, linking with -lc++ or -stdlib=libc++ is enough.
cmake_args.append("-DLLVM_USE_SPLIT_DWARF:Bool=ON") define('LIBCXX_ENABLE_STATIC_ABI_LIBRARY', True)
])
if "+all_targets" not in spec: # all is default on cmake if "+all_targets" not in spec: # all is default on cmake
targets = ["NVPTX", "AMDGPU"] 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") targets.append("X86")
elif spec.target.family == "arm": elif spec.target.family == "arm":
targets.append("ARM") targets.append("ARM")
elif spec.target.family == "aarch64": elif spec.target.family == "aarch64":
targets.append("AArch64") targets.append("AArch64")
elif ( elif spec.target.family in ("sparc", "sparc64"):
spec.target.family == "sparc"
or spec.target.family == "sparc64"
):
targets.append("Sparc") targets.append("Sparc")
elif ( elif spec.target.family in ("ppc64", "ppc64le", "ppc", "ppcle"):
spec.target.family == "ppc64"
or spec.target.family == "ppc64le"
or spec.target.family == "ppc"
or spec.target.family == "ppcle"
):
targets.append("PowerPC") targets.append("PowerPC")
cmake_args.append( cmake_args.append(define("LLVM_TARGETS_TO_BUILD", targets))
"-DLLVM_TARGETS_TO_BUILD:STRING=" + ";".join(targets)
)
if "+omp_tsan" in spec: cmake_args.append(from_variant("LIBOMP_TSAN_SUPPORT", "omp_tsan"))
cmake_args.append("-DLIBOMP_TSAN_SUPPORT=ON")
if spec.satisfies("@bolt"): if spec.satisfies("@bolt"):
projects.remove("openmp") projects.remove("openmp")
@ -495,64 +580,64 @@ def cmake_args(self):
cmake_args.append("-DLIBOMP_USE_ARGOBOTS=ON") cmake_args.append("-DLIBOMP_USE_ARGOBOTS=ON")
if self.compiler.name == "gcc": if self.compiler.name == "gcc":
gcc_prefix = ancestor(self.compiler.cc, 2) compiler = Executable(self.compiler.cc)
cmake_args.append("-DGCC_INSTALL_PREFIX=" + gcc_prefix) gcc_output = compiler('-print-search-dirs', output=str, error=str)
if spec.satisfies("platform=cray") or spec.satisfies("platform=linux"): for line in gcc_output.splitlines():
cmake_args.append("-DCMAKE_BUILD_WITH_INSTALL_RPATH=1") 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 self.spec.satisfies("~code_signing platform=darwin"): 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 # Semicolon seperated list of projects to enable
cmake_args.append( cmake_args.append(define("LLVM_ENABLE_PROJECTS", projects))
"-DLLVM_ENABLE_PROJECTS:STRING={0}".format(";".join(projects))
) # Semicolon seperated list of runtimes to enable
if runtimes:
cmake_args.append(define("LLVM_ENABLE_RUNTIMES", runtimes))
return cmake_args return cmake_args
@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")
@run_after("install") @run_after("install")
def post_install(self): def post_install(self):
spec = self.spec spec = self.spec
define = CMakePackage.define
# unnecessary if we get bootstrap builds in here # unnecessary if we build openmp via LLVM_ENABLE_RUNTIMES
if "+cuda" in self.spec: if "+cuda ~omp_as_runtime" in self.spec:
ompdir = "build-bootstrapped-omp" 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 # rebuild libomptarget to get bytecode runtime library files
with working_dir(ompdir, create=True): with working_dir(ompdir, create=True):
cmake_args = [ cmake_args = [
self.stage.source_path + "/openmp", '-G', 'Ninja',
"-DCMAKE_C_COMPILER:PATH={0}".format( define('CMAKE_BUILD_TYPE', spec.variants['build_type'].value),
spec.prefix.bin + "/clang" define("CMAKE_C_COMPILER", spec.prefix.bin + "/clang"),
), define("CMAKE_CXX_COMPILER", spec.prefix.bin + "/clang++"),
"-DCMAKE_CXX_COMPILER:PATH={0}".format( define("CMAKE_INSTALL_PREFIX", spec.prefix),
spec.prefix.bin + "/clang++" define('CMAKE_PREFIX_PATH', prefix_paths)
),
"-DCMAKE_INSTALL_PREFIX:PATH={0}".format(spec.prefix),
] ]
cmake_args.extend(self.cmake_args()) cmake_args.extend(self.cmake_args())
cmake_args.append( cmake_args.extend([
"-DLIBOMPTARGET_NVPTX_ENABLE_BCLIB:BOOL=TRUE" define("LIBOMPTARGET_NVPTX_ENABLE_BCLIB", True),
) define("LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR",
spec["libelf"].prefix.include),
# work around bad libelf detection in libomptarget self.stage.source_path + "/openmp",
cmake_args.append( ])
"-DLIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR:String={0}".format(
spec["libelf"].prefix.include
)
)
cmake(*cmake_args) cmake(*cmake_args)
make() ninja()
make("install") ninja("install")
if "+python" in self.spec: if "+python" in self.spec:
install_tree("llvm/bindings/python", site_packages_dir) install_tree("llvm/bindings/python", site_packages_dir)