Skip to content

Commit 9d04a05

Browse files
authored
Improve debug logging (#8325)
Update the bootstrap and helpers script to add verbose logging to help troubleshoot the code path taken. Also, update the build-using-self to add command line option to enable xctest/swift-testing tests.
1 parent 60b4913 commit 9d04a05

File tree

3 files changed

+86
-6
lines changed

3 files changed

+86
-6
lines changed

Utilities/bootstrap

+45-2
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,19 @@ else:
5353
class BinaryNotFound(BaseException):
5454

5555
def __init__(self, *, tool: str, path: pathlib.Path):
56-
super().__init__("Unable to find {tool} source directory at {path}")
56+
super().__init__(f"Unable to find {tool} source directory at {path}")
5757

58+
def log_entry_exit(func):
59+
def wrapper(*args, **kwargs):
60+
logging.debug("Starting call to %s ...", func.__name__)
61+
try:
62+
return func(*args, **kwargs)
63+
finally:
64+
logging.debug("Done call to %s ...", func.__name__)
5865

66+
return wrapper
67+
68+
@log_entry_exit
5969
def main():
6070
parser = argparse.ArgumentParser(description="""
6171
This script will build a bootstrapped copy of the Swift Package Manager, and optionally perform extra
@@ -95,6 +105,7 @@ def main():
95105
# Argument parsing
96106
# -----------------------------------------------------------
97107

108+
@log_entry_exit
98109
def add_global_args(parser):
99110
"""Configures the parser with the arguments necessary for all actions."""
100111
parser.add_argument(
@@ -111,6 +122,7 @@ def add_global_args(parser):
111122
action="store_true",
112123
help="whether to always reconfigure cmake")
113124

125+
@log_entry_exit
114126
def add_build_args(parser):
115127
"""Configures the parser with the arguments necessary for build-related actions."""
116128
add_global_args(parser)
@@ -187,6 +199,7 @@ def add_build_args(parser):
187199
"--cross-compile-config",
188200
help="Swift flags to cross-compile SwiftPM with itself")
189201

202+
@log_entry_exit
190203
def add_test_args(parser):
191204
"""Configures the parser with the arguments necessary for the test action."""
192205
add_build_args(parser)
@@ -206,6 +219,7 @@ def add_test_args(parser):
206219
help="whether to skip tests with the integrated driver",
207220
default=True)
208221

222+
@log_entry_exit
209223
def parse_global_args(args):
210224
"""Parses and cleans arguments necessary for all actions."""
211225
# Test if 'build_dirs' and 'source_dirs' exist, and initialise them only if not.
@@ -236,6 +250,7 @@ def parse_global_args(args):
236250
else:
237251
args.sysroot = None
238252

253+
@log_entry_exit
239254
def parse_build_args(args):
240255
"""Parses and cleans arguments necessary for build-related actions."""
241256
parse_global_args(args)
@@ -250,6 +265,8 @@ def parse_build_args(args):
250265
args.build_dirs["llbuild"] = os.path.abspath(args.llbuild_build_dir)
251266

252267
args.swiftc_path = get_swiftc_path(args)
268+
logging.debug("Returned value of get_swiftc_path(args): %r", get_swiftc_path(args))
269+
logging.debug("Settings args.swiftc_path to %r", args.swiftc_path)
253270
args.clang_path = get_tool_path(args, "clang")
254271
args.clangxx_path = get_tool_path(args, "clang++")
255272
if not args.skip_cmake_bootstrap:
@@ -276,10 +293,12 @@ def parse_build_args(args):
276293
args.bootstrap = not args.skip_cmake_bootstrap or \
277294
not os.path.exists(os.path.join(os.path.split(args.swiftc_path)[0], "swift-build"))
278295

296+
@log_entry_exit
279297
def parse_test_args(args):
280298
"""Parses and cleans arguments necessary for the test action."""
281299
parse_build_args(args)
282300

301+
@log_entry_exit
283302
def get_swiftc_path(args):
284303
"""Returns the path to the Swift compiler."""
285304
logging.debug("Getting path to swiftc...")
@@ -307,11 +326,12 @@ def get_swiftc_path(args):
307326

308327
logging.debug("swiftc_path set to %r", swiftc_path)
309328
if os.path.exists(swiftc_path):
310-
logging.debug("swiftc_path exists.. returning...")
329+
logging.debug("swiftc_path exists.. returning %r...", swiftc_path)
311330
return swiftc_path
312331
logging.error("unable to find swiftc at %s", swiftc_path)
313332
raise BinaryNotFound(tool="swiftc", path=swiftc_path)
314333

334+
@log_entry_exit
315335
def get_tool_path(args, tool):
316336
"""Returns the path to the specified tool."""
317337
logging.debug("Searching for %s tool", tool)
@@ -327,6 +347,7 @@ def get_tool_path(args, tool):
327347
else:
328348
return call_output(["which", tool], verbose=args.verbose)
329349

350+
@log_entry_exit
330351
def get_build_target(args, cross_compile=False):
331352
"""Returns the target-triple of the current machine or for cross-compilation."""
332353
try:
@@ -379,13 +400,15 @@ def get_unversioned_build_target(args, cross_compile=False):
379400
# Actions
380401
# -----------------------------------------------------------
381402

403+
@log_entry_exit
382404
def clean(args):
383405
"""Cleans the build artifacts."""
384406
logging.info("Cleaning")
385407
parse_global_args(args)
386408

387409
call(["rm", "-rf", args.build_dir], verbose=args.verbose)
388410

411+
@log_entry_exit
389412
def build(args):
390413
"""Builds SwiftPM using a two-step process: first using CMake, then with itself."""
391414
parse_build_args(args)
@@ -423,6 +446,7 @@ def build(args):
423446

424447
build_swiftpm_with_swiftpm(args,integrated_swift_driver=False)
425448

449+
@log_entry_exit
426450
def test(args):
427451
"""Builds SwiftPM, then tests itself."""
428452
build(args)
@@ -456,6 +480,7 @@ def test(args):
456480
integratedDriverCmd.append("BuildTests;FunctionalTests")
457481
call_swiftpm(args, integratedDriverCmd)
458482

483+
@log_entry_exit
459484
def install(args):
460485
"""Builds SwiftPM, then installs its build products."""
461486
build(args)
@@ -493,6 +518,7 @@ def install(args):
493518
install_dylib(args, "SwiftPMDataModel", args.libswiftpmdatamodel_install_dir, libswiftpmdatamodel_modules)
494519

495520
# Installs the SwiftPM tools and runtime support libraries.
521+
@log_entry_exit
496522
def install_swiftpm(prefix, args):
497523
# Install the swift-package-manager tool and create symlinks to it.
498524
cli_tool_dest = os.path.join(prefix, "bin")
@@ -520,6 +546,7 @@ def install_swiftpm(prefix, args):
520546

521547

522548
# Helper function that installs a dynamic library and a set of modules to a particular directory.
549+
@log_entry_exit
523550
def install_dylib(args, library_name, install_dir, module_names):
524551
# Install the dynamic library itself.
525552
install_binary(args, g_shared_lib_prefix + library_name + g_shared_lib_suffix, install_dir)
@@ -541,6 +568,7 @@ def install_dylib(args, library_name, install_dir, module_names):
541568

542569

543570
# Helper function that installs a single built artifact to a particular directory. The source may be either a file or a directory.
571+
@log_entry_exit
544572
def install_binary(args, binary, destination, destination_is_directory=True, ignored_patterns=[], subpath=None):
545573
if subpath:
546574
basepath = os.path.join(args.bin_dir, subpath)
@@ -549,6 +577,7 @@ def install_binary(args, binary, destination, destination_is_directory=True, ign
549577
src = os.path.join(basepath, binary)
550578
install_file(args, src, destination, destination_is_directory=destination_is_directory, ignored_patterns=ignored_patterns)
551579

580+
@log_entry_exit
552581
def install_file(args, src, destination, destination_is_directory=True, ignored_patterns=[]):
553582
if destination_is_directory:
554583
dest = os.path.join(destination, os.path.basename(src))
@@ -566,6 +595,7 @@ def install_file(args, src, destination, destination_is_directory=True, ignored_
566595
# Build functions
567596
# -----------------------------------------------------------
568597

598+
@log_entry_exit
569599
def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake_env = []):
570600
"""Runs CMake if needed, then builds with Ninja."""
571601
cache_path = os.path.join(build_dir, "CMakeCache.txt")
@@ -605,6 +635,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake
605635

606636
call(ninja_cmd + ninja_args, cwd=build_dir, verbose=args.verbose)
607637

638+
@log_entry_exit
608639
def build_llbuild(args):
609640
"""Builds LLBuild using CMake."""
610641
logging.info("Building llbuild")
@@ -637,6 +668,7 @@ def build_llbuild(args):
637668
args.source_dirs["llbuild"] = get_llbuild_source_path(args)
638669
build_with_cmake(args, flags, [], args.source_dirs["llbuild"], args.build_dirs["llbuild"], cmake_env=cmake_env)
639670

671+
@log_entry_exit
640672
def build_dependency(args, target_name, common_cmake_flags = [], non_darwin_cmake_flags = []):
641673
logging.info("Building dependency %s", target_name)
642674
args.build_dirs[target_name] = os.path.join(args.target_dir, target_name)
@@ -650,19 +682,22 @@ def build_dependency(args, target_name, common_cmake_flags = [], non_darwin_cmak
650682

651683
build_with_cmake(args, cmake_flags, [], args.source_dirs[target_name], args.build_dirs[target_name])
652684

685+
@log_entry_exit
653686
def add_rpath_for_cmake_build(args, rpath):
654687
"Adds the given rpath to the CMake-built swift-bootstrap"
655688
swift_build = os.path.join(args.bootstrap_dir, "bin/swift-bootstrap")
656689
add_rpath_cmd = ["install_name_tool", "-add_rpath", rpath, swift_build]
657690
logging.info(' '.join(add_rpath_cmd))
658691
subprocess.call(add_rpath_cmd, stderr=subprocess.PIPE, env=os.environ)
659692

693+
@log_entry_exit
660694
def get_swift_backdeploy_library_paths(args):
661695
if platform.system() == 'Darwin':
662696
return ['/usr/lib/swift']
663697
else:
664698
return []
665699

700+
@log_entry_exit
666701
def build_swiftpm_with_cmake(args):
667702
"""Builds SwiftPM using CMake."""
668703
logging.info("Building SwiftPM (with CMake)")
@@ -702,6 +737,7 @@ def build_swiftpm_with_cmake(args):
702737
for lib_path in get_swift_backdeploy_library_paths(args):
703738
add_rpath_for_cmake_build(args, lib_path)
704739

740+
@log_entry_exit
705741
def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
706742
"""Builds SwiftPM using the version of SwiftPM built with CMake."""
707743

@@ -745,6 +781,7 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
745781

746782
symlink_force(os.path.join(args.bootstrap_dir, "pm"), os.path.join(lib_dir, "pm"))
747783

784+
@log_entry_exit
748785
def call_swiftpm(args, cmd, cwd=None):
749786
"""Calls a SwiftPM binary with the necessary environment variables and flags."""
750787
logging.info("function args: %r, cmd: %r, cwd: %r", args, cmd, cwd)
@@ -773,16 +810,19 @@ def call_swiftpm(args, cmd, cwd=None):
773810
# Build-related helper functions
774811
# -----------------------------------------------------------
775812

813+
@log_entry_exit
776814
def get_dispatch_cmake_arg(args):
777815
"""Returns the CMake argument to the Dispatch configuration to use for building SwiftPM."""
778816
dispatch_dir = os.path.join(args.dispatch_build_dir, "cmake/modules")
779817
return "-Ddispatch_DIR=" + dispatch_dir
780818

819+
@log_entry_exit
781820
def get_foundation_cmake_arg(args):
782821
"""Returns the CMake argument to the Foundation configuration to use for building SwiftPM."""
783822
foundation_dir = os.path.join(args.foundation_build_dir, "cmake/modules")
784823
return "-DFoundation_DIR=" + foundation_dir
785824

825+
@log_entry_exit
786826
def get_llbuild_cmake_arg(args):
787827
"""Returns the CMake argument to the LLBuild framework/binary to use for building SwiftPM."""
788828
if args.llbuild_link_framework:
@@ -791,6 +831,7 @@ def get_llbuild_cmake_arg(args):
791831
llbuild_dir = os.path.join(args.build_dirs["llbuild"], "cmake/modules")
792832
return "-DLLBuild_DIR=" + llbuild_dir
793833

834+
@log_entry_exit
794835
def get_llbuild_source_path(args):
795836
"""Returns the path to the LLBuild source folder."""
796837
llbuild_path = os.path.join(args.project_root, "..", "llbuild")
@@ -800,6 +841,7 @@ def get_llbuild_source_path(args):
800841
logging.error("unable to find llbuild source directory at %s", llbuild_path)
801842
raise BinaryNotFound(tool="llbuild", path=llbuild_path)
802843

844+
@log_entry_exit
803845
def get_swiftpm_env_cmd(args):
804846
"""Returns the environment variable command to run SwiftPM binaries."""
805847
env_cmd = ["env"]
@@ -846,6 +888,7 @@ def get_swiftpm_env_cmd(args):
846888
]
847889
return env_cmd
848890

891+
@log_entry_exit
849892
def get_swiftpm_flags(args):
850893
"""Returns the flags to run SwiftPM binaries."""
851894
build_flags = [

Utilities/build-using-self

+11-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,14 @@ def get_arguments() -> argparse.Namespace:
6868
choices=[e.value for e in Configuration],
6969
help="The configuraiton to use.",
7070
)
71-
71+
parser.add_argument(
72+
"--enable-swift-testing",
73+
action="store_true",
74+
)
75+
parser.add_argument(
76+
"--enable-xctest",
77+
action="store_true",
78+
)
7279
args = parser.parse_args()
7380
return args
7481

@@ -147,8 +154,10 @@ def main() -> None:
147154
call(
148155
shlex.split(f"swift build --configuration {args.config}"),
149156
)
157+
swift_testing_arg= "--enable-swift-testing" if args.enable_swift_testing else ""
158+
xctest_arg= "--enable-xctest" if args.enable_swift_testing else ""
150159
call(
151-
shlex.split(f"swift test --configuration {args.config} --parallel"),
160+
shlex.split(f"swift test --configuration {args.config} --parallel {swift_testing_arg} {xctest_arg}"),
152161
)
153162

154163
with change_directory(REPO_ROOT_PATH / "IntegrationTests"):

Utilities/helpers.py

+30-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,22 @@ def call(cmd, cwd=None, verbose=False):
7171
except subprocess.CalledProcessError as cpe:
7272
logging.debug("executing command >>> %r with cwd %s", " ".join([str(c) for c in cmd]), cwd)
7373
logging.error(
74-
"Process failure: %s\n[---- START OUTPUT ----]\n%s\n[---- END OUTPUT ----]",
74+
"\n".join([
75+
"Process failure with return code %d: %s",
76+
"[---- START stdout ----]",
77+
"%s",
78+
"[---- END stdout ----]",
79+
"[---- START stderr ----]",
80+
"%s",
81+
"[---- END stderr ----]",
82+
"[---- START OUTPUT ----]",
83+
"%s",
84+
"[---- END OUTPUT ----]",
85+
]),
86+
cpe.returncode,
7587
str(cpe),
88+
cpe.stdout,
89+
cpe.stderr,
7690
cpe.output,
7791
)
7892
raise cpe
@@ -93,8 +107,22 @@ def call_output(cmd, cwd=None, stderr=False, verbose=False):
93107
except subprocess.CalledProcessError as cpe:
94108
logging.debug("executing command >>> %r with cwd %s", " ".join([str(c) for c in cmd]), cwd)
95109
logging.error(
96-
"%s\n[---- START OUTPUT ----]\n%s\n[---- END OUTPUT ----]",
110+
"\n".join([
111+
"Process failure with return code %d: %s",
112+
"[---- START stdout ----]",
113+
"%s",
114+
"[---- END stdout ----]",
115+
"[---- START stderr ----]",
116+
"%s",
117+
"[---- END stderr ----]",
118+
"[---- START OUTPUT ----]",
119+
"%s",
120+
"[---- END OUTPUT ----]",
121+
]),
122+
cpe.returncode,
97123
str(cpe),
124+
cpe.stdout,
125+
cpe.stderr,
98126
cpe.output,
99127
)
100128
raise cpe

0 commit comments

Comments
 (0)