Skip to content

Commit a61d116

Browse files
drexinDougGregor
authored andcommitted
Revert "Revert "[Build] Make cmark build a build-script product (swiftlang#37102)""
This reverts commit 3150086. (cherry picked from commit 7cfabf5)
1 parent 40e4263 commit a61d116

File tree

10 files changed

+507
-17
lines changed

10 files changed

+507
-17
lines changed

utils/build-script

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -856,11 +856,12 @@ class BuildScriptInvocation(object):
856856

857857
"""
858858

859+
if self.args.build_cmark:
860+
before_impl_product_classes.append(products.CMark)
861+
859862
# FIXME: This is a weird division (returning a list of class objects),
860863
# but it matches the existing structure of the `build-script-impl`.
861864
impl_product_classes = []
862-
if self.args.build_cmark:
863-
impl_product_classes.append(products.CMark)
864865

865866
# If --skip-build-llvm is passed in, LLVM cannot be completely disabled, as
866867
# Swift still needs a few LLVM targets like tblgen to be built for it to be
@@ -989,6 +990,17 @@ class BuildScriptInvocation(object):
989990

990991
# Execute each "pass".
991992

993+
# Pre-build-script-impl products...
994+
# Note: currently only supports building for the host.
995+
for host_target in all_host_names:
996+
for product_class in before_impl_product_classes:
997+
if product_class.is_build_script_impl_product():
998+
continue
999+
if not product_class.is_before_build_script_impl_product():
1000+
continue
1001+
# Execute clean, build, test, install
1002+
self.execute_product_build_steps(product_class, host_target)
1003+
9921004
# Build...
9931005
for host_target in all_hosts:
9941006
# FIXME: We should only compute these once.

utils/build_swift/build_swift/driver_arguments.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ def create_argument_parser():
282282
help='instead of building, write JSON to stdout containing '
283283
'various values used to build in this configuration')
284284

285+
option(['--reconfigure'], store_true,
286+
help="Reconfigure all projects as we build")
287+
285288
option('--legacy-impl', store_true('legacy_impl'),
286289
help='use legacy implementation')
287290

utils/build_swift/tests/expected_options.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
'native_llvm_tools_path': None,
196196
'native_swift_tools_path': None,
197197
'dump_config': False,
198+
'reconfigure': False,
198199
'relocate_xdg_cache_home_under_build_subdir': False,
199200
'show_sdks': False,
200201
'skip_build': False,
@@ -500,6 +501,7 @@ class BuildScriptImplOption(_BaseOption):
500501

501502
SetTrueOption('--legacy-impl', dest='legacy_impl'),
502503
SetTrueOption('--infer', dest='infer_dependencies'),
504+
SetTrueOption('--reconfigure'),
503505

504506
EnableOption('--android'),
505507
EnableOption('--build-external-benchmarks'),
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# swift_build_support/products/product.py -----------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2021 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See https://swift.org/LICENSE.txt for license information
9+
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
import os
14+
15+
from . import product
16+
from .. import cmake
17+
from .. import shell
18+
19+
20+
class CMakeProduct(product.Product):
21+
def build_with_cmake(self, build_targets, build_type, build_args):
22+
assert self.toolchain.cmake is not None
23+
cmake_build = []
24+
_cmake = cmake.CMake(self.args, self.toolchain)
25+
26+
if self.toolchain.distcc_pump:
27+
cmake_build.append(self.toolchain.distcc_pump)
28+
cmake_build.extend([self.toolchain.cmake, "--build"])
29+
30+
generator_output_path = ""
31+
if self.args.cmake_generator == "Ninja":
32+
generator_output_path = os.path.join(self.build_dir, "build.ninja")
33+
34+
cmake_cache_path = os.path.join(self.build_dir, "CMakeCache.txt")
35+
if self.args.reconfigure or not os.path.isfile(cmake_cache_path) or \
36+
(generator_output_path and not os.path.isfile(generator_output_path)):
37+
if not os.path.exists(self.build_dir):
38+
os.makedirs(self.build_dir)
39+
40+
# Use `cmake-file-api` in case it is available.
41+
query_dir = os.path.join(self.build_dir, ".cmake", "api", "v1", "query")
42+
if not os.path.exists(query_dir):
43+
os.makedirs(query_dir)
44+
open(os.path.join(query_dir, "codemodel-v2"), 'a').close()
45+
open(os.path.join(query_dir, "cache-v2"), 'a').close()
46+
47+
env = None
48+
if self.toolchain.distcc:
49+
env = {
50+
"DISTCC_HOSTS": "localhost,lzo,cpp"
51+
}
52+
53+
with shell.pushd(self.build_dir):
54+
shell.call([self.toolchain.cmake] + list(self.cmake_options) +
55+
list(_cmake.common_options()) +
56+
self.args.extra_cmake_options + [self.source_dir],
57+
env=env)
58+
59+
if not self.args.skip_build or self.product_name() == "llvm":
60+
if self.args.cmake_generator == "Xcode":
61+
# Xcode generator uses "ALL_BUILD" instead of "all".
62+
# Also, xcodebuild uses -target instead of bare names.
63+
build_targets = build_targets.copy()
64+
build_targets = [val for target in build_targets
65+
for val in ["-target",
66+
target if target != "all"
67+
else "ALL_BUILD"]]
68+
69+
# Xcode can't restart itself if it turns out we need to reconfigure.
70+
# Do an advance build to handle that.
71+
shell.call(cmake_build + [self.build_dir, build_type])
72+
73+
shell.call(cmake_build + [self.build_dir, "--config", build_type, "--"]
74+
+ build_args + build_targets)
75+
76+
def test_with_cmake(self, executable_target, results_targets,
77+
build_type, build_args):
78+
assert self.toolchain.cmake is not None
79+
cmake_build = []
80+
81+
if self.toolchain.distcc_pump:
82+
cmake_build.append(self.toolchain.distcc_pump)
83+
cmake_args = [self.toolchain.cmake, "--build", self.build_dir,
84+
"--config", build_type, "--"]
85+
cmake_build.extend(cmake_args + build_args)
86+
87+
def target_flag(target):
88+
if self.args.cmake_generator == "Xcode":
89+
return ["-target", target]
90+
return [target]
91+
92+
if executable_target:
93+
shell.call(cmake_build + target_flag(executable_target))
94+
95+
for target in results_targets:
96+
if target:
97+
test_target = target
98+
print("--- %s ---" % target)
99+
if test_target.startswith("check-swift") and self.args.test_paths:
100+
test_target = test_target + "-custom"
101+
102+
shell.call(cmake_build + target_flag(test_target))
103+
104+
print("--- %s finished ---" % target)
105+
106+
def install_with_cmake(self, install_targets, install_destdir):
107+
assert self.toolchain.cmake is not None
108+
cmake_build = []
109+
110+
if self.toolchain.distcc_pump:
111+
cmake_build.append(self.toolchain.distcc_pump)
112+
cmake_args = [self.toolchain.cmake, "--build", self.build_dir, "--"]
113+
cmake_build.extend(cmake_args + install_targets)
114+
115+
environment = {'DESTDIR': install_destdir}
116+
shell.call(cmake_build, env=environment)

utils/swift_build_support/swift_build_support/products/cmark.py

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,110 @@
1010
#
1111
# ----------------------------------------------------------------------------
1212

13-
from . import product
13+
from build_swift.build_swift.wrappers import xcrun
1414

15+
from . import cmake_product
1516

16-
class CMark(product.Product):
17+
18+
class CMark(cmake_product.CMakeProduct):
1719
@classmethod
1820
def is_build_script_impl_product(cls):
1921
"""is_build_script_impl_product -> bool
2022
2123
Whether this product is produced by build-script-impl.
2224
"""
25+
return False
26+
27+
@classmethod
28+
def is_before_build_script_impl_product(cls):
29+
"""is_before_build_script_impl_product -> bool
30+
31+
Whether this product is build before any build-script-impl products.
32+
"""
2333
return True
2434

2535
# This is the root of the build-graph, so it doesn't have any dependencies.
2636
@classmethod
2737
def get_dependencies(cls):
2838
return []
39+
40+
def should_build(self, host_target):
41+
"""should_build() -> Bool
42+
43+
Whether or not this product should be built with the given arguments.
44+
"""
45+
return self.args.build_cmark
46+
47+
def build(self, host_target):
48+
"""build() -> void
49+
50+
Perform the build, for a non-build-script-impl product.
51+
"""
52+
self.cmake_options.define('CMAKE_BUILD_TYPE:STRING',
53+
self.args.cmark_build_variant)
54+
55+
(platform, arch) = host_target.split('-')
56+
57+
if host_target.startswith("macosx") or \
58+
host_target.startswith("iphone") or \
59+
host_target.startswith("appletv") or \
60+
host_target.startswith("watch"):
61+
62+
cmake_os_sysroot = xcrun.sdk_path(platform)
63+
64+
cmake_osx_deployment_target = ''
65+
if platform == "macosx":
66+
cmake_osx_deployment_target = self.args.darwin_deployment_version_osx
67+
68+
common_c_flags = ' '.join(self.common_cross_c_flags(platform, arch))
69+
70+
self.cmake_options.define('CMAKE_C_FLAGS', common_c_flags)
71+
self.cmake_options.define('CMAKE_CXX_FLAGS', common_c_flags)
72+
self.cmake_options.define('CMAKE_OSX_SYSROOT:PATH', cmake_os_sysroot)
73+
self.cmake_options.define('CMAKE_OSX_DEPLOYMENT_TARGET',
74+
cmake_osx_deployment_target)
75+
self.cmake_options.define('CMAKE_OSX_ARCHITECTURES', arch)
76+
77+
self.build_with_cmake(["all"], self.args.cmark_build_variant, [])
78+
79+
def should_test(self, host_target):
80+
"""should_test() -> Bool
81+
82+
Whether or not this product should be tested with the given arguments.
83+
"""
84+
if self.is_cross_compile_target(host_target):
85+
return False
86+
87+
return self.args.test
88+
89+
def test(self, host_target):
90+
"""
91+
Perform the test phase for the product.
92+
93+
This phase might build and execute the product tests.
94+
"""
95+
executable_target = 'api_test'
96+
results_targets = ['test']
97+
if self.args.cmake_generator == 'Xcode':
98+
# Xcode generator uses "RUN_TESTS" instead of "test".
99+
results_targets = ['RUN_TESTS']
100+
101+
self.test_with_cmake(executable_target, results_targets,
102+
self.args.cmark_build_variant, [])
103+
104+
def should_install(self, host_target):
105+
"""should_install() -> Bool
106+
107+
Whether or not this product should be installed with the given
108+
arguments.
109+
"""
110+
return self.args.install_all
111+
112+
def install(self, host_target):
113+
"""
114+
Perform the install phase for the product.
115+
116+
This phase might copy the artifacts from the previous phases into a
117+
destination directory.
118+
"""
119+
self.install_with_cmake(["install"], self.host_install_destdir(host_target))

utils/swift_build_support/swift_build_support/products/product.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ def __init__(self, args, toolchain, source_dir, build_dir):
155155
self.source_dir = source_dir
156156
self.build_dir = build_dir
157157
self.cmake_options = cmake.CMakeOptions()
158+
self.common_c_flags = ['-Wno-unknown-warning-option',
159+
'-Werror=unguarded-availability-new']
158160

159161
def is_release(self):
160162
"""is_release() -> Bool
@@ -179,6 +181,73 @@ def install_toolchain_path(self, host_target):
179181
return targets.toolchain_path(install_destdir,
180182
self.args.install_prefix)
181183

184+
def should_include_host_in_lipo(self, host_target):
185+
if self.args.cross_compile_hosts:
186+
if host_target.startswith("macosx") or \
187+
host_target.startswith("iphone") or \
188+
host_target.startswith("appletv") or \
189+
host_target.startswith("watch"):
190+
return True
191+
return False
192+
193+
def host_install_destdir(self, host_target):
194+
if self.args.cross_compile_hosts:
195+
# If cross compiling tools, install into a host-specific subdirectory.
196+
if self.should_include_host_in_lipo(host_target):
197+
# If this is one of the hosts we should lipo,
198+
# install in to a temporary subdirectory.
199+
return '%s/intermediate-install/%s' % \
200+
(self.args.install_destdir, host_target)
201+
elif host_target == "merged-hosts":
202+
# This assumes that all hosts are merged to the lipo.
203+
return self.args.install_destdir
204+
else:
205+
return '%s/%s' % (self.args.install_destdir, host_target)
206+
else:
207+
return self.args.install_destdir
208+
209+
def is_cross_compile_target(self, host_target):
210+
return self.args.cross_compile_hosts and \
211+
host_target in self.args.cross_compile_hosts
212+
213+
# TODO: Remove once we've moved over to cmake toolchains
214+
def common_cross_c_flags(self, platform, arch):
215+
cross_flags = []
216+
217+
if platform == 'macosx':
218+
target = '{}-apple-macosx{}'.format(
219+
arch, self.args.darwin_deployment_version_osx)
220+
cross_flags.extend(['-arch', arch, '-target', target])
221+
elif platform == 'iphonesimulator':
222+
target = '{}-apple-ios{}'.format(
223+
arch, self.args.darwin_deployment_version_ios)
224+
cross_flags.extend(['-arch', arch, '-target', target])
225+
elif platform == 'iphoneos':
226+
target = '{}-apple-ios{}'.format(
227+
arch, self.args.darwin_deployment_version_ios)
228+
cross_flags.extend(['-arch', arch, '-target', target])
229+
elif platform == 'appletvsimulator':
230+
target = '{}-apple-tvos{}'.format(
231+
arch, self.args.darwin_deployment_version_tvos)
232+
cross_flags.extend(['-arch', arch, '-target', target])
233+
elif platform == 'appletvos':
234+
target = '{}-apple-tvos{}'.format(
235+
arch, self.args.darwin_deployment_version_tvos)
236+
cross_flags.extend(['-arch', arch, '-target', target])
237+
elif platform == 'watchsimulator':
238+
target = '{}-apple-watchos{}'.format(
239+
arch, self.args.darwin_deployment_version_watchos)
240+
cross_flags.extend(['-arch', arch, '-target', target])
241+
elif platform == 'watchos':
242+
target = '{}-apple-watchos{}'.format(
243+
arch, self.args.darwin_deployment_version_watchos)
244+
cross_flags.extend(['-arch', arch, '-target', target])
245+
246+
if self.is_release():
247+
cross_flags.append('-fno-stack-protector')
248+
249+
return self.common_c_flags + cross_flags
250+
182251

183252
class ProductBuilder(object):
184253
"""

0 commit comments

Comments
 (0)