Require clang in stage 1 when enabling stage 2 / test-suite

Both the test-suite and stage 2 need clang, so check early that it is
built as part of stage 1.

I'm not 100% certain on the former, since nowadays the test-suite
contains some bitcode tests which might be able to run without clang,
but it's unlikely that we'll ever be interested in such a scenario.

Change-Id: I6668557d9c2ef8cbad8a309a3c73c690d24533d1
diff --git a/scripts/llvm.py b/scripts/llvm.py
index 1962293..70ba713 100644
--- a/scripts/llvm.py
+++ b/scripts/llvm.py
@@ -208,6 +208,15 @@
     sandboxDir = args.sandbox
     testSuiteFlags = args.testSuiteFlags
 
+    if not "clang" in stage1Subprojs:
+        if enableTestSuite:
+            die("Can't enable the test-suite if stage 1 doesn't build clang."
+                "Please add clang to the subprojects to be built for stage 1.")
+
+        if stage2BuildDir:
+            die("Can't enable stage 2 if stage 1 doesn't build clang."
+                "Please add clang to the subprojects to be built for stage 1.")
+
     if dryRun:
         consumer = CommandPrinter()
     else:
@@ -246,8 +255,6 @@
             buildConfig2 = LLVMBuildConfig(sourceConfig, stage2BuildDir,
                                            consumer)
 
-            # TODO: Make sure clang is actually built in this config (preferably
-            # before reaching this point)
             buildConfig2.cmake(
                 stage2Defs + [
                     "-DCMAKE_C_COMPILER={}/bin/clang".format(stage1BuildDir),
@@ -262,8 +269,6 @@
 
             setup_test_suite(consumer, sandboxDir, lntDir)
 
-            # TODO: Make sure clang is actually built in this config (preferably
-            # before reaching this point)
             lit = os.path.join(testedBuildDir, "bin", "llvm-lit")
             clang = os.path.join(testedBuildDir, "bin", "clang")
             run_test_suite(consumer, sandboxDir, testSuiteDir, lit,
diff --git a/tests/cli/testbuildandtest.py b/tests/cli/testbuildandtest.py
index da3d14b..0603784 100644
--- a/tests/cli/testbuildandtest.py
+++ b/tests/cli/testbuildandtest.py
@@ -5,6 +5,7 @@
 
 """
 import os
+from subprocess import CalledProcessError
 from tempfile import NamedTemporaryFile
 
 from llvmtestcase import LLVMTestCase, require_command_arg, debug
@@ -127,6 +128,7 @@
                 "--repos-dir", reposDir,
                 "--source-dir", sourceDir,
                 "--stage1-build-dir", buildDir,
+                "--stage1-subproject", "clang",
                 "--enable-test-suite",
                 "--sandbox", sandboxDir))
 
@@ -171,6 +173,7 @@
                 "--repos-dir", reposDir,
                 "--source-dir", sourceDir,
                 "--stage1-build-dir", buildDir,
+                "--stage1-subproject", "clang",
                 "--enable-test-suite",
                 "--sandbox", sandboxDir,
                 "--lnt-flag=--threads=4",
@@ -203,6 +206,33 @@
             "--threads=4 --cppflags '-mcpu=cortex-a15 -marm'".format(
                 sandbox=sandboxDir, testsuite=testSuiteDir, build=buildDir))
 
+    def test_stage1_needs_clang_if_testsuite_is_enabled(self):
+        """
+        Test that we error out early on if we enable the test-suite but don't
+        add clang to stage 1.
+        """
+        reposDir = "path-to-repos"
+        sourceDir = "path-to-sources"
+        buildDir = "path-to-stage1"
+        sandboxDir = "path-to-sandbox"
+
+        testSuiteDir = os.path.join(reposDir, "test-suite")
+        lntDir = os.path.join(reposDir, "lnt")
+
+        with self.assertRaises(CalledProcessError) as context:
+            output = self.run_with_output(
+                self.llvm_build_and_test(
+                    "--dry-run",
+                    "--repos-dir", reposDir,
+                    "--source-dir", sourceDir,
+                    "--stage1-build-dir", buildDir,
+                    "--enable-test-suite",
+                    "--sandbox", sandboxDir))
+
+        self.assertIn(
+            "Can't enable the test-suite if stage 1 doesn't build clang",
+            str(context.exception.output))
+
     def test_default_stage2(self):
         """
         Test that we dump the correct commands for a 2-stage build of LLVM.
@@ -218,6 +248,7 @@
                 "--repos-dir", reposDir,
                 "--source-dir", sourceDir,
                 "--stage1-build-dir", buildDir1,
+                "--stage1-subproject", "clang",
                 "--stage2-build-dir", buildDir2))
 
         commands = output.splitlines()
@@ -363,6 +394,28 @@
             commands[3],
             "{stage2}\$ ninja check-all".format(stage2=buildDir2))
 
+    def test_stage1_needs_clang_if_stage2_is_enabled(self):
+        """
+        Test that we can't enable stage 2 unless stage 1 builds clang.
+        """
+        reposDir = "path-to-repos"
+        sourceDir = "path-to-sources"
+        buildDir1 = "path-to-stage1"
+        buildDir2 = "path-to-stage2"
+
+        with self.assertRaises(CalledProcessError) as context:
+            output = self.run_with_output(
+                self.llvm_build_and_test(
+                    "--dry-run",
+                    "--repos-dir", reposDir,
+                    "--source-dir", sourceDir,
+                    "--stage1-build-dir", buildDir1,
+                    "--stage2-build-dir", buildDir2))
+
+        self.assertIn(
+            "Can't enable stage 2 if stage 1 doesn't build clang",
+            str(context.exception.output))
+
     def test_stage2_and_testsuite(self):
         """
         Test that we dump the correct commands for a 2-stage build of LLVM and a
@@ -383,6 +436,7 @@
                 "--repos-dir", reposDir,
                 "--source-dir", sourceDir,
                 "--stage1-build-dir", buildDir1,
+                "--stage1-subproject", "clang",
                 "--stage2-build-dir", buildDir2,
                 "--enable-test-suite",
                 "--sandbox", sandboxDir))