mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:30:12 +01:00
Modify clang configuration to make llvm-15 work better. (#2186)
The debug flag change is discussed at https://github.com/llvm/llvm-project/issues/57637 This modifies the devcontainer Dockerfile to switch to an ubuntu and apt-based llvm-15. That was used in testing of these changes. The move away from brew is partly necessary if we want llvm-15, but also installs much faster (roughly 90s setup). This was based in part on #1618
This commit is contained in:
+30
-12
@@ -2,19 +2,37 @@
|
||||
# Exceptions. See /LICENSE for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
ARG TAG=3.5.6
|
||||
FROM docker.io/homebrew/brew:${TAG}
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Install libxcrypt using Homebrew.
|
||||
RUN brew install libxcrypt --overwrite
|
||||
# Install apt tools:
|
||||
# git: Used by VS Code.
|
||||
# golang: Used for Bazelisk and Buildifier.
|
||||
# python3: For Carbon tools.
|
||||
# gnupg, software-properties-common, wget: For llvm.sh.
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y \
|
||||
git \
|
||||
gnupg \
|
||||
golang \
|
||||
python3-pip \
|
||||
python3.9 \
|
||||
software-properties-common \
|
||||
wget
|
||||
|
||||
# Install all other dependencies using Homebrew.
|
||||
RUN brew install bazelisk node python@3.9
|
||||
ENV PATH="/root/go/bin:${PATH}"
|
||||
# Bazelisk is used for Carbon builds.
|
||||
RUN go install github.com/bazelbuild/bazelisk@v1.14.0
|
||||
RUN ln -s /root/go/bin/bazelisk /root/go/bin/bazel
|
||||
# Buildifier is used by the Bazel VS Code extension.
|
||||
RUN go install github.com/bazelbuild/buildtools/buildifier@5.1.0
|
||||
|
||||
# Install all python dependencies modules using Pip.
|
||||
# Install LLVM from apt.llvm.org.
|
||||
RUN wget https://apt.llvm.org/llvm.sh
|
||||
RUN chmod +x llvm.sh
|
||||
RUN ./llvm.sh 15 all
|
||||
RUN rm llvm.sh
|
||||
ENV CC="/usr/bin/clang-15"
|
||||
|
||||
# Update pip and install black and pre-commit.
|
||||
RUN pip3 install -U pip
|
||||
RUN pip3 install pre-commit black codespell
|
||||
|
||||
# Install Clang/LLVM using Homebrew.
|
||||
# Many Clang/LLVM releases aren't built with options we rely on.
|
||||
RUN brew install llvm
|
||||
RUN pip3 install black pre-commit
|
||||
|
||||
@@ -20,6 +20,7 @@ load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
|
||||
load(
|
||||
":clang_detected_variables.bzl",
|
||||
"clang_bindir",
|
||||
"clang_version",
|
||||
"clang_include_dirs_list",
|
||||
"clang_resource_dir",
|
||||
"llvm_bindir",
|
||||
@@ -496,6 +497,13 @@ def _impl(ctx):
|
||||
implies = ["fuzzer"],
|
||||
)
|
||||
|
||||
# With clang 14 and lower, we expect it to be built with libc++ debug
|
||||
# support. In later LLVM versions, we expect the assertions define to work.
|
||||
if clang_version and clang_version <= 14:
|
||||
libcpp_debug_flags = ["-D_LIBCPP_DEBUG=1"]
|
||||
else:
|
||||
libcpp_debug_flags = ["-D_LIBCPP_ENABLE_ASSERTIONS=1"]
|
||||
|
||||
linux_flags_feature = feature(
|
||||
name = "linux_flags",
|
||||
enabled = True,
|
||||
@@ -537,10 +545,7 @@ def _impl(ctx):
|
||||
),
|
||||
flag_set(
|
||||
actions = all_compile_actions,
|
||||
flag_groups = [flag_group(flags = [
|
||||
# Enable libc++'s debug features.
|
||||
"-D_LIBCPP_DEBUG=1",
|
||||
])],
|
||||
flag_groups = [flag_group(flags = libcpp_debug_flags)],
|
||||
with_features = [
|
||||
with_feature_set(not_features = ["opt"]),
|
||||
],
|
||||
|
||||
@@ -17,6 +17,27 @@ def _run(repository_ctx, cmd):
|
||||
|
||||
return exec_result
|
||||
|
||||
def _clang_version(version_output):
|
||||
"""Returns clang's major version number, or None if not found."""
|
||||
version_prefix = "clang version "
|
||||
version_start = version_output.find(version_prefix)
|
||||
if version_start == -1:
|
||||
# No version
|
||||
return None
|
||||
version_start += len(version_prefix)
|
||||
|
||||
# Find a dot to indicate something like 'clang version 14.0.6'.
|
||||
version_dot = version_output.find(".", version_start)
|
||||
if version_dot == -1:
|
||||
return None
|
||||
|
||||
# Make sure the dot was on the same line as the version.
|
||||
if version_output.find("\n", version_start) < version_dot:
|
||||
return None
|
||||
|
||||
# Return the version as int.
|
||||
return int(version_output[version_start:version_dot])
|
||||
|
||||
def _detect_system_clang(repository_ctx):
|
||||
"""Detects whether the system-provided clang can be used.
|
||||
|
||||
@@ -38,7 +59,7 @@ def _detect_system_clang(repository_ctx):
|
||||
version_output = _run(repository_ctx, [cc_path, "--version"]).stdout
|
||||
if "clang" not in version_output:
|
||||
fail("Searching for clang or CC (%s), and found (%s), which is not a Clang compiler" % (cc, cc_path))
|
||||
return cc_path
|
||||
return (cc_path, _clang_version(version_output))
|
||||
|
||||
def _compute_clang_resource_dir(repository_ctx, clang):
|
||||
"""Runs the `clang` binary to get its resource dir."""
|
||||
@@ -66,14 +87,14 @@ def _compute_clang_cpp_include_search_paths(repository_ctx, clang, sysroot):
|
||||
|
||||
# Create an empty temp file for Clang to use
|
||||
if repository_ctx.os.name.lower().startswith("windows"):
|
||||
repository_ctx.file('_temp', '')
|
||||
repository_ctx.file("_temp", "")
|
||||
|
||||
# Read in an empty input file. If we are building from
|
||||
# Windows, then we create an empty temp file. Clang
|
||||
# on Windows does not like it when you pass a non-existent file.
|
||||
if repository_ctx.os.name.lower().startswith("windows"):
|
||||
repository_ctx.file('_temp', '')
|
||||
input_file = repository_ctx.path('_temp')
|
||||
repository_ctx.file("_temp", "")
|
||||
input_file = repository_ctx.path("_temp")
|
||||
else:
|
||||
input_file = "/dev/null"
|
||||
|
||||
@@ -131,7 +152,7 @@ def _configure_clang_toolchain_impl(repository_ctx):
|
||||
# here as the other LLVM tools may not be symlinked into the PATH even if
|
||||
# `clang` is. We also insist on finding the basename of `clang++` as that is
|
||||
# important for C vs. C++ compiles.
|
||||
clang = _detect_system_clang(repository_ctx)
|
||||
(clang, clang_version) = _detect_system_clang(repository_ctx)
|
||||
clang = clang.realpath.dirname.get_child("clang++")
|
||||
|
||||
# Compute the various directories used by Clang.
|
||||
@@ -168,6 +189,7 @@ def _configure_clang_toolchain_impl(repository_ctx):
|
||||
substitutions = {
|
||||
"{LLVM_BINDIR}": str(arpath.dirname),
|
||||
"{CLANG_BINDIR}": str(clang.dirname),
|
||||
"{CLANG_VERSION}": str(clang_version),
|
||||
"{CLANG_RESOURCE_DIR}": resource_dir,
|
||||
"{CLANG_INCLUDE_DIRS_LIST}": str(
|
||||
[str(path) for path in include_dirs],
|
||||
|
||||
@@ -10,6 +10,7 @@ This file gets processed by a repository rule, substituting the
|
||||
|
||||
llvm_bindir = "{LLVM_BINDIR}"
|
||||
clang_bindir = "{CLANG_BINDIR}"
|
||||
clang_version = {CLANG_VERSION}
|
||||
clang_resource_dir = "{CLANG_RESOURCE_DIR}"
|
||||
clang_include_dirs_list = {CLANG_INCLUDE_DIRS_LIST}
|
||||
sysroot_dir = "{SYSROOT}"
|
||||
|
||||
Reference in New Issue
Block a user