Skip to content

Commit 1e5f790

Browse files
committed
[Build] allow to generate symbols for a subset of binaries
This would be needed to reduce overall build times in scenarios when generating symbols for all binaries is too expensive and/or not needed. Addresses rdar://76865276
1 parent b903a6c commit 1e5f790

File tree

5 files changed

+149
-1
lines changed

5 files changed

+149
-1
lines changed

utils/build-script

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,12 @@ class BuildScriptInvocation(object):
813813
' '.join(args.llvm_ninja_targets_for_cross_compile_hosts)
814814
]
815815

816+
if args.darwin_symroot_path_filters:
817+
impl_args += [
818+
"--darwin_symroot_path_filters=%s" %
819+
' '.join(args.darwin_symroot_path_filters)
820+
]
821+
816822
# Compute the set of host-specific variables, which we pass through to
817823
# the build script via environment variables.
818824
host_specific_variables = self.compute_host_specific_variables()

utils/build-script-impl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ KNOWN_SETTINGS=(
103103
darwin-deployment-version-watchos "2.0" "minimum deployment target version for watchOS"
104104
darwin-install-extract-symbols "" "whether to extract symbols with dsymutil during installations"
105105
darwin-install-extract-symbols-use-just-built-dsymutil "1" "whether we should extract symbols using the just built dsymutil"
106+
darwin-symroot-path-filters "" "space-separated list of path patterns to consider for symbol generation"
106107
darwin-overlay-target "" "single overlay target to build, dependencies are computed later"
107108
darwin-sdk-deployment-targets "xctest-ios-8.0" "semicolon-separated list of triples like 'fookit-ios-9.0;barkit-watchos-9.0'"
108109
darwin-stdlib-install-name-dir "" "the directory of the install_name for standard library dylibs"
@@ -3111,6 +3112,26 @@ function printJSONEndTimestamp() {
31113112
printJSONTimestamp ${command} "end"
31123113
}
31133114

3115+
function grep_that_allows_no_matches() {
3116+
# This will not cause the script to fail
3117+
# if no line in the input matches the pattern
3118+
grep "$@" || test $? = 1
3119+
}
3120+
3121+
function filter_paths() {
3122+
if [[ -n "$1" ]]; then
3123+
local -a filters
3124+
filters=($1)
3125+
local -a grep_arguments
3126+
for cfilter in "${filters[@]}"; do
3127+
grep_arguments+=('-e' "$cfilter")
3128+
done
3129+
grep_that_allows_no_matches "${grep_arguments[@]}"
3130+
else
3131+
cat
3132+
fi
3133+
}
3134+
31143135
for host in "${ALL_HOSTS[@]}"; do
31153136
# Check if we should perform this action.
31163137
if ! [[ $(should_execute_action "${host}-extractsymbols") ]]; then
@@ -3150,7 +3171,9 @@ for host in "${ALL_HOSTS[@]}"; do
31503171
# Copy executables and shared libraries from the `host_install_destdir` to
31513172
# INSTALL_SYMROOT and run dsymutil on them.
31523173
(cd "${CURRENT_INSTALL_DIR}" &&
3153-
find ./"${CURRENT_PREFIX}" -perm -0111 -type f -print | cpio --insecure -pdm -v "${host_symroot}")
3174+
find ./"${CURRENT_PREFIX}" -perm -0111 -type f -print | \
3175+
filter_paths "${DARWIN_SYMROOT_PATH_FILTERS}" | \
3176+
cpio --insecure -pdm -v "${host_symroot}")
31543177

31553178
dsymutil_path=
31563179
if [[ -n "${DARWIN_INSTALL_EXTRACT_SYMBOLS_USE_JUST_BUILT_DSYMUTIL}" ]]; then

utils/build_swift/build_swift/driver_arguments.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,12 @@ def create_argument_parser():
684684
option('--symbols-package', store_path,
685685
help='if provided, an archive of the symbols directory will be '
686686
'generated at this path')
687+
option('--darwin-symroot-path-filters', append,
688+
type=argparse.ShellSplitType(),
689+
help='Space separated list of patterns used to match '
690+
'a subset of files to generate symbols for. '
691+
'Only supported on Darwin. Can be called multiple times '
692+
'to add multiple such options.')
687693

688694
# -------------------------------------------------------------------------
689695
in_group('Build variant')

