blob: 83ec52c41c473ee1204cf09911b604d4c3457cea [file] [edit]
# Copyright 2025 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.
"""Script to generate BUILD.bazel files for one soc/<vendor> directory."""
import argparse
from pathlib import Path
import sys
import cmake_converter_common as common
import soc_cmake_to_bazel
def is_leaf(cmake_dir: Path) -> bool:
"""Checks if a directory is a leaf SoC directory."""
# common directory does not represent a real SoC.
if cmake_dir.name == 'common':
return False
for item in cmake_dir.iterdir():
if item.is_dir():
if next(item.rglob('CMakeLists.txt'), None):
return False
return True
def main():
"""Main entry point."""
parser = argparse.ArgumentParser(
description=(
"Batch-convert Zephyr's CMakeLists.txt files in one soc/<vendor>"
' directory to BUILD.bazel'
)
)
parser.add_argument(
'--start_dir',
required=True,
help='Top-level SoC directory to start conversion, e.g. soc/atmel',
)
parser.add_argument(
'--output_dir',
required=True,
help=(
'Output directory to hold converted BUILD.bazel files, e.g.'
' third_party/zephyr/soc/atmel'
),
)
args = parser.parse_args()
start_path = Path(args.start_dir)
output_path = Path(args.output_dir)
try:
any_cmake_file = next(start_path.rglob('CMakeLists.txt'))
soc_root = soc_cmake_to_bazel.find_soc_root(any_cmake_file)
except (StopIteration, ValueError) as e:
print(
f"Error: No CMakeLists.txt found in '{args.start_dir}' "
"or it's not a Zephyr SoC directory.",
file=sys.stderr,
)
print(f'Details: {e}', file=sys.stderr)
sys.exit(1)
if start_path.parent != soc_root:
print(
f"Warning: '{start_path}' is not a top-level SoC directory "
'e.g. soc/atmel. Converted Bazel rules may miss common files '
'in the top-level SoC directory.'
)
cmake_files = sorted(list(start_path.rglob('CMakeLists.txt')))
for cmake_file in cmake_files:
cmake_dir = cmake_file.parent
output_dir = common.translate_relative_path(
cmake_dir, start_path, output_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 = cmake_dir.name
skip_parent = False
if target_name == 'common' or cmake_dir == start_path:
skip_parent = True
parent_cmake_file = next(cmake_dir.parent.glob('CMakeLists.txt'), None)
if not parent_cmake_file:
skip_parent = True
parent_filegroup_name, common_filegroup_names = (
soc_cmake_to_bazel.get_filegroup_names(cmake_file, skip_parent)
)
leaf = is_leaf(cmake_dir)
bazel_content = soc_cmake_to_bazel.convert_cmakelists_to_bazel(
cmake_content,
target_name,
leaf,
parent_filegroup_name,
common_filegroup_names,
)
with open(output_file, 'w', encoding='utf-8') as f:
f.write(bazel_content)
# Write an empty header file alongside the generated BUILD.bazel so that
# our generated filegroups are never empty.
empty_header_file = output_dir / 'empty.h'
with open(empty_header_file, 'w') as f:
f.write("""// Copyright 2025 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.
""")
print('Conversion complete.')
if __name__ == '__main__':
main()