diff --git a/.github/bazel_version.json b/.github/bazel_version.json index 2ada6a5b..0fcae114 100644 --- a/.github/bazel_version.json +++ b/.github/bazel_version.json @@ -1,4 +1,5 @@ [ - "6.5.0" + "6.5.0", + "7.7.0" ] diff --git a/.github/workflows/foss.yaml b/.github/workflows/foss.yaml index 8dbf76f3..8463e740 100644 --- a/.github/workflows/foss.yaml +++ b/.github/workflows/foss.yaml @@ -66,7 +66,9 @@ jobs: foss_rhel_test: name: "Test rules on FOSS projects Bazel ${{ matrix.bazel_version }} (RHEL)" runs-on: ubuntu-24.04 - container: redhat/ubi9:latest + container: + image: redhat/ubi9:latest + options: --init needs: load_versions strategy: fail-fast: false diff --git a/.github/workflows/unit_test.yaml b/.github/workflows/unit_test.yaml index 40e28e8e..c3fbfd96 100644 --- a/.github/workflows/unit_test.yaml +++ b/.github/workflows/unit_test.yaml @@ -76,7 +76,9 @@ jobs: rhel9_test: name: "Unit tests: Bazel ${{ matrix.bazel_version }} (RHEL9)" runs-on: ubuntu-24.04 - container: redhat/ubi9:latest + container: + image: redhat/ubi9:latest + options: --init needs: load_versions strategy: fail-fast: false diff --git a/README.md b/README.md index 5b43d346..c55acf7d 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Prerequisites We need the following tools: - Git 2 or newer (we use 2.36) -- Bazel 6, not yet bazel 7 (we recommend version 6.5.0) +- Bazel 6 or 7, not yet bazel 8 (we recommend version 7.7.0) - Clang 16 or newer (we use 16), we use clang-tidy - Python 3.8 or newer (we use 3.11) - CodeChecker 6.26 or newer (we use 6.26.0) @@ -100,13 +100,13 @@ pip3 install codechecker ``` Install Bazel: -We recommend bazel 6.5.0 +We recommend bazel 7.7.0 ```bash -wget https://github.com/bazelbuild/bazel/releases/download/6.5.0/bazel-6.5.0-linux-x86_64 && \ -chmod +x bazel-6.5.0-linux-x86_64 && \ -sudo mv bazel-6.5.0-linux-x86_64 /usr/local/bin/bazel +wget https://github.com/bazelbuild/bazel/releases/download/7.7.0/bazel-7.7.0-linux-x86_64 && \ +chmod +x bazel-7.7.0-linux-x86_64 && \ +sudo mv bazel-7.7.0-linux-x86_64 /usr/local/bin/bazel ``` -Or choose a suitable binary for your system from this list: https://github.com/bazelbuild/bazel/releases/tag/6.5.0 +Or choose a suitable binary for your system from this list: https://github.com/bazelbuild/bazel/releases/tag/7.7.0 Alternatively follow the official guide at: https://bazel.build/install > [!CAUTION] diff --git a/src/codechecker.bzl b/src/codechecker.bzl index fc8ee7d2..8819d227 100644 --- a/src/codechecker.bzl +++ b/src/codechecker.bzl @@ -18,6 +18,10 @@ load( "tools.bzl", "warning" ) +load( + "common.bzl", + "old_bazel_attributes", +) load( "@codechecker_bazel//src:codechecker_config.bzl", "get_config_file", @@ -252,10 +256,6 @@ _codechecker_test = rule( cfg = platforms_transition, doc = "List of compilable targets which should be checked.", ), - "_whitelist_function_transition": attr.label( - default = "@bazel_tools//tools/whitelists/function_transition_whitelist", - doc = "needed for transitions", - ), "_compile_commands_filter": attr.label( allow_files = True, executable = True, @@ -287,7 +287,7 @@ _codechecker_test = rule( default = [], doc = "List of analyze command arguments, e.g. --ctu", ), - }, + } | old_bazel_attributes(), outputs = { "compile_commands": "%{name}/compile_commands.json", "codechecker_commands": "%{name}/codechecker_commands.json", @@ -319,7 +319,10 @@ def codechecker_test( name = name, targets = targets, options = analyze, - config = config, + # Bazel 7 recognizes that the per_file_rule does not yet have a + # config attribute, and fails. TODO: uncomment when config files + # are supported in per_file rule + #config = config, tags = tags, **kwargs ) diff --git a/src/common.bzl b/src/common.bzl new file mode 100644 index 00000000..7d2f4f09 --- /dev/null +++ b/src/common.bzl @@ -0,0 +1,37 @@ +# Copyright 2023 Ericsson AB +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Provide a collection of functions used by multiple bzl files. +""" + +load( + "@default_codechecker_tools//:defs.bzl", + "BAZEL_VERSION" +) + +def old_bazel_attributes(): + """ + Returns a map with necessary attributes for the used Bazel version + + In older Bazel versions (e.g. 6) rulesets using transitions + must have the attribute _whitelist_function_transition. + In newer versions (e.g. 7) this is an error. + """ + if BAZEL_VERSION.split(".")[0] in "0123456": + return ({"_whitelist_function_transition": attr.label( + default = "@bazel_tools//tools/whitelists/function_transition_whitelist", + doc = "needed for transitions", + )}) + return {} diff --git a/src/compile_commands.bzl b/src/compile_commands.bzl index 25a78a9c..303c4288 100644 --- a/src/compile_commands.bzl +++ b/src/compile_commands.bzl @@ -39,12 +39,16 @@ load( "CPP_COMPILE_ACTION_NAME", "C_COMPILE_ACTION_NAME", ) - load( "@codechecker_bazel//src:tools.bzl", "source_attr" ) +load( + "@codechecker_bazel//src:common.bzl", + "old_bazel_attributes" +) + SourceFilesInfo = provider( doc = "Source files and corresponding compilation database (or compile commands)", fields = { @@ -432,11 +436,7 @@ _compile_commands = rule( cfg = platforms_transition, doc = "List of compilable targets which should be checked.", ), - "_whitelist_function_transition": attr.label( - default = "@bazel_tools//tools/whitelists/function_transition_whitelist", - doc = "needed for transitions", - ), - }, + } | old_bazel_attributes(), outputs = { "compile_commands": "%{name}/compile_commands.json", }, diff --git a/src/tools.bzl b/src/tools.bzl index 31cc9903..88543402 100644 --- a/src/tools.bzl +++ b/src/tools.bzl @@ -96,6 +96,7 @@ def _codechecker_local_repository_impl(repository_ctx): fail("ERROR! CodeChecker is not detected") defs = "CODECHECKER_BIN_PATH = '{}'\n".format(codechecker_bin_path) + defs += "BAZEL_VERSION = '{}'\n".format(native.bazel_version) repository_ctx.file( repository_ctx.path("defs.bzl"), content = defs, diff --git a/test/unit/external_repository/test_external_repo.py b/test/unit/external_repository/test_external_repo.py index 259e2314..0028bd3c 100644 --- a/test/unit/external_repository/test_external_repo.py +++ b/test/unit/external_repository/test_external_repo.py @@ -30,6 +30,7 @@ class TestImplDepExternalDep(TestBase): __test_path__ = os.path.dirname(os.path.abspath(__file__)) BAZEL_BIN_DIR = os.path.join("bazel-bin") BAZEL_TESTLOGS_DIR = os.path.join("bazel-testlogs") + BAZEL_VERSION = None @final @classmethod @@ -38,19 +39,31 @@ def setUpClass(cls): Copy bazelversion from main, otherwise bazelisk will download the latest bazel version. """ + # The folder bazel-external_repository contains this script + # and the unittest test discovery finds it. + # This is why, it is imperative that these directories get cleared + cls.run_command("bazel clean") super().setUpClass() try: shutil.copy("../../../.bazelversion", ".bazelversion") shutil.copy( "../../../.bazelversion", "third_party/my_lib/.bazelversion") + except: logging.debug("No bazel version set, using system default") + _, stdout, _ = cls.run_command("bazel --version") + cls.BAZEL_VERSION = stdout.split(' ')[2].strip() + logging.debug("Using Bazel", cls.BAZEL_VERSION) @final @classmethod def tearDownClass(cls): """Remove bazelversion from this test""" super().tearDownClass() + # The folder bazel-external_repository contains this script + # and the unittest test discovery finds it. + # This is why, it is imperative that these directories get cleared + cls.run_command("bazel clean") try: os.remove(".bazelversion") except: @@ -71,13 +84,21 @@ def test_compile_commands_external_lib(self): "compile_commands.json") # The ~override part is a consquence of using Bzlmod. + if self.BAZEL_VERSION.startswith("6"): # type: ignore + pattern1 = "-isystem external/external_lib~override/include" + pattern2 = "-isystem " + \ + "bazel-out/k8-fastbuild/bin/external/external_lib~override/include" + else: + pattern1 = "-isystem external/external_lib~/include" + pattern2 = "-isystem " + \ + "bazel-out/k8-fastbuild/bin/external/external_lib~/include" + self.assertTrue(self.contains_regex_in_file( comp_json_file, - "-isystem external/external_lib~override/include")) + pattern1)) self.assertTrue(self.contains_regex_in_file( comp_json_file, - "-isystem " + - "bazel-out/k8-fastbuild/bin/external/external_lib~override/include")) + pattern2)) def test_codechecker_external_lib(self): """Test: bazel build :codechecker_external_deps"""