Skip to content

Commit 81606a8

Browse files
committed
Adding additional logging to troubleshoot the bootstap failure
1 parent 6fcb906 commit 81606a8

File tree

3 files changed

+126
-80
lines changed

3 files changed

+126
-80
lines changed

Utilities/bootstrap

Lines changed: 96 additions & 41 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

@@ -159,6 +186,13 @@ def add_build_args(parser):
159186
parser.add_argument(
160187
"--cross-compile-config",
161188
help="Swift flags to cross-compile SwiftPM with itself")
189+
parser.add_argument(
190+
"--no-local-deps",
191+
default=True,
192+
action="store_false",
193+
dest="use_local_deps",
194+
help="When set, do not use local dependencies"
195+
)
162196

163197
def add_test_args(parser):
164198
"""Configures the parser with the arguments necessary for the test action."""
@@ -253,36 +287,47 @@ def parse_test_args(args):
253287

254288
def get_swiftc_path(args):
255289
"""Returns the path to the Swift compiler."""
290+
logging.debug("Getting path to swiftc...")
256291
if args.swiftc_path:
257292
swiftc_path = os.path.abspath(args.swiftc_path)
293+
logging.debug("path provided via command line argument. swiftc_path is %r", swiftc_path)
258294
elif os.getenv("SWIFT_EXEC"):
259-
swiftc_path = os.path.realpath(os.getenv("SWIFT_EXEC"))
295+
swiftc_path = os.getenv("SWIFT_EXEC")
296+
logging.debug("SWIFT_EXEC env set. swiftc_path set to %r", swiftc_path)
260297
elif platform.system() == 'Darwin':
298+
logging.debug("we are on darwin, so calling `xcrun --find swiftc`")
261299
swiftc_path = call_output(
262300
["xcrun", "--find", "swiftc"],
263301
stderr=subprocess.PIPE,
264-
verbose=args.verbose
302+
verbose=args.verbose,
265303
)
304+
logging.debug("swiftc_path is set to %r", swiftc_path)
266305
else:
267306
swiftc_path = call_output(["which", "swiftc"], verbose=args.verbose)
307+
logging.debug("calling 'which swiftc'. path is %r", swiftc_path)
268308

269309
if os.path.basename(swiftc_path) == 'swift':
270310
swiftc_path = swiftc_path + 'c'
311+
logging.debug("appending to path, it is now %r", swiftc_path)
271312

313+
logging.debug("swiftc_path set to %r", swiftc_path)
272314
if os.path.exists(swiftc_path):
315+
logging.debug("swiftc_path exists.. returning...")
273316
return swiftc_path
274-
error("unable to find swiftc at %s" % swiftc_path)
317+
logging.error("unable to find swiftc at %s", swiftc_path)
318+
raise BinaryNotFound(tool="swiftc", path=swiftc_path)
275319

276320
def get_tool_path(args, tool):
277321
"""Returns the path to the specified tool."""
322+
logging.debug("Searching for %s tool", tool)
278323
path = getattr(args, tool + "_path", None)
279324
if path is not None:
280325
return os.path.abspath(path)
281326
elif platform.system() == 'Darwin':
282327
return call_output(
283328
["xcrun", "--find", tool],
284329
stderr=subprocess.PIPE,
285-
verbose=args.verbose
330+
verbose=args.verbose,
286331
)
287332
else:
288333
return call_output(["which", tool], verbose=args.verbose)
@@ -294,26 +339,30 @@ def get_build_target(args, cross_compile=False):
294339
if cross_compile:
295340
cross_compile_json = json.load(open(args.cross_compile_config))
296341
command += ['-target', cross_compile_json["target"]]
342+
logging.debug("Running command >>> %r", command)
297343
target_info_json = subprocess.check_output(command,
298-
stderr=subprocess.PIPE, universal_newlines=True).strip()
344+
stderr=subprocess.PIPE, universal_newlines=True, env=os.environ).strip()
345+
logging.debug("Command returned: %r", target_info_json)
299346
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:
347+
return args.target_info["target"]["unversionedTriple" if platform.system() == 'Darwin' else "triple"]
348+
except subprocess.CalledProcessError as cpe:
349+
logging.debug("Command failed...")
304350
# Temporary fallback for Darwin.
305351
if platform.system() == 'Darwin':
306-
return 'x86_64-apple-macosx'
352+
macOS_default = 'x86_64-apple-macosx'
353+
logging.debug("we are on Darwin. defaulting to %r", macOS_default)
354+
return macOS_default
307355
else:
308-
error(str(e))
356+
logging.error("get build targets: %s", str(cpe))
357+
raise cpe
309358