utils/build_swift/tests/expected_options.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
defaults.DARWIN_DEPLOYMENT_VERSION_TVOS,
137137
'darwin_deployment_version_watchos':
138138
defaults.DARWIN_DEPLOYMENT_VERSION_WATCHOS,
139+
'darwin_symroot_path_filters': [],
139140
'darwin_xcrun_toolchain': None,
140141
'distcc': False,
141142
'sccache': False,
@@ -688,6 +689,7 @@ class BuildScriptImplOption(_BaseOption):
688689
AppendOption('--test-paths'),
689690
AppendOption('--llvm-ninja-targets'),
690691
AppendOption('--llvm-ninja-targets-for-cross-compile-hosts'),
692+
AppendOption('--darwin-symroot-path-filters'),
691693

692694
UnsupportedOption('--build-jobs'),
693695
UnsupportedOption('--common-cmake-options'),
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# REQUIRES: standalone_build
2+
# REQUIRES: OS=macosx
3+
4+
# RUN: %empty-directory(%t)
5+
# RUN: mkdir -p %t
6+
# RUN: split-file %s %t
7+
8+
# Even though we are running build-script with dry-run,
9+
# symbol extraction runs real commands against the file system.
10+
# Thus we generate a series of files
11+
# to exercise the filtering logic
12+
# RUN: mkdir -p %t/destdir/bin
13+
# RUN: mkdir -p %t/destdir/lib
14+
# RUN: %swiftc_driver %t/hello.swift -o %t/destdir/bin/swift-demangle
15+
# RUN: %swiftc_driver %t/hello.swift -o %t/destdir/bin/swift-def-to-yaml-converter
16+
# RUN: ln -s %t/destdir/swift-demangle %t/destdir/bin/swift-api-digester
17+
# RUN: cp %t/swift-util.py %t/destdir/bin
18+
# RUN: chmod a+x %t/destdir/bin/swift-util.py
19+
# RUN: %swiftc_driver %t/dylib.swift -emit-library -o %t/destdir/lib/libswiftDemangle.dylib
20+
# RUN: %swiftc_driver %t/dylib.swift -emit-library -o %t/destdir/lib/lib_InternalSwiftScan.dylib
21+
# RUN: %swiftc_driver %t/dylib.swift -emit-library -static -o %t/destdir/lib/libswiftASTSectionImporter.a
22+
# RUN: mkdir -p %t/symroot/macosx-%target-cpu
23+
24+
# test build-script-impl on its own
25+
# RUN: SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script-impl --dry-run --build-dir=%t/build --workspace=%swift_src_root/.. --cmake %cmake --only-execute macosx-%target-cpu-extractsymbols --host-cc /usr/bin/true --darwin-install-extract-symbols=1 --host-target=macosx-%target-cpu --install-symroot=%t/symroot --install-destdir=%t/destdir --build-jobs=1 --darwin-symroot-path-filters="/lib/ /swift-demangle" 2>&1 | tee %t/build-script-impl-output.txt
26+
# RUN: %FileCheck --input-file=%t/build-script-impl-output.txt %s
27+
# RUN: %FileCheck --input-file=%t/build-script-impl-output.txt --check-prefixes CHECK-SKIPPED %s
28+
29+
# ensure build-script pass the argument to build-script-impl
30+
# RUN: %empty-directory(%t/symroot)
31+
# RUN: mkdir -p %t/symroot/macosx-%target-cpu
32+
# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --cmake %cmake --darwin-install-extract-symbols=1 --install-destdir=%t/destdir --toolchain-prefix="" --install-symroot=%t/symroot --darwin-symroot-path-filters="/lib/ /swift-demangle" --jobs=1 2>&1 | tee %t/build-script-output.txt
33+
# RUN: %FileCheck --input-file=%t/build-script-output.txt %s
34+
# RUN: %FileCheck --input-file=%t/build-script-output.txt --check-prefixes CHECK-SKIPPED %s
35+
36+
# ensure we get all the values if we specify the flag multiple times
37+
# RUN: %empty-directory(%t/symroot)
38+
# RUN: mkdir -p %t/symroot/macosx-%target-cpu
39+
# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --cmake %cmake --darwin-install-extract-symbols=1 --install-destdir=%t/destdir --toolchain-prefix="" --install-symroot=%t/symroot --darwin-symroot-path-filters="/lib/" --darwin-symroot-path-filters="/swift-demangle" --jobs=1 2>&1 | tee %t/build-script-output.txt
40+
# RUN: %FileCheck --input-file=%t/build-script-output.txt %s
41+
# RUN: %FileCheck --input-file=%t/build-script-output.txt --check-prefixes CHECK-SKIPPED %s
42+
43+
44+
# CHECK: --- Extracting symbols ---
45+
46+
# Ensure we copy all the files in lib and the swift-demangle executable
47+
# CHECK-LABEL: cpio
48+
# CHECK-DAG: swift-demangle
49+
# CHECK-DAG: libswiftDemangle.dylib
50+
# CHECK-DAG: lib_InternalSwiftScan.dylib
51+
52+
# Ensure we generate symbols for the file in the symroot
53+
# CHECK-LABEL: "command": "dsymutil", "start"
54+
# CHECK-DAG: dsymutil {{.*}}swift-demangle
55+
# CHECK-DAG: dsymutil {{.*}}libswiftDemangle.dylib
56+
# CHECK-DAG: dsymutil {{.*}}lib_InternalSwiftScan.dylib
57+
58+
# Ensure we strip the files in the installation directory
59+
# (which are not subject to the filters)
60+
# CHECK-LABEL: xcrun_find_tool strip
61+
# CHECK-DAG: strip {{.*}}swift-demangle
62+
# CHECK-DAG: strip {{.*}}swift-def-to-yaml-converter
63+
# CHECK-DAG: strip {{.*}}libswiftDemangle.dylib
64+
# CHECK-DAG: strip {{.*}}lib_InternalSwiftScan.dylib
65+
# CHECK-DAG: strip {{.*}}libswiftASTSectionImporter.a
66+
# CHECK-DAG: strip {{.*}}swift-util.py
67+
68+
# Ensure we codesign dylibs
69+
# CHECK-LABEL: xcrun_find_tool codesign
70+
# CHECK-DAG: codesign {{.*}}libswiftDemangle.dylib
71+
# CHECK-DAG: codesign {{.*}}lib_InternalSwiftScan.dylib
72+
73+
74+
# CHECK-SKIPPED: --- Extracting symbols ---
75+
76+
# Ensure we don't copy files not included by the filters
77+
# CHECK-SKIPPED-LABEL: cpio
78+
# CHECK-SKIPPED-NOT: swift-util.py
79+
# CHECK-SKIPPED-NOT: swift-def-to-yaml-converter
80+
# CHECK-SKIPPED-NOT: libswiftASTSectionImporter.a
81+
# CHECK-SKIPPED-NOT: swift-api-digester
82+
83+
# Ensure we don't generate symbols for files we did not copy
84+
# CHECK-SKIPPED-LABEL: "command": "dsymutil", "start"
85+
# CHECK-SKIPPED-NOT: dsymutil {{.*}}swift-def-to-yaml-converter
86+
# CHECK-SKIPPED-NOT: dsymutil {{.*}}libswiftASTSectionImporter.a
87+
# CHECK-SKIPPED-NOT: dsymutil {{.*}}swift-util.py
88+
# CHECK-SKIPPED-NOT: dsymutil {{.*}}swift-api-digester
89+
90+
# Ensure we don't strip symlinks
91+
# CHECK-SKIPPED-LABEL: xcrun_find_tool strip
92+
# CHECK-SKIPPED-NOT: strip {{.*}}swift-api-digester
93+
94+
# Ensure we don't codesign executables, symlinks,
95+
# static archives and python scripts
96+
# CHECK-SKIPPED-LABEL: xcrun_find_tool codesign
97+
# CHECK-SKIPPED-NOT: codesign {{.*}}swift-demangle
98+
# CHECK-SKIPPED-NOT: codesign {{.*}}libswiftASTSectionImporter.a
99+
# CHECK-SKIPPED-NOT: codesign {{.*}}swift-util.py
100+
# CHECK-SKIPPED-NOT: codesign {{.*}}swift-api-digester
101+
# CHECK-SKIPPED-NOT: codesign {{.*}}swift-def-to-yaml-converter
102+
103+
#--- hello.swift
104+
print("hello")
105+
106+
#--- dylib.swift
107+
func greet(person: String) -> String {
108+
return "Hello \(person)"
109+
}
110+
#--- swift-util.py
111+
print("hello")

0 commit comments

Comments
 (0)