Skip to content

Commit 7cfabf5

Browse files
committed
Revert "Revert "[Build] Make cmark build a build-script product (#37102)""
This reverts commit 3150086.
1 parent eb8514c commit 7cfabf5

File tree

11 files changed

+494
-20
lines changed

11 files changed

+494
-20
lines changed

utils/build-script

+4-3
Original file line numberDiff line numberDiff line change
@@ -886,11 +886,12 @@ class BuildScriptInvocation(object):
886886
if self.args.build_early_swift_driver:
887887
before_impl_product_classes.append(products.EarlySwiftDriver)
888888

889+
if self.args.build_cmark:
890+
before_impl_product_classes.append(products.CMark)
891+
889892
# FIXME: This is a weird division (returning a list of class objects),
890893
# but it matches the existing structure of the `build-script-impl`.
891894
impl_product_classes = []
892-
if self.args.build_cmark:
893-
impl_product_classes.append(products.CMark)
894895

895896
# If --skip-build-llvm is passed in, LLVM cannot be completely disabled, as
896897
# Swift still needs a few LLVM targets like tblgen to be built for it to be
@@ -1026,7 +1027,7 @@ class BuildScriptInvocation(object):
10261027

10271028
# Pre-build-script-impl products...
10281029
# Note: currently only supports building for the host.
1029-
for host_target in [self.args.host_target]:
1030+
for host_target in all_host_names:
10301031
for product_class in before_impl_product_classes:
10311032
if product_class.is_build_script_impl_product():
10321033
continue

utils/build_swift/build_swift/driver_arguments.py

+3
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ def create_argument_parser():
288288
help='instead of building, write JSON to stdout containing '
289289
'various values used to build in this configuration')
290290

291+
option(['--reconfigure'], store_true,
292+
help="Reconfigure all projects as we build")
293+
291294
option('--legacy-impl', store_true('legacy_impl'),
292295
help='use legacy implementation')
293296

utils/build_swift/tests/expected_options.py

+2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@
197197
'native_llvm_tools_path': None,
198198
'native_swift_tools_path': None,
199199
'dump_config': False,
200+
'reconfigure': False,
200201
'relocate_xdg_cache_home_under_build_subdir': False,
201202
'show_sdks': False,
202203
'skip_build': False,
@@ -506,6 +507,7 @@ class BuildScriptImplOption(_BaseOption):
506507

507508
SetTrueOption('--legacy-impl', dest='legacy_impl'),
508509
SetTrueOption('--infer', dest='infer_dependencies'),
510+
SetTrueOption('--reconfigure'),
509511

510512
EnableOption('--android'),
511513
EnableOption('--build-external-benchmarks'),
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

+87-4
Original file line numberDiff line numberDiff line change
@@ -10,27 +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
"""
23-
return True
25+
return False
2426

2527
@classmethod
2628
def is_before_build_script_impl_product(cls):
2729
"""is_before_build_script_impl_product -> bool
2830
2931
Whether this product is build before any build-script-impl products.
3032
"""
31-
return False
33+
return True
3234

3335
# This is the root of the build-graph, so it doesn't have any dependencies.
3436
@classmethod
3537
def get_dependencies(cls):
3638
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/earlyswiftdriver.py

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ def is_before_build_script_impl_product(cls):
4141
return True
4242

4343
def should_build(self, host_target):
44+
if self.is_cross_compile_target(host_target):
45+
return False
46+
4447
if self.args.build_early_swift_driver:
4548
if toolchain.host_toolchain().find_tool("swift") is None:
4649
warn_msg = 'Host toolchain could not locate a '\

utils/swift_build_support/swift_build_support/products/product.py

+69
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ def __init__(self, args, toolchain, source_dir, build_dir):
166166
self.source_dir = source_dir
167167
self.build_dir = build_dir
168168
self.cmake_options = cmake.CMakeOptions()
169+
self.common_c_flags = ['-Wno-unknown-warning-option',
170+
'-Werror=unguarded-availability-new']
169171

170172
def is_release(self):
171173
"""is_release() -> Bool
@@ -190,6 +192,73 @@ def install_toolchain_path(self, host_target):
190192
return targets.toolchain_path(install_destdir,
191193
self.args.install_prefix)
192194

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

194263
class ProductBuilder(object):
195264
"""

0 commit comments

Comments
 (0)