310359
# -----------------------------------------------------------
311360
# Actions
312361
# -----------------------------------------------------------
313362

314363
def clean(args):
315364
"""Cleans the build artifacts."""
316-
note("Cleaning")
365+
logging.info("Cleaning")
317366
parse_global_args(args)
318367

319368
call(["rm", "-rf", args.build_dir], verbose=args.verbose)
@@ -323,6 +372,7 @@ def build(args):
323372
parse_build_args(args)
324373

325374
if args.bootstrap:
375+
logging.info("Building bootstrap")
326376
# Build llbuild if its build path is not passed in.
327377
if not "llbuild" in args.build_dirs:
328378
build_llbuild(args)
@@ -359,7 +409,7 @@ def test(args):
359409
"""Builds SwiftPM, then tests itself."""
360410
build(args)
361411

362-
note("Testing")
412+
logging.info("Testing")
363413
parse_test_args(args)
364414
cmd = [
365415
os.path.join(args.bin_dir, "swift-test")
@@ -376,7 +426,7 @@ def test(args):
376426
return
377427

378428
# Build SwiftPM with the integrated driver.
379-
note("Bootstrap with the integrated Swift driver")
429+
logging.info("Bootstrap with the integrated Swift driver")
380430
build_swiftpm_with_swiftpm(args,integrated_swift_driver=True)
381431

382432
# Test SwiftPM with the integrated driver. Only the build and
@@ -439,7 +489,7 @@ def install_swiftpm(prefix, args):
439489
for tool in ["swift-build", "swift-test", "swift-run", "swift-package-collection", "swift-package-registry", "swift-sdk", "swift-experimental-sdk"]:
440490
src = "swift-package"
441491
dest = os.path.join(cli_tool_dest, tool)
442-
note("Creating tool symlink from %s to %s" % (src, dest))
492+
logging.info("Creating tool symlink from %s to %s", src, dest)
443493
symlink_force(src, dest)
444494

445495
# Install the PackageDescription/CompilerPluginSupport libraries and associated modules.
@@ -488,7 +538,7 @@ def install_file(args, src, destination, destination_is_directory=True, ignored_
488538
else:
489539
dest = destination
490540

491-
note("Installing %s to %s" % (src, dest))
541+
logging.info("Installing %s to %s", src, dest)
492542
if os.path.isdir(src):
493543
shutil.copytree(src, dest, ignore=shutil.ignore_patterns(*ignored_patterns))
494544
else:
@@ -521,8 +571,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake
521571
"-DCMAKE_RANLIB:PATH=%s" % (args.ranlib_path),
522572
] + cmake_args + [source_path]
523573

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

527576
mkdir_p(build_dir)
528577
call(cmd, cwd=build_dir, verbose=True)
@@ -540,7 +589,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake
540589

541590
def build_llbuild(args):
542591
"""Builds LLBuild using CMake."""
543-
note("Building llbuild")
592+
logging.info("Building llbuild")
544593

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

573622
def build_dependency(args, target_name, common_cmake_flags = [], non_darwin_cmake_flags = []):
574-
note("Building " + target_name)
623+
logging.info("Building dependency %s", target_name)
575624
args.build_dirs[target_name] = os.path.join(args.target_dir, target_name)
576625

577626
cmake_flags = common_cmake_flags
@@ -587,8 +636,8 @@ def add_rpath_for_cmake_build(args, rpath):
587636
"Adds the given rpath to the CMake-built swift-bootstrap"
588637
swift_build = os.path.join(args.bootstrap_dir, "bin/swift-bootstrap")
589638
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)
639+
logging.info(' '.join(add_rpath_cmd))
640+
subprocess.call(add_rpath_cmd, stderr=subprocess.PIPE, env=os.environ)
592641

593642
def get_swift_backdeploy_library_paths(args):
594643
if platform.system() == 'Darwin':
@@ -598,7 +647,7 @@ def get_swift_backdeploy_library_paths(args):
598647

599648
def build_swiftpm_with_cmake(args):
600649
"""Builds SwiftPM using CMake."""
601-
note("Building SwiftPM (with CMake)")
650+
logging.info("Building SwiftPM (with CMake)")
602651

