diff --git a/.github/workflows/pre_commit.yaml b/.github/workflows/pre_commit.yaml index 59137c8e383f..8e598519cc3c 100644 --- a/.github/workflows/pre_commit.yaml +++ b/.github/workflows/pre_commit.yaml @@ -26,6 +26,7 @@ jobs: # prettier-ignore allowed-endpoints: > *.dl.sourceforge.net:443 + api.github.com:443 bcr.bazel.build:443 downloads.sourceforge.net:443 files.pythonhosted.org:443 @@ -40,6 +41,13 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + + # Ensure LLVM is set up consistently. + - uses: ./.github/actions/build-setup-common + with: + matrix_runner: ubuntu-latest + remote_cache_upload: '--remote_upload_local_results=false' + - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 # We want to automatically create github suggestions for pre-commit file diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index ba6b1ebc4cae..aa644d8bf905 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -129,7 +129,7 @@ "moduleExtensions": { "//bazel/cc_toolchains:clang_configuration.bzl%clang_toolchain_extension": { "general": { - "bzlTransitiveDigest": "K2JE5G8tvZ+UBmAPF5s/YSUNg53pTvAZi2ause87buQ=", + "bzlTransitiveDigest": "YfAlFgFWuxAcofKFZTG3JR3DeQD3yED9F1mzTVz6xoA=", "usagesDigest": "FiqDwj5QoiCFb1PRYvajLeyuRjRXbsy2CVC+VsEEt7Q=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, diff --git a/bazel/cc_toolchains/clang_configuration.bzl b/bazel/cc_toolchains/clang_configuration.bzl index 741623848519..4faf003e5ba3 100644 --- a/bazel/cc_toolchains/clang_configuration.bzl +++ b/bazel/cc_toolchains/clang_configuration.bzl @@ -13,7 +13,11 @@ def _run(repository_ctx, cmd): """Runs the provided `cmd`, checks for failure, and returns the result.""" exec_result = repository_ctx.execute(cmd) if exec_result.return_code != 0: - fail("Unable to run command successfully: %s" % str(cmd)) + fail("Command failed with return code {0}: {1}\n{2}".format( + exec_result.return_code, + str(cmd), + exec_result.stderr, + )) return exec_result @@ -100,24 +104,26 @@ def _compute_bsd_sysroot(repository_ctx): return sysroot_path.realpath return default +# File content used when computing search paths. This additionally verifies that +# libc++ is installed. +_CLANG_INCLUDE_FILE_CONTENT = """ +#if __has_include() +#include +#endif +#ifndef _LIBCPP_STD_VER +#error "No libc++ install found!" +#endif +""" + def _compute_clang_cpp_include_search_paths(repository_ctx, clang, sysroot): """Runs the `clang` binary and extracts the include search paths. Returns the resulting paths as a list of strings. """ - # Create an empty temp file for Clang to use - if repository_ctx.os.name.lower().startswith("windows"): - 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") - else: - input_file = "/dev/null" + # Create a file for Clang to use as input. + repository_ctx.file("_temp", _CLANG_INCLUDE_FILE_CONTENT) + input_file = repository_ctx.path("_temp") # The only way to get this out of Clang currently is to parse the verbose # output of the compiler when it is compiling C++ code. @@ -132,7 +138,7 @@ def _compute_clang_cpp_include_search_paths(repository_ctx, clang, sysroot): # Force the language to be C++. "-x", "c++", - # Read in an empty input file. + # Use the input file. input_file, # Always use libc++. "-stdlib=libc++", @@ -176,6 +182,11 @@ def _configure_clang_toolchain_impl(repository_ctx): (clang, clang_version, clang_version_for_cache) = _detect_system_clang( repository_ctx, ) + if clang_version and clang_version < 16: + fail("Found clang {0}. ".format(clang_version) + + "Carbon requires clang >=16. See " + + "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/contribution_tools.md#old-llvm-versions") + clang_cpp = clang.dirname.get_child("clang++") # Compute the various directories used by Clang. diff --git a/docs/project/contribution_tools.md b/docs/project/contribution_tools.md index b0a0d3458526..d0d67b5707b2 100644 --- a/docs/project/contribution_tools.md +++ b/docs/project/contribution_tools.md @@ -24,6 +24,7 @@ contributions. - [Optional tools](#optional-tools) - [Manually building Clang and LLVM (not recommended)](#manually-building-clang-and-llvm-not-recommended) - [Troubleshooting build issues](#troubleshooting-build-issues) + - [`bazel clean`](#bazel-clean) - [Old LLVM versions](#old-llvm-versions) - [Asking for help](#asking-for-help) - [Troubleshooting debug issues](#troubleshooting-debug-issues) @@ -167,10 +168,8 @@ These tools are essential for work on Carbon. outdated, and not be upgraded. - Main tools - [Bazel](https://www.bazel.build/) - - NOTE: See [the bazelisk config](/.bazeliskrc) for a supported - version. - - [Bazelisk](https://docs.bazel.build/versions/master/install-bazelisk.html) - (for macOS): Handles Bazel versions. + - [Bazelisk](https://docs.bazel.build/versions/master/install-bazelisk.html): + Downloads and runs the [configured Bazel version](/.bazeliskrc). - [Clang](https://clang.llvm.org/) and [LLVM](https://llvm.org/) - NOTE: Most LLVM 14+ installs should build Carbon. If you're having issues, see @@ -255,6 +254,12 @@ work reliably include: ## Troubleshooting build issues +### `bazel clean` + +Changes to packages installed on your system may not be noticed by `bazel`. This +includes things such as changing LLVM versions, or installing libc++. Running +`bazel clean` should force cached state to be rebuilt. + ### Old LLVM versions Many build issues result from the particular options `clang` and `llvm` have @@ -266,8 +271,7 @@ System installs of macOS typically won't work, for example being an old LLVM version or missing llvm-ar; [setup commands](#setup-commands) includes LLVM from Homebrew for this reason. -It may be necessary to run `bazel clean` after updating versions in order to -clean up cached state. +Run [`bazel clean`](#bazel-clean) when changing the installed LLVM version. ### Asking for help @@ -280,7 +284,7 @@ echo $CC which clang which clang-16 clang --version -grep llvm_bindir $(bazel info workspace)/bazel-execroot/external/bazel_cc_toolchain/clang_detected_variables.bzl +grep llvm_bindir $(bazel info workspace)/bazel-execroot/external/_main\~clang_toolchain_extension\~bazel_cc_toolchain/clang_detected_variables.bzl # If on macOS: brew --prefix llvm