| # Copyright 2026 The Pigweed Authors |
| # |
| # 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 |
| # |
| # https://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. |
| """Generate BUILD.bazel files for samples and tests directories using CMake parser.""" |
| |
| import argparse |
| import os |
| from pathlib import Path |
| import subprocess |
| import sys |
| |
| # Add current directory to path to import local modules |
| sys.path.append(str(Path(__file__).resolve().parent)) |
| import app_cmake_to_bazel |
| from bazel_utils import get_bazel_package_prefix, run_buildozer |
| import cmake_converter_common as common |
| |
| |
| def create_build_files(zephyr_root, output_root): |
| """Finds all subdirectories under zephyr_root/samples/ containing a |
| sample.yaml file, and all subdirectories under zephyr_root/tests/ |
| containing a testcase.yaml file, and generates a BUILD.bazel file |
| in the corresponding directory in output_root. |
| """ |
| zephyr_root = Path(zephyr_root).resolve() |
| output_root = Path(output_root).resolve() |
| |
| def process_dir(sub_dir_name, marker_file): |
| target_root = zephyr_root / sub_dir_name |
| if not target_root.exists(): |
| print(f'Warning: {target_root} does not exist.') |
| return |
| |
| is_test = sub_dir_name == 'tests' |
| |
| for root, _, files in os.walk(target_root): |
| if marker_file in files: |
| current_path = Path(root) |
| cmake_file = current_path / 'CMakeLists.txt' |
| |
| if not cmake_file.exists(): |
| # Some directories might have yaml but no CMakeLists.txt |
| continue |
| |
| relative_path = current_path.relative_to(zephyr_root) |
| output_dir = output_root / relative_path |
| output_dir.mkdir(parents=True, exist_ok=True) |
| output_file = output_dir / 'BUILD.bazel' |
| |
| print(f'Converting {cmake_file} to {output_file}...') |
| |
| with open(cmake_file, 'r', encoding='utf-8') as f: |
| cmake_content = f.read() |
| |
| target_name = current_path.name |
| target_name = target_name.replace('-', '_').replace('.', '_') |
| |
| path_transformer = common.get_path_transformer(current_path) |
| bazel_content = app_cmake_to_bazel.convert_cmakelists_to_bazel( |
| cmake_content, |
| target_name, |
| current_path, |
| path_transformer=path_transformer, |
| is_test=is_test, |
| ) |
| |
| try: |
| with open(output_file, 'w', encoding='utf-8') as f: |
| f.write(bazel_content) |
| except IOError as e: |
| print(f'Error: Could not write to {output_file}. {e}') |
| continue |
| |
| try: |
| subprocess.run( |
| ['buildifier', str(output_file)], |
| check=True, |
| stdout=subprocess.DEVNULL, |
| stderr=subprocess.DEVNULL, |
| ) |
| except subprocess.CalledProcessError: |
| print(f'Warning: failed to run buildifier on {output_file}') |
| except FileNotFoundError: |
| pass |
| |
| process_dir('samples', 'sample.yaml') |
| process_dir('tests', 'testcase.yaml') |
| |
| # Determine Bazel package prefix |
| bazel_prefix = get_bazel_package_prefix(output_root) |
| if bazel_prefix == '//': |
| prefix = '//' |
| else: |
| prefix = f'{bazel_prefix}/' |
| |
| # Fixups for kernel/common |
| common_target = f"{prefix}tests/kernel/common:main" |
| print(f"Applying fixups for {common_target}...") |
| run_buildozer( |
| ['remove visibility', 'add deps @zephyr_version//:version'], |
| common_target, |
| ) |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser( |
| description='Generate BUILD.bazel files for samples and tests directories.' |
| ) |
| parser.add_argument( |
| '--zephyr_root', |
| required=True, |
| help='The root directory of the Zephyr tree.', |
| ) |
| parser.add_argument( |
| '--output_root', |
| required=True, |
| help='The root directory for the generated BUILD.bazel files.', |
| ) |
| args = parser.parse_args() |
| create_build_files(args.zephyr_root, args.output_root) |
| |
| |
| if __name__ == '__main__': |
| main() |