603652
cmake_flags = [
604653
get_llbuild_cmake_arg(args),
@@ -642,19 +691,20 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
642691
swiftpm_args = []
643692

644693
if args.bootstrap:
645-
note("Building SwiftPM (with a freshly built swift-bootstrap)")
694+
logging.info("Building SwiftPM (with a freshly built swift-bootstrap)")
646695
swiftpm_args.append("SWIFTPM_CUSTOM_LIBS_DIR=" + os.path.join(args.bootstrap_dir, "pm"))
647696
swiftpm_args.append(os.path.join(args.bootstrap_dir, "bin/swift-bootstrap"))
648697
else:
649-
note("Building SwiftPM (with a prebuilt swift-build)")
698+
logging.info("Building SwiftPM (with a prebuilt swift-build)")
650699
swiftpm_args.append(args.swift_build_path or os.path.join(os.path.split(args.swiftc_path)[0], "swift-build"))
651700
swiftpm_args.append("--disable-sandbox")
652701

653702
# Enforce resolved versions to avoid stray dependencies that aren't local.
654703
swiftpm_args.append("--force-resolved-versions")
655704

656705
# Any leftover resolved file from a run without `SWIFTCI_USE_LOCAL_DEPS` needs to be deleted.
657-
if os.path.exists("Package.resolved"):
706+
if os.path.exists("Package.resolved") and args.use_local_deps:
707+
logging.debug("removing Package.resolve")
658708
os.remove("Package.resolved")
659709

660710
if integrated_swift_driver:
@@ -680,25 +730,27 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
680730

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

736+
logging.debug("build target: %r", args.build_target)
686737
args.platform_path = None
687738
for path in args.target_info["paths"]["runtimeLibraryPaths"]:
688739
args.platform_path = re.search(r"(lib/swift/([^/]+))$", path)
689740
if args.platform_path:
690741
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
742+
else:
743+
# this gets called if the for loop does not break
744+
logging.error(
745+
"the command `%s -print-target-info` didn't return a valid runtime library path",
746+
args.swiftc_path
696747
)
748+
raise SystemExit(1)
697749

698750
full_cmd = get_swiftpm_env_cmd(args) + cmd + get_swiftpm_flags(args)
699751
if cwd is None:
700752
cwd = args.project_root
701-
call(full_cmd, cwd=cwd, verbose=True)
753+
call_output(full_cmd, cwd=cwd, stderr=True, verbose=True)
702754

703755
# -----------------------------------------------------------
704756
# Build-related helper functions
@@ -727,8 +779,9 @@ def get_llbuild_source_path(args):
727779
llbuild_path = os.path.join(args.project_root, "..", "llbuild")
728780
if os.path.exists(llbuild_path):
729781
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)
782+
logging.info("clone llbuild next to swiftpm directory; see development docs: https://github.com/swiftlang/swift-package-manager/blob/master/Documentation/Contributing.md")
783+
logging.error("unable to find llbuild source directory at %s", llbuild_path)
784+
raise BinaryNotFound(tool="llbuild", path=llbuild_path)
732785

733786
def get_swiftpm_env_cmd(args):
734787
"""Returns the environment variable command to run SwiftPM binaries."""
@@ -739,7 +792,8 @@ def get_swiftpm_env_cmd(args):
739792

740793
if args.llbuild_link_framework:
741794
env_cmd.append("SWIFTPM_LLBUILD_FWK=1")
742-
env_cmd.append("SWIFTCI_USE_LOCAL_DEPS=1")
795+
if args.use_local_deps:
796+
env_cmd.append("SWIFTCI_USE_LOCAL_DEPS=1")
743797
env_cmd.append("SWIFTPM_MACOS_DEPLOYMENT_TARGET=%s" % g_macos_deployment_target)
744798

745799
if not '-macosx' in args.build_target and args.command == 'install':
@@ -823,7 +877,8 @@ def get_swiftpm_flags(args):
823877
elif cross_compile_hosts.startswith('android-'):
824878
build_flags.extend(["--destination", args.cross_compile_config])
825879
else:
826-
error("cannot cross-compile for %s" % cross_compile_hosts)
880+
logging.error("cannot cross-compile for %s", cross_compile_hosts)
881+
raise SystemExit(1)
827882

828883
# Ensure we are not sharing the module cache with concurrent builds in CI
829884
local_module_cache_path=os.path.join(args.build_dir, "module-cache")
@@ -837,6 +892,6 @@ def get_swiftpm_flags(args):
837892
return build_flags
838893

839894
if __name__ == '__main__':
840-
log_timestamp("start")
895+
logging.info("start")
841896
main()
842-
log_timestamp("end")
897+
logging.info("end")

0 commit comments

Comments
 (0)