forked from OERV-BSP/u-boot
buildman: Support #include files in defconfigs
This is used by some boards in U-Boot and is a convenient way to deal with common settings where using a Kconfig files is not desirable. Detect #include files and process them as if they were part of the original file. Signed-off-by: Simon Glass <sjg@chromium.org> Fixes: https://source.denx.de/u-boot/custodians/u-boot-dm/-/issues/30
This commit is contained in:
@@ -19,7 +19,10 @@ import time
|
||||
from buildman import board
|
||||
from buildman import kconfiglib
|
||||
|
||||
from u_boot_pylib import command
|
||||
from u_boot_pylib.terminal import print_clear, tprint
|
||||
from u_boot_pylib import tools
|
||||
from u_boot_pylib import tout
|
||||
|
||||
### constant variables ###
|
||||
OUTPUT_FILE = 'boards.cfg'
|
||||
@@ -202,6 +205,7 @@ class KconfigScanner:
|
||||
os.environ['KCONFIG_OBJDIR'] = ''
|
||||
self._tmpfile = None
|
||||
self._conf = kconfiglib.Kconfig(warn=False)
|
||||
self._srctree = srctree
|
||||
|
||||
def __del__(self):
|
||||
"""Delete a leftover temporary file before exit.
|
||||
@@ -239,7 +243,26 @@ class KconfigScanner:
|
||||
expect_target, match, rear = leaf.partition('_defconfig')
|
||||
assert match and not rear, f'{leaf} : invalid defconfig'
|
||||
|
||||
self._conf.load_config(defconfig)
|
||||
temp = None
|
||||
if b'#include' in tools.read_file(defconfig):
|
||||
cmd = [
|
||||
os.getenv('CPP', 'cpp'),
|
||||
'-nostdinc', '-P',
|
||||
'-I', self._srctree,
|
||||
'-undef',
|
||||
'-x', 'assembler-with-cpp',
|
||||
defconfig]
|
||||
result = command.run_pipe([cmd], capture=True, capture_stderr=True)
|
||||
temp = tempfile.NamedTemporaryFile(prefix='buildman-')
|
||||
tools.write_file(temp.name, result.stdout, False)
|
||||
fname = temp.name
|
||||
tout.info(f'Processing #include to produce {defconfig}')
|
||||
else:
|
||||
fname = defconfig
|
||||
|
||||
self._conf.load_config(fname)
|
||||
if temp:
|
||||
del temp
|
||||
self._tmpfile = None
|
||||
|
||||
params = {}
|
||||
|
||||
@@ -1112,6 +1112,30 @@ The -U option uses the u-boot.env files which are produced by a build.
|
||||
Internally, buildman writes out an out-env file into the build directory for
|
||||
later comparison.
|
||||
|
||||
defconfig fragments
|
||||
-------------------
|
||||
|
||||
Buildman provides some initial support for configuration fragments. It can scan
|
||||
these when present in defconfig files and handle the resuiting Kconfig
|
||||
correctly. Thus it is possible to build a board which has a ``#include`` in the
|
||||
defconfig file.
|
||||
|
||||
For now, Buildman simply includes the files to produce a single output file,
|
||||
using the C preprocessor. It does not call the ``merge_config.sh`` script. The
|
||||
redefined/redundant logic in that script could fairly easily be repeated in
|
||||
Buildman, to detect potential problems. For now it is not clear that this is
|
||||
useful.
|
||||
|
||||
To specify the C preprocessor to use, set the ``CPP`` environment variable. The
|
||||
default is ``cpp``.
|
||||
|
||||
Note that Buildman does not support adding fragments to existing boards, e.g.
|
||||
like::
|
||||
|
||||
make qemu_riscv64_defconfig acpi.config
|
||||
|
||||
This is partly because there is no way for Buildman to know which fragments are
|
||||
valid on which boards.
|
||||
|
||||
Building with clang
|
||||
-------------------
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
# Copyright (c) 2014 Google, Inc
|
||||
#
|
||||
|
||||
import io
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
@@ -373,6 +375,22 @@ class TestFunctional(unittest.TestCase):
|
||||
def _HandleCommandSize(self, args):
|
||||
return command.CommandResult(return_code=0)
|
||||
|
||||
def _HandleCommandCpp(self, args):
|
||||
# args ['-nostdinc', '-P', '-I', '/tmp/tmp7f17xk_o/src', '-undef',
|
||||
# '-x', 'assembler-with-cpp', fname]
|
||||
fname = args[7]
|
||||
buf = io.StringIO()
|
||||
for line in tools.read_file(fname, False).splitlines():
|
||||
if line.startswith('#include'):
|
||||
# Example: #include <configs/renesas_rcar2.config>
|
||||
m_incfname = re.match('#include <(.*)>', line)
|
||||
data = tools.read_file(m_incfname.group(1), False)
|
||||
for line in data.splitlines():
|
||||
print(line, file=buf)
|
||||
else:
|
||||
print(line, file=buf)
|
||||
return command.CommandResult(stdout=buf.getvalue(), return_code=0)
|
||||
|
||||
def _HandleCommand(self, **kwargs):
|
||||
"""Handle a command execution.
|
||||
|
||||
@@ -406,6 +424,8 @@ class TestFunctional(unittest.TestCase):
|
||||
return self._HandleCommandObjcopy(args)
|
||||
elif cmd.endswith( 'size'):
|
||||
return self._HandleCommandSize(args)
|
||||
elif cmd.endswith( 'cpp'):
|
||||
return self._HandleCommandCpp(args)
|
||||
|
||||
if not result:
|
||||
# Not handled, so abort
|
||||
@@ -1118,3 +1138,17 @@ CONFIG_SOC="fred"
|
||||
'config': '-',
|
||||
'target': 'board0'},
|
||||
['WARNING: board0_defconfig: No TARGET_BOARD0 enabled']), res)
|
||||
|
||||
# check handling of #include files; see _HandleCommandCpp()
|
||||
inc = os.path.join(src, 'common')
|
||||
tools.write_file(inc, b'CONFIG_TARGET_BOARD0=y\n')
|
||||
tools.write_file(norm, f'#include <{inc}>', False)
|
||||
res = scanner.scan(norm, True)
|
||||
self.assertEqual(({
|
||||
'arch': 'arm',
|
||||
'cpu': 'armv7',
|
||||
'soc': '-',
|
||||
'vendor': 'Tester',
|
||||
'board': 'ARM Board 0',
|
||||
'config': 'config0',
|
||||
'target': 'board0'}, []), res)
|
||||
|
||||
Reference in New Issue
Block a user