Add llvm.py configure
Add a subcommand that runs CMake in a given build directory, with a
custom generator and custom CMake definitions. Also update llvm-build to
use it instead of calling CMake directly, and add calls to it in
llvm-projs as well to make sure we update the build directories whenever
we enable or disable a project.
One known issue with the current code is that the output of the CMake
command is not printed out live, but rather after the command has
finished execution. This is going to be more important for llvm.py build
than for llvm.py configure, so we can fix it in a future commit.
Change-Id: I263b2d47c2083a1778608253bbd437149375c539
diff --git a/tests/unittests/testllvmbuildconfig.py b/tests/unittests/testllvmbuildconfig.py
new file mode 100644
index 0000000..509e8a4
--- /dev/null
+++ b/tests/unittests/testllvmbuildconfig.py
@@ -0,0 +1,89 @@
+from modules.llvm import LLVMBuildConfig
+
+from os import makedirs
+from shutil import rmtree
+
+from unittest import TestCase
+from unittest.mock import MagicMock
+from uuid import uuid4
+
+
+class TestLLVMBuildConfig(TestCase):
+ testdirprefix = "BuildConfigUT"
+
+ def setUp(self):
+ self.sourcePath = "llvm" + str(uuid4())
+ self.buildPath = "build" + str(uuid4())
+
+ sourceConfigAttrs = {"get_path.return_value": self.sourcePath}
+ self.sourceConfig = MagicMock(**sourceConfigAttrs)
+
+ makedirs(self.buildPath)
+
+ def tearDown(self):
+ rmtree(self.buildPath)
+
+ def test_configure_generator(self):
+ """Test that we can use a custom generator for our CMake command."""
+ buildConfig = LLVMBuildConfig(self.sourceConfig, self.buildPath)
+
+ consumer = MagicMock()
+ buildConfig.cmake(consumer, [], "Unix Makefiles")
+ command, directory = consumer.consume.call_args[0]
+
+ self.assertEqual(directory, self.buildPath)
+
+ self.assertEqual(command[0], "cmake")
+ self.assertIn(self.sourcePath, command)
+ self.assertEqual(
+ command.index("-G") + 1,
+ command.index("Unix Makefiles"))
+
+ def test_configure_definitions(self):
+ """Test that we can define custom CMake variables."""
+ buildConfig = LLVMBuildConfig(self.sourceConfig, self.buildPath)
+ flags = ["-DCMAKE_BUILD_TYPE=Release",
+ "-DCMAKE_CXX_FLAGS=\"-Oz -g\""]
+
+ consumer = MagicMock()
+ buildConfig.cmake(consumer, flags, "Ninja")
+ command, directory = consumer.consume.call_args[0]
+
+ self.assertEqual(directory, self.buildPath)
+
+ self.assertEqual(command[0], "cmake")
+ self.assertEqual(command.index("-G") + 1, command.index("Ninja"))
+ self.assertIn(self.sourcePath, command)
+ self.assertEqual(command.index(flags[0]) + 1, command.index(flags[1]))
+
+ def test_update_projects(self):
+ """
+ Test that we explicitly enable/disable subprojects based on what is
+ enabled in the source config.
+ """
+
+ def for_each_subproj(action):
+ # Pretend that clang is enabled and lld isn't.
+ clang_subproj = MagicMock()
+ clang_subproj.cmake_var = "BUILD_CLANG"
+ action(clang_subproj, True)
+
+ lld_subproj = MagicMock()
+ lld_subproj.cmake_var = "BUILD_LLD"
+ action(lld_subproj, False)
+
+ self.sourceConfig.for_each_subproj.side_effect = for_each_subproj
+
+ buildConfig = LLVMBuildConfig(self.sourceConfig, self.buildPath)
+
+ consumer = MagicMock()
+ buildConfig.cmake(consumer, [], "Ninja")
+ command, directory = consumer.consume.call_args[0]
+
+ self.assertEqual(directory, self.buildPath)
+
+ self.assertEqual(command[0], "cmake")
+ self.assertEqual(command.index("-G") + 1, command.index("Ninja"))
+ self.assertIn(self.sourcePath, command)
+ self.assertIn("-DBUILD_CLANG=ON", command)
+ self.assertIn("-DBUILD_LLD=OFF", command)