Cmake: add defconfig preprocess capability in Cmake build environment(recursively expand #include)
Add:
cmake/nuttx_process_config.cmake
tools/process_config.py
Update nuttx/CMakeLists.txt to call process_config defined ini
nuttx_process_config.cmake to process defconfig before actually using it
This commit is contained in:
parent
e87c43b798
commit
be36d42da5
3 changed files with 169 additions and 0 deletions
|
|
@ -158,6 +158,22 @@ if(NOT EXISTS "${NUTTX_DEFCONFIG}")
|
|||
message(FATAL_ERROR "No config file found at ${NUTTX_DEFCONFIG}")
|
||||
endif()
|
||||
|
||||
# Process initial defconfig ###################################################
|
||||
# Process initial defconfig to recursively expand #include in it
|
||||
|
||||
include(nuttx_process_config)
|
||||
get_filename_component(NUTTX_DEFCONFIG_DIR "${NUTTX_DEFCONFIG}" DIRECTORY)
|
||||
process_config(
|
||||
${CMAKE_BINARY_DIR}/.defconfig.processed
|
||||
${NUTTX_DEFCONFIG}
|
||||
INCLUDE_PATHS
|
||||
${NUTTX_DEFCONFIG_DIR}/../../common/configs
|
||||
${NUTTX_DEFCONFIG_DIR}/../common
|
||||
${NUTTX_DEFCONFIG_DIR}
|
||||
${NUTTX_DIR}/../apps
|
||||
${NUTTX_DIR}/../nuttx-apps)
|
||||
set(NUTTX_DEFCONFIG ${CMAKE_BINARY_DIR}/.defconfig.processed)
|
||||
|
||||
# Generate initial .config ###################################################
|
||||
# This is needed right before any other configure step so that we can source
|
||||
# Kconfig variables into CMake variables
|
||||
|
|
|
|||
48
cmake/nuttx_process_config.cmake
Normal file
48
cmake/nuttx_process_config.cmake
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# ##############################################################################
|
||||
# cmake/nuttx_process_config.cmake
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
# license agreements. See the NOTICE file distributed with this work for
|
||||
# additional information regarding copyright ownership. The ASF licenses this
|
||||
# file to you 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.
|
||||
#
|
||||
# ##############################################################################
|
||||
|
||||
function(process_config OUTPUT INPUT)
|
||||
set(options)
|
||||
set(oneValueArgs)
|
||||
set(multiValueArgs INCLUDE_PATHS)
|
||||
cmake_parse_arguments(PARSE_ARGV 2 PROCESS_INCLUDES "${options}"
|
||||
"${oneValueArgs}" "${multiValueArgs}")
|
||||
|
||||
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||
|
||||
set(include_args "")
|
||||
foreach(path IN LISTS PROCESS_INCLUDES_INCLUDE_PATHS)
|
||||
list(APPEND include_args "${path}")
|
||||
endforeach()
|
||||
|
||||
message(STATUS "Processing includes: ${INPUT} → ${OUTPUT}")
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/process_config.py
|
||||
${OUTPUT} ${INPUT} ${include_args}
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE out
|
||||
ERROR_VARIABLE err)
|
||||
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to process includes:\n${err}")
|
||||
endif()
|
||||
endfunction()
|
||||
105
tools/process_config.py
Normal file
105
tools/process_config.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/env python3
|
||||
# tools/process_config.py
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you 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.
|
||||
#
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def expand_file(input_path, include_paths, processed=None):
|
||||
"""
|
||||
Recursively expand the file, returning its contents in order as a list of lines.
|
||||
"""
|
||||
if processed is None:
|
||||
processed = set()
|
||||
|
||||
input_path = Path(input_path).resolve()
|
||||
if input_path in processed:
|
||||
return [] # Already processed, avoid duplicate includes
|
||||
processed.add(input_path)
|
||||
|
||||
expanded_lines = []
|
||||
|
||||
with input_path.open("r", encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for line in lines:
|
||||
line_strip = line.strip()
|
||||
match = re.match(r'#include\s*[<"]([^">]+)[">]', line_strip)
|
||||
if match:
|
||||
include_file = match.group(1)
|
||||
found = False
|
||||
|
||||
# Check the current directory first
|
||||
|
||||
direct_path = input_path.parent / include_file
|
||||
if direct_path.exists():
|
||||
expanded_lines.extend(
|
||||
expand_file(direct_path, include_paths, processed)
|
||||
)
|
||||
found = True
|
||||
else:
|
||||
# Then check in the include paths
|
||||
|
||||
for path in include_paths:
|
||||
candidate = Path(path) / include_file
|
||||
if candidate.exists():
|
||||
expanded_lines.extend(
|
||||
expand_file(candidate, include_paths, processed)
|
||||
)
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
print(
|
||||
f'ERROR: Cannot find "{include_file}" from {input_path}',
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
else:
|
||||
expanded_lines.append(line)
|
||||
|
||||
expanded_lines.append("\n") # Keep separation between files
|
||||
return expanded_lines
|
||||
|
||||
|
||||
def process_file(output_path, input_path, include_paths):
|
||||
lines = expand_file(input_path, include_paths)
|
||||
with open(output_path, "w", encoding="utf-8") as out:
|
||||
out.writelines(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
print(
|
||||
"Usage: process_includes.py <output_file> <input_file> [include_paths...]",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
output_file = Path(sys.argv[1])
|
||||
input_file = sys.argv[2]
|
||||
include_dirs = sys.argv[3:]
|
||||
|
||||
if output_file.exists():
|
||||
output_file.unlink()
|
||||
|
||||
process_file(output_file, input_file, include_dirs)
|
||||
Loading…
Add table
Reference in a new issue