diff --git a/utils/build-script b/utils/build-script index 36dc3f2f81745..9463d553f0a9a 100755 --- a/utils/build-script +++ b/utils/build-script @@ -886,11 +886,12 @@ class BuildScriptInvocation(object): if self.args.build_early_swift_driver: before_impl_product_classes.append(products.EarlySwiftDriver) + if self.args.build_cmark: + before_impl_product_classes.append(products.CMark) + # FIXME: This is a weird division (returning a list of class objects), # but it matches the existing structure of the `build-script-impl`. impl_product_classes = [] - if self.args.build_cmark: - impl_product_classes.append(products.CMark) # If --skip-build-llvm is passed in, LLVM cannot be completely disabled, as # Swift still needs a few LLVM targets like tblgen to be built for it to be @@ -1026,7 +1027,7 @@ class BuildScriptInvocation(object): # Pre-build-script-impl products... # Note: currently only supports building for the host. - for host_target in [self.args.host_target]: + for host_target in all_host_names: for product_class in before_impl_product_classes: if product_class.is_build_script_impl_product(): continue diff --git a/utils/build_swift/build_swift/driver_arguments.py b/utils/build_swift/build_swift/driver_arguments.py index 5def4a11076d1..c648c337e1c4a 100644 --- a/utils/build_swift/build_swift/driver_arguments.py +++ b/utils/build_swift/build_swift/driver_arguments.py @@ -288,6 +288,9 @@ def create_argument_parser(): help='instead of building, write JSON to stdout containing ' 'various values used to build in this configuration') + option(['--reconfigure'], store_true, + help="Reconfigure all projects as we build") + option('--legacy-impl', store_true('legacy_impl'), help='use legacy implementation') diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py index f728f51808701..c4f2ee8c13ea2 100644 --- a/utils/build_swift/tests/expected_options.py +++ b/utils/build_swift/tests/expected_options.py @@ -197,6 +197,7 @@ 'native_llvm_tools_path': None, 'native_swift_tools_path': None, 'dump_config': False, + 'reconfigure': False, 'relocate_xdg_cache_home_under_build_subdir': False, 'show_sdks': False, 'skip_build': False, @@ -506,6 +507,7 @@ class BuildScriptImplOption(_BaseOption): SetTrueOption('--legacy-impl', dest='legacy_impl'), SetTrueOption('--infer', dest='infer_dependencies'), + SetTrueOption('--reconfigure'), EnableOption('--android'), EnableOption('--build-external-benchmarks'), diff --git a/utils/swift_build_support/swift_build_support/products/cmake_product.py b/utils/swift_build_support/swift_build_support/products/cmake_product.py new file mode 100644 index 0000000000000..746ff0ef1801c --- /dev/null +++ b/utils/swift_build_support/swift_build_support/products/cmake_product.py @@ -0,0 +1,116 @@ +# swift_build_support/products/product.py -----------------------*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2021 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See https://swift.org/LICENSE.txt for license information +# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- + +import os + +from . import product +from .. import cmake +from .. import shell + + +class CMakeProduct(product.Product): + def build_with_cmake(self, build_targets, build_type, build_args): + assert self.toolchain.cmake is not None + cmake_build = [] + _cmake = cmake.CMake(self.args, self.toolchain) + + if self.toolchain.distcc_pump: + cmake_build.append(self.toolchain.distcc_pump) + cmake_build.extend([self.toolchain.cmake, "--build"]) + + generator_output_path = "" + if self.args.cmake_generator == "Ninja": + generator_output_path = os.path.join(self.build_dir, "build.ninja") + + cmake_cache_path = os.path.join(self.build_dir, "CMakeCache.txt") + if self.args.reconfigure or not os.path.isfile(cmake_cache_path) or \ + (generator_output_path and not os.path.isfile(generator_output_path)): + if not os.path.exists(self.build_dir): + os.makedirs(self.build_dir) + + # Use `cmake-file-api` in case it is available. + query_dir = os.path.join(self.build_dir, ".cmake", "api", "v1", "query") + if not os.path.exists(query_dir): + os.makedirs(query_dir) + open(os.path.join(query_dir, "codemodel-v2"), 'a').close() + open(os.path.join(query_dir, "cache-v2"), 'a').close() + + env = None + if self.toolchain.distcc: + env = { + "DISTCC_HOSTS": "localhost,lzo,cpp" + } + + with shell.pushd(self.build_dir): + shell.call([self.toolchain.cmake] + list(self.cmake_options) + + list(_cmake.common_options()) + + self.args.extra_cmake_options + [self.source_dir], + env=env) + + if not self.args.skip_build or self.product_name() == "llvm": + if self.args.cmake_generator == "Xcode": + # Xcode generator uses "ALL_BUILD" instead of "all". + # Also, xcodebuild uses -target instead of bare names. + build_targets = build_targets.copy() + build_targets = [val for target in build_targets + for val in ["-target", + target if target != "all" + else "ALL_BUILD"]] + + # Xcode can't restart itself if it turns out we need to reconfigure. + # Do an advance build to handle that. + shell.call(cmake_build + [self.build_dir, build_type]) + + shell.call(cmake_build + [self.build_dir, "--config", build_type, "--"] + + build_args + build_targets) + + def test_with_cmake(self, executable_target, results_targets, + build_type, build_args): + assert self.toolchain.cmake is not None + cmake_build = [] + + if self.toolchain.distcc_pump: + cmake_build.append(self.toolchain.distcc_pump) + cmake_args = [self.toolchain.cmake, "--build", self.build_dir, + "--config", build_type, "--"] + cmake_build.extend(cmake_args + build_args) + + def target_flag(target): + if self.args.cmake_generator == "Xcode": + return ["-target", target] + return [target] + + if executable_target: + shell.call(cmake_build + target_flag(executable_target)) + + for target in results_targets: + if target: + test_target = target + print("--- %s ---" % target) + if test_target.startswith("check-swift") and self.args.test_paths: + test_target = test_target + "-custom" + + shell.call(cmake_build + target_flag(test_target)) + + print("--- %s finished ---" % target) + + def install_with_cmake(self, install_targets, install_destdir): + assert self.toolchain.cmake is not None + cmake_build = [] + + if self.toolchain.distcc_pump: + cmake_build.append(self.toolchain.distcc_pump) + cmake_args = [self.toolchain.cmake, "--build", self.build_dir, "--"] + cmake_build.extend(cmake_args + install_targets) + + environment = {'DESTDIR': install_destdir} + shell.call(cmake_build, env=environment) diff --git a/utils/swift_build_support/swift_build_support/products/cmark.py b/utils/swift_build_support/swift_build_support/products/cmark.py index b55dcaa52fbdf..5a791c7afbda9 100644 --- a/utils/swift_build_support/swift_build_support/products/cmark.py +++ b/utils/swift_build_support/swift_build_support/products/cmark.py @@ -10,17 +10,19 @@ # # ---------------------------------------------------------------------------- -from . import product +from build_swift.build_swift.wrappers import xcrun +from . import cmake_product -class CMark(product.Product): + +class CMark(cmake_product.CMakeProduct): @classmethod def is_build_script_impl_product(cls): """is_build_script_impl_product -> bool Whether this product is produced by build-script-impl. """ - return True + return False @classmethod def is_before_build_script_impl_product(cls): @@ -28,9 +30,90 @@ def is_before_build_script_impl_product(cls): Whether this product is build before any build-script-impl products. """ - return False + return True # This is the root of the build-graph, so it doesn't have any dependencies. @classmethod def get_dependencies(cls): return [] + + def should_build(self, host_target): + """should_build() -> Bool + + Whether or not this product should be built with the given arguments. + """ + return self.args.build_cmark + + def build(self, host_target): + """build() -> void + + Perform the build, for a non-build-script-impl product. + """ + self.cmake_options.define('CMAKE_BUILD_TYPE:STRING', + self.args.cmark_build_variant) + + (platform, arch) = host_target.split('-') + + if host_target.startswith("macosx") or \ + host_target.startswith("iphone") or \ + host_target.startswith("appletv") or \ + host_target.startswith("watch"): + + cmake_os_sysroot = xcrun.sdk_path(platform) + + cmake_osx_deployment_target = '' + if platform == "macosx": + cmake_osx_deployment_target = self.args.darwin_deployment_version_osx + + common_c_flags = ' '.join(self.common_cross_c_flags(platform, arch)) + + self.cmake_options.define('CMAKE_C_FLAGS', common_c_flags) + self.cmake_options.define('CMAKE_CXX_FLAGS', common_c_flags) + self.cmake_options.define('CMAKE_OSX_SYSROOT:PATH', cmake_os_sysroot) + self.cmake_options.define('CMAKE_OSX_DEPLOYMENT_TARGET', + cmake_osx_deployment_target) + self.cmake_options.define('CMAKE_OSX_ARCHITECTURES', arch) + + self.build_with_cmake(["all"], self.args.cmark_build_variant, []) + + def should_test(self, host_target): + """should_test() -> Bool + + Whether or not this product should be tested with the given arguments. + """ + if self.is_cross_compile_target(host_target): + return False + + return self.args.test + + def test(self, host_target): + """ + Perform the test phase for the product. + + This phase might build and execute the product tests. + """ + executable_target = 'api_test' + results_targets = ['test'] + if self.args.cmake_generator == 'Xcode': + # Xcode generator uses "RUN_TESTS" instead of "test". + results_targets = ['RUN_TESTS'] + + self.test_with_cmake(executable_target, results_targets, + self.args.cmark_build_variant, []) + + def should_install(self, host_target): + """should_install() -> Bool + + Whether or not this product should be installed with the given + arguments. + """ + return self.args.install_all + + def install(self, host_target): + """ + Perform the install phase for the product. + + This phase might copy the artifacts from the previous phases into a + destination directory. + """ + self.install_with_cmake(["install"], self.host_install_destdir(host_target)) diff --git a/utils/swift_build_support/swift_build_support/products/earlyswiftdriver.py b/utils/swift_build_support/swift_build_support/products/earlyswiftdriver.py index 9fad3c92f52b3..7a5775b0ce107 100644 --- a/utils/swift_build_support/swift_build_support/products/earlyswiftdriver.py +++ b/utils/swift_build_support/swift_build_support/products/earlyswiftdriver.py @@ -41,6 +41,9 @@ def is_before_build_script_impl_product(cls): return True def should_build(self, host_target): + if self.is_cross_compile_target(host_target): + return False + if self.args.build_early_swift_driver: if toolchain.host_toolchain().find_tool("swift") is None: warn_msg = 'Host toolchain could not locate a '\ diff --git a/utils/swift_build_support/swift_build_support/products/product.py b/utils/swift_build_support/swift_build_support/products/product.py index 7e072d3d1f969..b2c8c6b52b760 100644 --- a/utils/swift_build_support/swift_build_support/products/product.py +++ b/utils/swift_build_support/swift_build_support/products/product.py @@ -166,6 +166,8 @@ def __init__(self, args, toolchain, source_dir, build_dir): self.source_dir = source_dir self.build_dir = build_dir self.cmake_options = cmake.CMakeOptions() + self.common_c_flags = ['-Wno-unknown-warning-option', + '-Werror=unguarded-availability-new'] def is_release(self): """is_release() -> Bool @@ -190,6 +192,73 @@ def install_toolchain_path(self, host_target): return targets.toolchain_path(install_destdir, self.args.install_prefix) + def should_include_host_in_lipo(self, host_target): + if self.args.cross_compile_hosts: + if host_target.startswith("macosx") or \ + host_target.startswith("iphone") or \ + host_target.startswith("appletv") or \ + host_target.startswith("watch"): + return True + return False + + def host_install_destdir(self, host_target): + if self.args.cross_compile_hosts: + # If cross compiling tools, install into a host-specific subdirectory. + if self.should_include_host_in_lipo(host_target): + # If this is one of the hosts we should lipo, + # install in to a temporary subdirectory. + return '%s/intermediate-install/%s' % \ + (self.args.install_destdir, host_target) + elif host_target == "merged-hosts": + # This assumes that all hosts are merged to the lipo. + return self.args.install_destdir + else: + return '%s/%s' % (self.args.install_destdir, host_target) + else: + return self.args.install_destdir + + def is_cross_compile_target(self, host_target): + return self.args.cross_compile_hosts and \ + host_target in self.args.cross_compile_hosts + + # TODO: Remove once we've moved over to cmake toolchains + def common_cross_c_flags(self, platform, arch): + cross_flags = [] + + if platform == 'macosx': + target = '{}-apple-macosx{}'.format( + arch, self.args.darwin_deployment_version_osx) + cross_flags.extend(['-arch', arch, '-target', target]) + elif platform == 'iphonesimulator': + target = '{}-apple-ios{}'.format( + arch, self.args.darwin_deployment_version_ios) + cross_flags.extend(['-arch', arch, '-target', target]) + elif platform == 'iphoneos': + target = '{}-apple-ios{}'.format( + arch, self.args.darwin_deployment_version_ios) + cross_flags.extend(['-arch', arch, '-target', target]) + elif platform == 'appletvsimulator': + target = '{}-apple-tvos{}'.format( + arch, self.args.darwin_deployment_version_tvos) + cross_flags.extend(['-arch', arch, '-target', target]) + elif platform == 'appletvos': + target = '{}-apple-tvos{}'.format( + arch, self.args.darwin_deployment_version_tvos) + cross_flags.extend(['-arch', arch, '-target', target]) + elif platform == 'watchsimulator': + target = '{}-apple-watchos{}'.format( + arch, self.args.darwin_deployment_version_watchos) + cross_flags.extend(['-arch', arch, '-target', target]) + elif platform == 'watchos': + target = '{}-apple-watchos{}'.format( + arch, self.args.darwin_deployment_version_watchos) + cross_flags.extend(['-arch', arch, '-target', target]) + + if self.is_release(): + cross_flags.append('-fno-stack-protector') + + return self.common_c_flags + cross_flags + class ProductBuilder(object): """ diff --git a/utils/swift_build_support/tests/products/test_cmark.py b/utils/swift_build_support/tests/products/test_cmark.py new file mode 100644 index 0000000000000..89d61cf028d13 --- /dev/null +++ b/utils/swift_build_support/tests/products/test_cmark.py @@ -0,0 +1,115 @@ +# tests/products/test_ninja.py ----------------------------------*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2021 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See https://swift.org/LICENSE.txt for license information +# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# ---------------------------------------------------------------------------- + +import argparse +import os +import shutil +import sys +import tempfile +import unittest +try: + # py2 + from StringIO import StringIO +except ImportError: + # py3 + from io import StringIO + +# from swift_build_support import cmake +from swift_build_support import shell +# from swift_build_support.products import CMark +from swift_build_support.targets import StdlibDeploymentTarget +from swift_build_support.toolchain import host_toolchain +from swift_build_support.workspace import Workspace + + +class CMarkTestCase(unittest.TestCase): + + def setUp(self): + # Setup workspace + tmpdir1 = os.path.realpath(tempfile.mkdtemp()) + tmpdir2 = os.path.realpath(tempfile.mkdtemp()) + os.makedirs(os.path.join(tmpdir1, 'cmark')) + + self.workspace = Workspace(source_root=tmpdir1, + build_root=tmpdir2) + + self.host = StdlibDeploymentTarget.host_target() + + # Setup toolchain + self.toolchain = host_toolchain() + self.toolchain.cc = '/path/to/cc' + self.toolchain.cxx = '/path/to/cxx' + + # Setup args + self.args = argparse.Namespace( + build_cmark=True, + cmake_generator="Ninja", + cmark_build_type="Release", + rebuild=False, + extra_cmake_options=[], + skip_build=False, + darwin_deployment_version_osx="10.9", + cmark_build_variant="Debug", + export_compile_commands=False, + reconfigure=False, + distcc=None, + sccache=None, + cmake_c_launcher=None, + cmake_cxx_launcher=None, + clang_user_visible_version=None, + build_ninja=False, + enable_asan=False, + enable_lsan=False, + enable_sanitize_coverage=False, + enable_tsan=False, + enable_ubsan=False) + + # Setup shell + shell.dry_run = True + self._orig_stdout = sys.stdout + self._orig_stderr = sys.stderr + self.stdout = StringIO() + self.stderr = StringIO() + sys.stdout = self.stdout + sys.stderr = self.stderr + + def tearDown(self): + shutil.rmtree(self.workspace.build_root) + shutil.rmtree(self.workspace.source_root) + sys.stdout = self._orig_stdout + sys.stderr = self._orig_stderr + shell.dry_run = False + self.workspace = None + self.toolchain = None + self.args = None + + def test_build(self): + # Test disabled until we've moved to cmake toolchains + True +# cmark = CMark( +# args=self.args, +# toolchain=self.toolchain, +# source_dir=self.workspace.source_root, +# build_dir=self.workspace.build_root) + +# cmark.build(host_target=self.host.name) +# _cmake = cmake.CMake(self.args, self.toolchain) + +# self.assertEqual(self.stdout.getvalue(), """\ +# + pushd {build_dir} +# + {cmake} -DCMAKE_BUILD_TYPE:STRING={build_variant} {cmake_args} {source_dir} +# + popd +# + {cmake} --build {build_dir} --config {build_variant} -- all +# """.format(build_dir=self.workspace.build_root, +# source_dir=self.workspace.source_root, +# cmake=self.toolchain.cmake, +# cmake_args=' '.join(_cmake.common_options()), +# build_variant=self.args.cmark_build_variant)) diff --git a/utils/swift_build_support/tests/products/test_earlyswiftdriver.py b/utils/swift_build_support/tests/products/test_earlyswiftdriver.py new file mode 100644 index 0000000000000..25a5902ca62ae --- /dev/null +++ b/utils/swift_build_support/tests/products/test_earlyswiftdriver.py @@ -0,0 +1,83 @@ +# tests/products/test_ninja.py ----------------------------------*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2021 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See https://swift.org/LICENSE.txt for license information +# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# ---------------------------------------------------------------------------- + +import argparse +import os +import shutil +import sys +import tempfile +import unittest +try: + # py2 + from StringIO import StringIO +except ImportError: + # py3 + from io import StringIO + +from swift_build_support import shell +from swift_build_support.products import EarlySwiftDriver +from swift_build_support.targets import StdlibDeploymentTarget +from swift_build_support.toolchain import host_toolchain +from swift_build_support.workspace import Workspace + + +class CMarkTestCase(unittest.TestCase): + + def setUp(self): + # Setup workspace + tmpdir1 = os.path.realpath(tempfile.mkdtemp()) + tmpdir2 = os.path.realpath(tempfile.mkdtemp()) + os.makedirs(os.path.join(tmpdir1, 'cmark')) + + self.workspace = Workspace(source_root=tmpdir1, + build_root=tmpdir2) + + self.host = StdlibDeploymentTarget.host_target() + + # Setup toolchain + self.toolchain = host_toolchain() + self.toolchain.cc = '/path/to/cc' + self.toolchain.cxx = '/path/to/cxx' + + self.cross_compile_hosts = ["macosx-arm64", "linux-x86_64", "linux-aarch64"] + + # Setup args + self.args = argparse.Namespace( + cross_compile_hosts=self.cross_compile_hosts) + + # Setup shell + shell.dry_run = True + self._orig_stdout = sys.stdout + self._orig_stderr = sys.stderr + self.stdout = StringIO() + self.stderr = StringIO() + sys.stdout = self.stdout + sys.stderr = self.stderr + + def tearDown(self): + shutil.rmtree(self.workspace.build_root) + shutil.rmtree(self.workspace.source_root) + sys.stdout = self._orig_stdout + sys.stderr = self._orig_stderr + shell.dry_run = False + self.workspace = None + self.toolchain = None + self.args = None + + def test_should_build(self): + early_swift_driver = EarlySwiftDriver( + args=self.args, + toolchain=self.toolchain, + source_dir=self.workspace.source_root, + build_dir=self.workspace.build_root) + + for target in self.cross_compile_hosts: + self.assertFalse(early_swift_driver.should_build(target)) diff --git a/validation-test/BuildSystem/infer_dumps_deps_if_verbose_build.test b/validation-test/BuildSystem/infer_dumps_deps_if_verbose_build.test index 6b0a58687d397..f2916a4a44164 100644 --- a/validation-test/BuildSystem/infer_dumps_deps_if_verbose_build.test +++ b/validation-test/BuildSystem/infer_dumps_deps_if_verbose_build.test @@ -4,18 +4,10 @@ # REQUIRES: standalone_build -# Build and install the SwiftPM dependencies first. -# -# CHECK: --- Installing cmark --- -# CHECK: --- Installing llvm --- -# CHECK: --- Installing swift --- -# CHECK: --- Installing llbuild --- - # Just make sure we compute the build graph/emit output. # # CHECK: -- Build Graph Inference -- # CHECK: Initial Product List: -# CHECK: cmark # CHECK: llvm # CHECK: swift # CHECK: Final Build Order: @@ -23,6 +15,13 @@ # CHECK: llvm # CHECK: swift +# Build and install the SwiftPM dependencies first. +# +# CHECK: --- Installing cmark --- +# CHECK: --- Installing llvm --- +# CHECK: --- Installing swift --- +# CHECK: --- Installing llbuild --- + # Then make sure we are installing/building SwiftPM last. # # CHECK: --- Building swiftpm --- diff --git a/validation-test/BuildSystem/skip_cmark_swift_llvm.test b/validation-test/BuildSystem/skip_cmark_swift_llvm.test index b703a4f5b6f26..65f83da2c9222 100644 --- a/validation-test/BuildSystem/skip_cmark_swift_llvm.test +++ b/validation-test/BuildSystem/skip_cmark_swift_llvm.test @@ -2,15 +2,15 @@ # RUN: %empty-directory(%t) # RUN: mkdir -p %t -# RUN: SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --install-all --cmake %cmake --skip-build-cmark 2>&1 | %FileCheck --check-prefix=SKIP-CMARK-CHECK %s +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --install-all --cmake %cmake --skip-build-cmark 2>&1 | %FileCheck --check-prefix=SKIP-CMARK-CHECK %s # RUN: %empty-directory(%t) # RUN: mkdir -p %t -# RUN: SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --install-all --cmake %cmake --skip-build-llvm 2>&1 | %FileCheck --check-prefix=SKIP-LLVM-CHECK %s +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --install-all --cmake %cmake --skip-build-llvm 2>&1 | %FileCheck --check-prefix=SKIP-LLVM-CHECK %s # RUN: %empty-directory(%t) # RUN: mkdir -p %t -# RUN: SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --install-all --cmake %cmake --skip-build-swift 2>&1 | %FileCheck --check-prefix=SKIP-SWIFT-CHECK %s +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --install-all --cmake %cmake --skip-build-swift 2>&1 | %FileCheck --check-prefix=SKIP-SWIFT-CHECK %s # SKIP-CMARK-CHECK-NOT: cmake --build {{.*}}cmark- # SKIP-CMARK-CHECK: cmake --build {{.*}}llvm- @@ -20,16 +20,16 @@ # SKIP-CMARK-CHECK: --- Installing swift --- # SKIP-LLVM-CHECK: cmake --build {{.*}}cmark- +# SKIP-LLVM-CHECK: --- Installing cmark --- # SKIP-LLVM-CHECK: cmake --build {{.*}}llvm-tblgen # SKIP-LLVM-CHECK: cmake --build {{.*}}swift- -# SKIP-LLVM-CHECK: --- Installing cmark --- # SKIP-LLVM-CHECK-NOT: --- Installing llvm --- # SKIP-LLVM-CHECK: --- Installing swift --- # SKIP-SWIFT-CHECK: cmake --build {{.*}}cmark- +# SKIP-SWIFT-CHECK: --- Installing cmark --- # SKIP-SWIFT-CHECK: cmake --build {{.*}}llvm- # SKIP-SWIFT-CHECK-NOT: cmake --build {{.*}}swift- -# SKIP-SWIFT-CHECK: --- Installing cmark --- # SKIP-SWIFT-CHECK: --- Installing llvm --- # SKIP-SWIFT-CHECK-NOT: --- Installing swift ---