diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0c4343468d..967abed9f2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ # Grab our configured image. The source for this is found at: # https://gitlab.denx.de/u-boot/gitlab-ci-runner -image: trini/u-boot-gitlab-ci-runner:xenial-20190720-02Aug2019 +image: trini/u-boot-gitlab-ci-runner:bionic-20190912.1-03Oct2019 # We run some tests in different order, to catch some failures quicker. stages: @@ -22,8 +22,9 @@ stages: - . /tmp/venv/bin/activate - pip install pytest==2.8.7 - pip install python-subunit - - grub-mkimage -o ~/grub_x86.efi -O i386-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - - grub-mkimage -o ~/grub_x64.efi -O x86_64-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd + - pip install coverage + - grub-mkimage --prefix="" -o ~/grub_x86.efi -O i386-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd + - grub-mkimage --prefix="" -o ~/grub_x64.efi -O x86_64-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - mkdir ~/grub2-arm - ( cd ~/grub2-arm; wget -O - http://download.opensuse.org/ports/armv7hl/distribution/leap/42.2/repo/oss/suse/armv7hl/grub2-arm-efi-2.02~beta2-87.1.armv7hl.rpm | rpm2cpio | cpio -di ) - mkdir ~/grub2-arm64 @@ -36,9 +37,9 @@ stages: # use clang only do one configuration. - if [[ "${BUILDMAN}" != "" ]]; then ret=0; - tools/buildman/buildman -P -E ${BUILDMAN} ${OVERRIDE}|| ret=$?; + tools/buildman/buildman -o /tmp -P -E ${BUILDMAN} ${OVERRIDE}|| ret=$?; if [[ $ret -ne 0 && $ret -ne 129 ]]; then - tools/buildman/buildman -sdeP ${BUILDMAN}; + tools/buildman/buildman -o /tmp -sdeP ${BUILDMAN}; exit $ret; fi; fi @@ -46,7 +47,7 @@ stages: # never prevent any test from running. That way, we can always pass # "-k something" even when $TEST_PY_TEST_SPEC doesnt need a custom # value. - - export UBOOT_TRAVIS_BUILD_DIR=`cd .. && pwd`/.bm-work/${TEST_PY_BD}; + - export UBOOT_TRAVIS_BUILD_DIR=/tmp/.bm-work/${TEST_PY_BD}; export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin; export PYTHONPATH=/tmp/uboot-test-hooks/py/travis-ci; if [[ "${TEST_PY_BD}" != "" ]]; then @@ -64,9 +65,9 @@ build all 32bit ARM platforms: stage: world build script: - ret=0; - ./tools/buildman/buildman -P -E arm -x aarch64 || ret=$?; + ./tools/buildman/buildman -o /tmp -P -E arm -x aarch64 || ret=$?; if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -sdeP; + ./tools/buildman/buildman -o /tmp -sdeP; exit $ret; fi; @@ -78,9 +79,9 @@ build all 64bit ARM platforms: - . /tmp/venv/bin/activate - pip install pyelftools - ret=0; - ./tools/buildman/buildman -P -E aarch64 || ret=$?; + ./tools/buildman/buildman -o /tmp -P -E aarch64 || ret=$?; if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -sdeP; + ./tools/buildman/buildman -o /tmp -sdeP; exit $ret; fi; @@ -89,9 +90,9 @@ build all PowerPC platforms: stage: world build script: - ret=0; - ./tools/buildman/buildman -P -E powerpc || ret=$?; + ./tools/buildman/buildman -o /tmp -P -E powerpc || ret=$?; if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -sdeP; + ./tools/buildman/buildman -o /tmp -sdeP; exit $ret; fi; @@ -100,9 +101,9 @@ build all other platforms: stage: world build script: - ret=0; - ./tools/buildman/buildman -P -E -x arm,powerpc || ret=$?; + ./tools/buildman/buildman -o /tmp -P -E -x arm,powerpc || ret=$?; if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -sdeP; + ./tools/buildman/buildman -o /tmp -sdeP; exit $ret; fi; @@ -162,10 +163,10 @@ Run binman, buildman, dtoc and patman testsuites: virtualenv /tmp/venv; . /tmp/venv/bin/activate; pip install pyelftools; - export UBOOT_TRAVIS_BUILD_DIR=`cd .. && pwd`/.bm-work/sandbox_spl; + export UBOOT_TRAVIS_BUILD_DIR=/tmp/.bm-work/sandbox_spl; export PYTHONPATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc/pylibfdt"; export PATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc:${PATH}"; - ./tools/buildman/buildman -P sandbox_spl; + ./tools/buildman/buildman -o /tmp -P sandbox_spl; ./tools/binman/binman --toolpath ${UBOOT_TRAVIS_BUILD_DIR}/tools test; ./tools/buildman/buildman -t; ./tools/dtoc/dtoc -t; diff --git a/.travis.yml b/.travis.yml index 0ce09e35b7..c48b711659 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ # build U-Boot on Travis CI - https://travis-ci.org/ sudo: required -dist: xenial +dist: bionic language: c @@ -12,7 +12,7 @@ addons: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-xenial-7 + - llvm-toolchain-bionic-7 packages: - cppcheck - sloccount @@ -52,12 +52,13 @@ install: - pip install pytest==2.8.7 - pip install python-subunit - pip install pyelftools - - grub-mkimage -o ~/grub_x86.efi -O i386-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - - grub-mkimage -o ~/grub_x64.efi -O x86_64-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd + - grub-mkimage --prefix="" -o ~/grub_x86.efi -O i386-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd + - grub-mkimage --prefix="" -o ~/grub_x64.efi -O x86_64-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - mkdir ~/grub2-arm - ( cd ~/grub2-arm; wget -O - http://download.opensuse.org/ports/armv7hl/distribution/leap/42.2/repo/oss/suse/armv7hl/grub2-arm-efi-2.02~beta2-87.1.armv7hl.rpm | rpm2cpio | cpio -di ) - mkdir ~/grub2-arm64 - ( cd ~/grub2-arm64; wget -O - http://download.opensuse.org/ports/aarch64/distribution/leap/42.2/repo/oss/suse/aarch64/grub2-arm64-efi-2.02~beta2-87.1.aarch64.rpm | rpm2cpio | cpio -di ) + - wget http://mirrors.kernel.org/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-1_amd64.deb && sudo dpkg -i libmpfr4_3.1.4-1_amd64.deb && rm libmpfr4_3.1.4-1_amd64.deb env: global: diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 119d02cbb2..f90b8ea7f5 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -175,6 +175,7 @@ class TestFunctional(unittest.TestCase): """ def setUp(self): self._base_dir = tempfile.mkdtemp() + self._output_dir = tempfile.mkdtemp() self._git_dir = os.path.join(self._base_dir, 'src') self._buildman_pathname = sys.argv[0] self._buildman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) @@ -207,6 +208,7 @@ class TestFunctional(unittest.TestCase): def tearDown(self): shutil.rmtree(self._base_dir) + shutil.rmtree(self._output_dir) def setupToolchains(self): self._toolchains = toolchain.Toolchains() @@ -421,7 +423,7 @@ class TestFunctional(unittest.TestCase): def testCurrentSource(self): """Very simple test to invoke buildman on the current source""" self.setupToolchains(); - self._RunControl() + self._RunControl('-o', self._output_dir) lines = terminal.GetPrintTestLines() self.assertIn('Building current source for %d boards' % len(boards), lines[0].text) @@ -434,7 +436,7 @@ class TestFunctional(unittest.TestCase): def testBadToolchain(self): """Test that missing toolchains are detected""" self.setupToolchains(); - ret_code = self._RunControl('-b', TEST_BRANCH) + ret_code = self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir) lines = terminal.GetPrintTestLines() # Buildman always builds the upstream commit as well @@ -458,13 +460,13 @@ class TestFunctional(unittest.TestCase): def testBranch(self): """Test building a branch with all toolchains present""" - self._RunControl('-b', TEST_BRANCH) + self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir) self.assertEqual(self._builder.count, self._total_builds) self.assertEqual(self._builder.fail, 0) def testCount(self): """Test building a specific number of commitst""" - self._RunControl('-b', TEST_BRANCH, '-c2') + self._RunControl('-b', TEST_BRANCH, '-c2', '-o', self._output_dir) self.assertEqual(self._builder.count, 2 * len(boards)) self.assertEqual(self._builder.fail, 0) # Each board has a mrproper, config, and then one make per commit @@ -472,34 +474,34 @@ class TestFunctional(unittest.TestCase): def testIncremental(self): """Test building a branch twice - the second time should do nothing""" - self._RunControl('-b', TEST_BRANCH) + self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir) # Each board has a mrproper, config, and then one make per commit self.assertEqual(self._make_calls, len(boards) * (self._commits + 2)) self._make_calls = 0 - self._RunControl('-b', TEST_BRANCH, clean_dir=False) + self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir, clean_dir=False) self.assertEqual(self._make_calls, 0) self.assertEqual(self._builder.count, self._total_builds) self.assertEqual(self._builder.fail, 0) def testForceBuild(self): """The -f flag should force a rebuild""" - self._RunControl('-b', TEST_BRANCH) + self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir) self._make_calls = 0 - self._RunControl('-b', TEST_BRANCH, '-f', clean_dir=False) + self._RunControl('-b', TEST_BRANCH, '-f', '-o', self._output_dir, clean_dir=False) # Each board has a mrproper, config, and then one make per commit self.assertEqual(self._make_calls, len(boards) * (self._commits + 2)) def testForceReconfigure(self): """The -f flag should force a rebuild""" - self._RunControl('-b', TEST_BRANCH, '-C') + self._RunControl('-b', TEST_BRANCH, '-C', '-o', self._output_dir) # Each commit has a mrproper, config and make self.assertEqual(self._make_calls, len(boards) * self._commits * 3) def testErrors(self): """Test handling of build errors""" self._error['board2', 1] = 'fred\n' - self._RunControl('-b', TEST_BRANCH) + self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir) self.assertEqual(self._builder.count, self._total_builds) self.assertEqual(self._builder.fail, 1) @@ -507,13 +509,13 @@ class TestFunctional(unittest.TestCase): # not be rebuilt del self._error['board2', 1] self._make_calls = 0 - self._RunControl('-b', TEST_BRANCH, clean_dir=False) + self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir, clean_dir=False) self.assertEqual(self._builder.count, self._total_builds) self.assertEqual(self._make_calls, 0) self.assertEqual(self._builder.fail, 1) # Now use the -F flag to force rebuild of the bad commit - self._RunControl('-b', TEST_BRANCH, '-F', clean_dir=False) + self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir, '-F', clean_dir=False) self.assertEqual(self._builder.count, self._total_builds) self.assertEqual(self._builder.fail, 0) self.assertEqual(self._make_calls, 3) diff --git a/tools/buildman/kconfiglib.py b/tools/buildman/kconfiglib.py index d68af056b6..3908985c7b 100644 --- a/tools/buildman/kconfiglib.py +++ b/tools/buildman/kconfiglib.py @@ -1,3409 +1,6219 @@ +# Copyright (c) 2011-2019, Ulf Magnusson # SPDX-License-Identifier: ISC -# -# Author: Ulf Magnusson -# https://github.com/ulfalizer/Kconfiglib - -# This is Kconfiglib, a Python library for scripting, debugging, and extracting -# information from Kconfig-based configuration systems. To view the -# documentation, run -# -# $ pydoc kconfiglib -# -# or, if you prefer HTML, -# -# $ pydoc -w kconfiglib -# -# The examples/ subdirectory contains examples, to be run with e.g. -# -# $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py -# -# Look in testsuite.py for the test suite. """ -Kconfiglib is a Python library for scripting and extracting information from -Kconfig-based configuration systems. Features include the following: +Overview +======== - - Symbol values and properties can be looked up and values assigned - programmatically. - - .config files can be read and written. - - Expressions can be evaluated in the context of a Kconfig configuration. - - Relations between symbols can be quickly determined, such as finding all - symbols that reference a particular symbol. - - Highly compatible with the scripts/kconfig/*conf utilities. The test suite - automatically compares outputs between Kconfiglib and the C implementation - for a large number of cases. +Kconfiglib is a Python 2/3 library for scripting and extracting information +from Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt) +configuration systems. -For the Linux kernel, scripts are run using +See the homepage at https://github.com/ulfalizer/Kconfiglib for a longer +overview. - $ make scriptconfig [ARCH=] SCRIPT= [SCRIPT_ARG=] +Since Kconfiglib 12.0.0, the library version is available in +kconfiglib.VERSION, which is a (, , ) tuple, e.g. +(12, 0, 0). -Using the 'scriptconfig' target ensures that required environment variables -(SRCARCH, ARCH, srctree, KERNELVERSION, etc.) are set up correctly. -Scripts receive the name of the Kconfig file to load in sys.argv[1]. As of -Linux 4.1.0-rc5, this is always "Kconfig" from the kernel top-level directory. -If an argument is provided with SCRIPT_ARG, it appears as sys.argv[2]. +Using Kconfiglib on the Linux kernel with the Makefile targets +============================================================== -To get an interactive Python prompt with Kconfiglib preloaded and a Config -object 'c' created, run +For the Linux kernel, a handy interface is provided by the +scripts/kconfig/Makefile patch, which can be applied with either 'git am' or +the 'patch' utility: - $ make iscriptconfig [ARCH=] + $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | git am + $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1 -Kconfiglib supports both Python 2 and Python 3. For (i)scriptconfig, the Python -interpreter to use can be passed in PYTHONCMD, which defaults to 'python'. PyPy -works well too, and might give a nice speedup for long-running jobs. +Warning: Not passing -p1 to patch will cause the wrong file to be patched. -The examples/ directory contains short example scripts, which can be run with -e.g. +Please tell me if the patch does not apply. It should be trivial to apply +manually, as it's just a block of text that needs to be inserted near the other +*conf: targets in scripts/kconfig/Makefile. - $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py +Look further down for a motivation for the Makefile patch and for instructions +on how you can use Kconfiglib without it. -or +If you do not wish to install Kconfiglib via pip, the Makefile patch is set up +so that you can also just clone Kconfiglib into the kernel root: - $ make scriptconfig SCRIPT=Kconfiglib/examples/help_grep.py SCRIPT_ARG=kernel + $ git clone git://github.com/ulfalizer/Kconfiglib.git + $ git am Kconfiglib/makefile.patch (or 'patch -p1 < Kconfiglib/makefile.patch') -testsuite.py contains the test suite. See the top of the script for how to run -it. +Warning: The directory name Kconfiglib/ is significant in this case, because +it's added to PYTHONPATH by the new targets in makefile.patch. -Credits: Written by Ulf "Ulfalizer" Magnusson +The targets added by the Makefile patch are described in the following +sections. -Send bug reports, suggestions and other feedback to ulfalizer a.t Google's -email service. Don't wrestle with internal APIs. Tell me what you need and I -might add it in a safe way as a client API instead.""" +make kmenuconfig +---------------- + +This target runs the curses menuconfig interface with Python 3. As of +Kconfiglib 12.2.0, both Python 2 and Python 3 are supported (previously, only +Python 3 was supported, so this was a backport). + + +make guiconfig +-------------- + +This target runs the Tkinter menuconfig interface. Both Python 2 and Python 3 +are supported. To change the Python interpreter used, pass +PYTHONCMD= to 'make'. The default is 'python'. + + +make [ARCH=] iscriptconfig +-------------------------------- + +This target gives an interactive Python prompt where a Kconfig instance has +been preloaded and is available in 'kconf'. To change the Python interpreter +used, pass PYTHONCMD= to 'make'. The default is 'python'. + +To get a feel for the API, try evaluating and printing the symbols in +kconf.defined_syms, and explore the MenuNode menu tree starting at +kconf.top_node by following 'next' and 'list' pointers. + +The item contained in a menu node is found in MenuNode.item (note that this can +be one of the constants kconfiglib.MENU and kconfiglib.COMMENT), and all +symbols and choices have a 'nodes' attribute containing their menu nodes +(usually only one). Printing a menu node will print its item, in Kconfig +format. + +If you want to look up a symbol by name, use the kconf.syms dictionary. + + +make scriptconfig SCRIPT=