aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2018-02-19 19:14:00 +0100
committerDiana Picus <diana.picus@linaro.org>2018-02-22 11:47:12 +0100
commitfec612c2a0bb8d1dd9c0a51a03c7b40caf66764e (patch)
tree8ef5099127a7812ab764f69c074a77cd3d1d2e9f
parent49ee93aa15132f4a90a98bca433678b622a5bdb2 (diff)
build-and-test: Allow flags to be read from files
Use the built-in support from the argparse module to allow our subcommand to read flags from configuration files. This is achieved by specifying a prefix (in our case '@') that indicates to argparse that it should read arguments from the file ('@filepath'), one per line. They are then processed as if they had been given on the command line in the position where the filename is. This makes it possible for flags in the file to override or be overriden by flags given on the command line, depending on their position relative to the filename. Flags that accumulate all the values that they receive cannot be overriden, but will instead accumulate everything regardless of whether it came from the command line or the file. Change-Id: I22a9a92a0f5ba49dd085ef5860c37bd4fc1009e1
-rw-r--r--scripts/llvm.py1
-rw-r--r--tests/cli/testbuildandtest.py105
2 files changed, 106 insertions, 0 deletions
diff --git a/scripts/llvm.py b/scripts/llvm.py
index 8d9a4c1..1962293 100644
--- a/scripts/llvm.py
+++ b/scripts/llvm.py
@@ -471,6 +471,7 @@ runTestSuite.set_defaults(run_command=run_the_test_suite)
buildAndTest = subcommands.add_parser(
'build-and-test', # TODO: This really needs a better name...
+ fromfile_prefix_chars='@',
help="Run complex build scenarios with one or two stages of clang and "
"optionally a test-suite run. This should be flexible enough to allow "
"us to reproduce any buildbot configuration, but it can obviously be "
diff --git a/tests/cli/testbuildandtest.py b/tests/cli/testbuildandtest.py
index 86e2203..fe879a2 100644
--- a/tests/cli/testbuildandtest.py
+++ b/tests/cli/testbuildandtest.py
@@ -5,6 +5,7 @@ tests.
"""
import os
+from tempfile import NamedTemporaryFile
from llvmtestcase import LLVMTestCase, require_command_arg, debug
@@ -15,6 +16,13 @@ class Testllvmbuildandtest(LLVMTestCase):
def llvm_build_and_test(cls, *args, **kwargs):
return cls.command_with_defaults("build-and-test", *args, **kwargs)
+ @classmethod
+ def get_temp_file_with_content(cls, content):
+ """Return a temporary file with the given content."""
+ theFile = NamedTemporaryFile(mode='wt')
+ print(content, file=theFile, flush=True)
+ return theFile
+
def test_default_stage1(self):
"""
Test that we dump the correct commands for a single stage build of LLVM.
@@ -393,3 +401,100 @@ class Testllvmbuildandtest(LLVMTestCase):
"--sandbox={sandbox} --test-suite={testsuite} "
"--use-lit={build}/bin/llvm-lit --cc={build}/bin/clang".format(
sandbox=sandboxDir, testsuite=testSuiteDir, build=buildDir2))
+
+ def test_read_flags_from_file(self):
+ """Test that we can read our flags from a configuration file."""
+ reposDir = "path-to-repos"
+ sourceDir = "path-to-sources"
+ buildDir = "path-to-stage1"
+
+ flagsInFile = ("--dry-run\n"
+ "--repos-dir\n"
+ "{repos}\n"
+ "--source-dir\n"
+ "{sources}\n"
+ "--stage1-build-dir\n"
+ "{build}").format(
+ repos=reposDir, sources=sourceDir, build=buildDir)
+
+ with self.get_temp_file_with_content(flagsInFile) as configFile:
+ output = self.run_with_output(
+ self.llvm_build_and_test("@{}".format(configFile.name)))
+
+ commands = output.splitlines()
+
+ self.assertRegex(commands[0],
+ "{build}\$ cmake -G Ninja .* {sources}".format(
+ build=buildDir, sources=sourceDir))
+
+ self.assertRegex(commands[1],
+ "{build}\$ ninja".format(build=buildDir))
+
+ def test_override_flags_from_file(self):
+ """
+ Test that we can combine flags from a configuration file and command
+ line flags. The command line flags that come before the name of the
+ configuration file should be overriden by those from the file, whereas
+ command line flags that come after the name of the configuration file
+ should override the values found in the file. For arguments that can be
+ passed multiple times, all the values are collected (both from the
+ command line and from the config file). They should however appear in
+ the order that they were given.
+ """
+ reposDir = "path-to-repos"
+ sourceDir = "path-to-sources"
+ buildDir = "path-to-stage1"
+
+ overridenSourceDir = "overriden-sources"
+ overridenBuildDir = "overriden-build"
+
+ flagsInFile = (
+ "--dry-run\n"
+ "--repos-dir\n"
+ "{repos}\n"
+ "--source-dir\n"
+ "{sources}\n"
+ "--stage1-build-dir\n"
+ "{build}\n"
+ "--stage1-subproject\n"
+ "clang\n"
+ "--stage1-cmake-def\n"
+ "CMAKE_CXX_FLAGS=-mthumb").format(repos=reposDir, sources=sourceDir,
+ build=overridenBuildDir)
+
+ with self.get_temp_file_with_content(flagsInFile) as configFile:
+ output = self.run_with_output(
+ self.llvm_build_and_test(
+ # This should be overriden by the value in the config file.
+ "--source-dir", overridenSourceDir,
+ # This should be appended to the value in the config file.
+ "--stage1-subproject", "lld",
+ # The config file.
+ "@{}".format(configFile.name),
+ # This should override the value in the config file.
+ "--stage1-build-dir", buildDir,
+ # These should be appended to the values in the config file.
+ "--stage1-subproject", "compiler-rt",
+ "--stage1-cmake-def", "CMAKE_CXX_FLAGS=-marm",
+ "--stage1-cmake-def", "LLVM_ENABLE_ASSERTIONS=True"))
+
+ commands = output.splitlines()
+
+ self.assertRegex(commands[0],
+ "{build}\$ cmake -G Ninja .* {sources}".format(
+ build=buildDir, sources=sourceDir))
+
+ self.assertIn("-DLLVM_TOOL_CLANG_BUILD=ON", commands[0])
+ self.assertIn("-DLLVM_TOOL_LLD_BUILD=ON", commands[0])
+ self.assertIn("-DLLVM_TOOL_COMPILER_RT_BUILD=ON", commands[0])
+ self.assertIn("-DLLVM_TOOL_LIBCXX_BUILD=OFF", commands[0])
+ self.assertIn("-DLLVM_TOOL_LLDB_BUILD=OFF", commands[0])
+
+ self.assertIn("-DCMAKE_CXX_FLAGS=-marm", commands[0])
+ self.assertIn("-DCMAKE_CXX_FLAGS=-mthumb", commands[0])
+ self.assertLess(commands[0].find("-DCMAKE_CXX_FLAGS=-mthumb"),
+ commands[0].find("-DCMAKE_CXX_FLAGS=-marm"))
+ self.assertIn("-DLLVM_ENABLE_ASSERTIONS=True", commands[0])
+
+ self.assertRegex(commands[1],
+ "{build}\$ ninja".format(build=buildDir))