blob: 0537b1f918d790f376d868fe1f9c74f3a06a5b71 [file]
# 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()