Skip to content

Commit b3798b2

Browse files
authored
pipeline: changes to support nightly toolchain (#8161)
Make changes to ensure success of the self-hosted macOS pipeline that executes using the nightly toolchain. ### Motivation: When enabling the nightly toolchain build, the CI build does not set SDKROOT environment variable on Darwin, which causes some tests to fail ### Modifications: 1. Set SDKROOT in build-using-self when on Darwin. When using the nightly toolchain, the `SDKROOT` environment variable was not set. Explicitely set this to the default xcode installation only when on Darwin. 2. Run the testTestsCanLinkAgainstAsyncExecutable only if it's executed on macOS 15 or never. 3. Add additional logging to troubleshoot the bootstap failure and convert to use python's logging module instead of print statements. Verifies #8137
1 parent d77dad0 commit b3798b2

File tree

5 files changed

+128
-79
lines changed

5 files changed

+128
-79
lines changed

Fixtures/Miscellaneous/TestableAsyncExe/Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import PackageDescription
33

44
let package = Package(
55
name: "TestableAsyncExe",
6+
platforms: [
7+
.macOS(.v10_15),
8+
],
69
targets: [
710
.executableTarget(
811
name: "TestableAsyncExe1"

Tests/FunctionalTests/MiscellaneousTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ final class MiscellaneousTestCase: XCTestCase {
423423
}
424424
}
425425

426+
@available(macOS 15, *)
426427
func testTestsCanLinkAgainstAsyncExecutable() async throws {
427428
#if compiler(<5.10)
428429
try XCTSkipIf(true, "skipping because host compiler doesn't have a fix for symbol conflicts yet")

Utilities/bootstrap

Lines changed: 86 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,31 @@ from __future__ import print_function
1717

1818
import argparse
1919
import json
20+
import logging
2021
import os
22+
import pathlib
2123
import platform
2224
import re
2325
import shutil
2426
import subprocess
25-
from helpers import note, error, symlink_force, mkdir_p, call, call_output, log_timestamp
26-
27+
import sys
28+
from helpers import symlink_force, mkdir_p, call, call_output
29+
30+
31+
logging.basicConfig(
32+
stream=sys.stdout,
33+
format=" | ".join([
34+
f"--- {pathlib.Path(sys.argv[0]).name}", # Prefix script name to the log in an attempt to avoid confusion when parsing logs
35+
"%(asctime)s",
36+
"%(levelname)-7s",
37+
"%(threadName)s",
38+
"%(module)s",
39+
"%(funcName)s",
40+
"Line:%(lineno)d",
41+
"%(message)s",
42+
]),
43+
level=logging.INFO,
44+
)
2745
g_macos_deployment_target = '12.0'
2846

2947
g_shared_lib_prefix = "lib"
@@ -32,6 +50,12 @@ if platform.system() == 'Darwin':
3250
else:
3351
g_shared_lib_suffix = ".so"
3452

53+
class BinaryNotFound(BaseException):
54+
55+
def __init__(self, *, tool: str, path: pathlib.Path):
56+
super().__init__("Unable to find {tool} source directory at {path}")
57+
58+
3559
def main():
3660
parser = argparse.ArgumentParser(description="""
3761
This script will build a bootstrapped copy of the Swift Package Manager, and optionally perform extra
@@ -60,7 +84,10 @@ def main():
6084
parser_install.set_defaults(func=install)
6185
add_build_args(parser_install)
6286

87+
logging.info("sys.argv: %r", sys.argv)
6388
args = parser.parse_args()
89+
# update the root logger level based on the verbose flag
90+
logging.getLogger().setLevel(logging.DEBUG if args.verbose else logging.INFO)
6491
args.func = args.func or build
6592
args.func(args)
6693

@@ -253,36 +280,47 @@ def parse_test_args(args):
253280

254281
def get_swiftc_path(args):
255282
"""Returns the path to the Swift compiler."""
283+
logging.debug("Getting path to swiftc...")
256284
if args.swiftc_path:
257285
swiftc_path = os.path.abspath(args.swiftc_path)
286+
logging.debug("path provided via command line argument. swiftc_path is %r", swiftc_path)
258287
elif os.getenv("SWIFT_EXEC"):
259-
swiftc_path = os.path.realpath(os.getenv("SWIFT_EXEC"))
288+
swiftc_path = os.getenv("SWIFT_EXEC")
289+
logging.debug("SWIFT_EXEC env set. swiftc_path set to %r", swiftc_path)
260290
elif platform.system() == 'Darwin':
291+
logging.debug("we are on darwin, so calling `xcrun --find swiftc`")
261292
swiftc_path = call_output(
262293
["xcrun", "--find", "swiftc"],
263294
stderr=subprocess.PIPE,
264-
verbose=args.verbose
295+
verbose=args.verbose,
265296
)
297+
logging.debug("swiftc_path is set to %r", swiftc_path)
266298
else:
267299
swiftc_path = call_output(["which", "swiftc"], verbose=args.verbose)
300+
logging.debug("calling 'which swiftc'. path is %r", swiftc_path)
268301

269302
if os.path.basename(swiftc_path) == 'swift':
270303
swiftc_path = swiftc_path + 'c'
304+
logging.debug("appending to path, it is now %r", swiftc_path)
271305

306+
logging.debug("swiftc_path set to %r", swiftc_path)
272307
if os.path.exists(swiftc_path):
308+
logging.debug("swiftc_path exists.. returning...")
273309
return swiftc_path
274-
error("unable to find swiftc at %s" % swiftc_path)
310+
logging.error("unable to find swiftc at %s", swiftc_path)
311+
raise BinaryNotFound(tool="swiftc", path=swiftc_path)
275312

276313
def get_tool_path(args, tool):
277314
"""Returns the path to the specified tool."""
315+
logging.debug("Searching for %s tool", tool)
278316
path = getattr(args, tool + "_path", None)
279317
if path is not None:
280318
return os.path.abspath(path)
281319
elif platform.system() == 'Darwin':
282320
return call_output(
283321
["xcrun", "--find", tool],
284322
stderr=subprocess.PIPE,
285-
verbose=args.verbose
323+
verbose=args.verbose,
286324
)
287325
else:
288326
return call_output(["which", tool], verbose=args.verbose)
@@ -294,26 +332,30 @@ def get_build_target(args, cross_compile=False):
294332
if cross_compile:
295333
cross_compile_json = json.load(open(args.cross_compile_config))
296334
command += ['-target', cross_compile_json["target"]]
335+
logging.debug("Running command >>> %r", command)
297336
target_info_json = subprocess.check_output(command,
298-
stderr=subprocess.PIPE, universal_newlines=True).strip()
337+
stderr=subprocess.PIPE, universal_newlines=True, env=os.environ).strip()
338+
logging.debug("Command returned: %r", target_info_json)
299339
args.target_info = json.loads(target_info_json)
300-
if platform.system() == 'Darwin':
301-
return args.target_info["target"]["unversionedTriple"]
302-
return args.target_info["target"]["triple"]
303-
except Exception as e:
340+
return args.target_info["target"]["unversionedTriple" if platform.system() == 'Darwin' else "triple"]
341+
except subprocess.CalledProcessError as cpe:
342+
logging.debug("Command failed...")
304343
# Temporary fallback for Darwin.
305344
if platform.system() == 'Darwin':
306-
return 'x86_64-apple-macosx'
345+
macOS_default = 'x86_64-apple-macosx'
346+
logging.debug("we are on Darwin. defaulting to %r", macOS_default)
347+
return macOS_default
307348
else:
308-
error(str(e))
349+
logging.error("get build targets: %s", str(cpe))
350+
raise cpe
309351

310352
# -----------------------------------------------------------
311353
# Actions
312354
# -----------------------------------------------------------
313355

314356
def clean(args):
315357
"""Cleans the build artifacts."""
316-
note("Cleaning")
358+
logging.info("Cleaning")
317359
parse_global_args(args)
318360

319361
call(["rm", "-rf", args.build_dir], verbose=args.verbose)
@@ -323,6 +365,7 @@ def build(args):
323365
parse_build_args(args)
324366

325367
if args.bootstrap:
368+
logging.info("Building bootstrap")
326369
# Build llbuild if its build path is not passed in.
327370
if not "llbuild" in args.build_dirs:
328371
build_llbuild(args)
@@ -359,7 +402,7 @@ def test(args):
359402
"""Builds SwiftPM, then tests itself."""
360403
build(args)
361404

362-
note("Testing")
405+
logging.info("Testing")
363406
parse_test_args(args)
364407
cmd = [
365408
os.path.join(args.bin_dir, "swift-test")
@@ -376,7 +419,7 @@ def test(args):
376419
return
377420

378421
# Build SwiftPM with the integrated driver.
379-
note("Bootstrap with the integrated Swift driver")
422+
logging.info("Bootstrap with the integrated Swift driver")
380423
build_swiftpm_with_swiftpm(args,integrated_swift_driver=True)
381424

382425
# Test SwiftPM with the integrated driver. Only the build and
@@ -439,7 +482,7 @@ def install_swiftpm(prefix, args):
439482
for tool in ["swift-build", "swift-test", "swift-run", "swift-package-collection", "swift-package-registry", "swift-sdk", "swift-experimental-sdk"]:
440483
src = "swift-package"
441484
dest = os.path.join(cli_tool_dest, tool)
442-
note("Creating tool symlink from %s to %s" % (src, dest))
485+
logging.info("Creating tool symlink from %s to %s", src, dest)
443486
symlink_force(src, dest)
444487

445488
# Install the PackageDescription/CompilerPluginSupport libraries and associated modules.
@@ -488,7 +531,7 @@ def install_file(args, src, destination, destination_is_directory=True, ignored_
488531
else:
489532
dest = destination
490533

491-
note("Installing %s to %s" % (src, dest))
534+
logging.info("Installing %s to %s", src, dest)
492535
if os.path.isdir(src):
493536
shutil.copytree(src, dest, ignore=shutil.ignore_patterns(*ignored_patterns))
494537
else:
@@ -521,8 +564,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake
521564
"-DCMAKE_RANLIB:PATH=%s" % (args.ranlib_path),
522565
] + cmake_args + [source_path]
523566

524-
if args.verbose:
525-
print(' '.join(cmd))
567+
logging.debug(' '.join(cmd))
526568

527569
mkdir_p(build_dir)
528570
call(cmd, cwd=build_dir, verbose=True)
@@ -540,7 +582,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake
540582

541583
def build_llbuild(args):
542584
"""Builds LLBuild using CMake."""
543-
note("Building llbuild")
585+
logging.info("Building llbuild")
544586

545587
# Set where we are going to build llbuild for future steps to find it
546588
args.build_dirs["llbuild"] = os.path.join(args.target_dir, "llbuild")
@@ -571,7 +613,7 @@ def build_llbuild(args):
571613
build_with_cmake(args, flags, [], args.source_dirs["llbuild"], args.build_dirs["llbuild"], cmake_env=cmake_env)
572614

573615
def build_dependency(args, target_name, common_cmake_flags = [], non_darwin_cmake_flags = []):
574-
note("Building " + target_name)
616+
logging.info("Building dependency %s", target_name)
575617
args.build_dirs[target_name] = os.path.join(args.target_dir, target_name)
576618

577619
cmake_flags = common_cmake_flags
@@ -587,8 +629,8 @@ def add_rpath_for_cmake_build(args, rpath):
587629
"Adds the given rpath to the CMake-built swift-bootstrap"
588630
swift_build = os.path.join(args.bootstrap_dir, "bin/swift-bootstrap")
589631
add_rpath_cmd = ["install_name_tool", "-add_rpath", rpath, swift_build]
590-
note(' '.join(add_rpath_cmd))
591-
subprocess.call(add_rpath_cmd, stderr=subprocess.PIPE)
632+
logging.info(' '.join(add_rpath_cmd))
633+
subprocess.call(add_rpath_cmd, stderr=subprocess.PIPE, env=os.environ)
592634

593635
def get_swift_backdeploy_library_paths(args):
594636
if platform.system() == 'Darwin':
@@ -598,7 +640,7 @@ def get_swift_backdeploy_library_paths(args):
598640

599641
def build_swiftpm_with_cmake(args):
600642
"""Builds SwiftPM using CMake."""
601-
note("Building SwiftPM (with CMake)")
643+
logging.info("Building SwiftPM (with CMake)")
602644

603645
cmake_flags = [
604646
get_llbuild_cmake_arg(args),
@@ -642,11 +684,11 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
642684
swiftpm_args = []
643685

644686
if args.bootstrap:
645-
note("Building SwiftPM (with a freshly built swift-bootstrap)")
687+
logging.info("Building SwiftPM (with a freshly built swift-bootstrap)")
646688
swiftpm_args.append("SWIFTPM_CUSTOM_LIBS_DIR=" + os.path.join(args.bootstrap_dir, "pm"))
647689
swiftpm_args.append(os.path.join(args.bootstrap_dir, "bin/swift-bootstrap"))
648690
else:
649-
note("Building SwiftPM (with a prebuilt swift-build)")
691+
logging.info("Building SwiftPM (with a prebuilt swift-build)")
650692
swiftpm_args.append(args.swift_build_path or os.path.join(os.path.split(args.swiftc_path)[0], "swift-build"))
651693
swiftpm_args.append("--disable-sandbox")
652694

@@ -655,6 +697,7 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
655697

656698
# Any leftover resolved file from a run without `SWIFTCI_USE_LOCAL_DEPS` needs to be deleted.
657699
if os.path.exists("Package.resolved"):
700+
logging.debug("removing Package.resolve")
658701
os.remove("Package.resolved")
659702

660703
if integrated_swift_driver:
@@ -680,25 +723,27 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
680723

681724
def call_swiftpm(args, cmd, cwd=None):
682725
"""Calls a SwiftPM binary with the necessary environment variables and flags."""
683-
726+
logging.info("function args: %r, cmd: %r, cwd: %r", args, cmd, cwd)
684727
args.build_target = get_build_target(args, cross_compile=(True if args.cross_compile_config else False))
685728

729+
logging.debug("build target: %r", args.build_target)
686730
args.platform_path = None
687731
for path in args.target_info["paths"]["runtimeLibraryPaths"]:
688732
args.platform_path = re.search(r"(lib/swift/([^/]+))$", path)
689733
if args.platform_path:
690734
break
691-
692-
if not args.platform_path:
693-
error(
694-
"the command `%s -print-target-info` didn't return a valid runtime library path"
695-
% args.swiftc_path
735+
else:
736+
# this gets called if the for loop does not break
737+
logging.error(
738+
"the command `%s -print-target-info` didn't return a valid runtime library path",
739+
args.swiftc_path
696740
)
741+
raise SystemExit(1)
697742

698743
full_cmd = get_swiftpm_env_cmd(args) + cmd + get_swiftpm_flags(args)
699744
if cwd is None:
700745
cwd = args.project_root
701-
call(full_cmd, cwd=cwd, verbose=True)
746+
call_output(full_cmd, cwd=cwd, stderr=True, verbose=True)
702747

703748
# -----------------------------------------------------------
704749
# Build-related helper functions
@@ -727,8 +772,9 @@ def get_llbuild_source_path(args):
727772
llbuild_path = os.path.join(args.project_root, "..", "llbuild")
728773
if os.path.exists(llbuild_path):
729774
return llbuild_path
730-
note("clone llbuild next to swiftpm directory; see development docs: https://github.com/swiftlang/swift-package-manager/blob/master/Documentation/Contributing.md")
731-
error("unable to find llbuild source directory at %s" % llbuild_path)
775+
logging.info("clone llbuild next to swiftpm directory; see development docs: https://github.com/swiftlang/swift-package-manager/blob/master/Documentation/Contributing.md")
776+
logging.error("unable to find llbuild source directory at %s", llbuild_path)
777+
raise BinaryNotFound(tool="llbuild", path=llbuild_path)
732778

733779
def get_swiftpm_env_cmd(args):
734780
"""Returns the environment variable command to run SwiftPM binaries."""
@@ -823,7 +869,8 @@ def get_swiftpm_flags(args):
823869
elif cross_compile_hosts.startswith('android-'):
824870
build_flags.extend(["--destination", args.cross_compile_config])
825871
else:
826-
error("cannot cross-compile for %s" % cross_compile_hosts)
872+
logging.error("cannot cross-compile for %s", cross_compile_hosts)
873+
raise SystemExit(1)
827874

828875
# Ensure we are not sharing the module cache with concurrent builds in CI
829876
local_module_cache_path=os.path.join(args.build_dir, "module-cache")
@@ -837,6 +884,6 @@ def get_swiftpm_flags(args):
837884
return build_flags
838885

839886
if __name__ == '__main__':
840-
log_timestamp("start")
887+
logging.info("start")
841888
main()
842-
log_timestamp("end")
889+
logging.info("end")

0 commit comments

Comments
 (0)