Skip to content

Commit c2d8cc7

Browse files
committed
[benchmark] Add support for building out of tree via build-script against the just built swift.
I recently broke the out of tree build by mistake [its fixed now ; )]. This inspired me to make it easy to test this behavior by adding support to build-script/cmake/etc for running an external benchmark build via AddExternalProjects. Now I can just call build-script with --build-external-benchmarks and thats it! It should just work! It already helped me to avoid breaking the external build twice! I hope that eventually we get this on a bot to make sure it keeps working [or even added to the smoke tests ; )]. *NOTE* This is disabled by default so it will not affect normal builds. *NOTE* This just builds the external benchmarks. There is an rpath issue that prevents you from running them (the benchmarks have the rpath set as if they are next to the stdlib, but they are not. This can be fixed in a few different ways, but I do not have time to finish implementing it = (. But this commit is a good first step and at least detects build errors.
1 parent 574b05d commit c2d8cc7

File tree

8 files changed

+174
-6
lines changed

8 files changed

+174
-6
lines changed

CMakeLists.txt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ else()
6666
endif()
6767

6868
option(SWIFT_BUILD_PERF_TESTSUITE
69-
"Create targets for swift performance benchmarks."
69+
"Create in-tree targets for building swift performance benchmarks."
70+
FALSE)
71+
72+
option(SWIFT_BUILD_EXTERNAL_PERF_TESTSUITE
73+
"Create out-of-tree targets for building swift performance benchmarks."
7074
FALSE)
7175

7276
option(SWIFT_INCLUDE_TESTS "Create targets for building/running tests." TRUE)
@@ -882,9 +886,16 @@ if(SWIFT_BUILD_DYNAMIC_STDLIB AND SWIFT_INCLUDE_TESTS)
882886
add_subdirectory(tools/swift-reflection-test)
883887
endif()
884888

885-
if(SWIFT_BUILD_PERF_TESTSUITE AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
886-
add_subdirectory(benchmark)
889+
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
890+
if(SWIFT_BUILD_PERF_TESTSUITE)
891+
add_subdirectory(benchmark)
892+
endif()
893+
if(SWIFT_BUILD_EXTERNAL_PERF_TESTSUITE)
894+
include(SwiftExternalBenchmarkBuild)
895+
add_external_benchmark_suite()
896+
endif()
887897
endif()
898+
888899
if(SWIFT_INCLUDE_TESTS)
889900
add_subdirectory(test)
890901
add_subdirectory(unittests)

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ endforeach()
231231

232232
message("--")
233233
message("-- Swift Benchmark Suite:")
234+
message("-- SWIFT_BENCHMARK_BUILT_STANDALONE = ${SWIFT_BENCHMARK_BUILT_STANDALONE}")
234235
message("-- SWIFT_EXEC = ${SWIFT_EXEC}")
235236
message("-- SWIFT_LIBRARY_PATH = ${SWIFT_LIBRARY_PATH}")
236237
message("-- CLANG_EXEC = ${CLANG_EXEC}")

benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,16 @@ function(swift_benchmark_compile)
395395
list(APPEND platform_executables ${new_output_exec})
396396
endforeach()
397397

398-
set(executable_target "swift-benchmark-${SWIFT_BENCHMARK_COMPILE_PLATFORM}-${arch}")
398+
# If we are building standalone, we add the -external suffix to all of our
399+
# cmake target names. This enables the main swift build to simple create
400+
# -external targets and forward them via AddExternalProject to the
401+
# standalone benchmark project. The reason why this is necessary is that we
402+
# want to be able to support in-tree and out-of-tree benchmark builds at the
403+
# same time implying that we need some sort of way to distinguish the
404+
# in-tree (which don't have the suffix) from the out of tree target (which
405+
# do).
406+
translate_flag(SWIFT_BENCHMARK_BUILT_STANDALONE "-external" external)
407+
set(executable_target "swift-benchmark-${SWIFT_BENCHMARK_COMPILE_PLATFORM}-${arch}${external}")
399408

400409
add_custom_target("${executable_target}"
401410
DEPENDS ${platform_executables})

benchmark/cmake/modules/SwiftBenchmarkUtils.cmake

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,19 @@ function(precondition var)
2727
endif()
2828
endif()
2929
endfunction()
30+
31+
# Translate a yes/no variable to the presence of a given string in a
32+
# variable.
33+
#
34+
# Usage:
35+
# translate_flag(is_set flag_name var_name)
36+
#
37+
# If is_set is true, sets ${var_name} to ${flag_name}. Otherwise,
38+
# unsets ${var_name}.
39+
function(translate_flag is_set flag_name var_name)
40+
if(${is_set})
41+
set("${var_name}" "${flag_name}" PARENT_SCOPE)
42+
else()
43+
set("${var_name}" "" PARENT_SCOPE)
44+
endif()
45+
endfunction()
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
2+
include(CMakeParseArguments)
3+
include(LLVMExternalProjectUtils)
4+
include(SwiftUtils)
5+
6+
# This is the name of the target on the parent cmake side that is associated
7+
# with an external project target.
8+
#
9+
# If LLVMExternalProjectUtils refactors its external target code, so we can
10+
# easily add individual forwarded targets with different dependencies, this can
11+
# be removed.
12+
function(compute_external_target_name target_name_out target)
13+
string(REPLACE ":" ";" target_list ${target})
14+
list(GET target_list 0 target)
15+
list(LENGTH target_list target_list_len)
16+
if(${target_list_len} GREATER 1)
17+
list(GET target_list 1 target_name)
18+
else()
19+
set(target_name "${target}")
20+
endif()
21+
22+
set(${target_name_out} "${target_name}" PARENT_SCOPE)
23+
endfunction()
24+
25+
function(compute_stdlib_dependencies stdlib_dependencies_out platform)
26+
foreach(stdlib_dependency ${UNIVERSAL_LIBRARY_NAMES_${platform}})
27+
string(FIND "${stdlib_dependency}" "Unittest" find_output)
28+
if("${find_output}" STREQUAL "-1")
29+
list(APPEND stdlib_dependencies "${stdlib_dependency}")
30+
endif()
31+
endforeach()
32+
set(${stdlib_dependencies_out} "${stdlib_dependencies}" PARENT_SCOPE)
33+
endfunction()
34+
35+
set(ONLY_PLATFORMS "macosx" "iphoneos" "appletvos" "watchos")
36+
37+
function (get_platform_from_target target_platform_out target)
38+
foreach (platform ${ONLY_PLATFORMS})
39+
string(FIND "${target}" "${platform}" FOUND_TARGET_PLATFORM)
40+
if (NOT FOUND_TARGET_PLATFORM)
41+
continue()
42+
endif()
43+
44+
set(${target_platform_out} "${platform}" PARENT_SCOPE)
45+
break()
46+
endforeach()
47+
endfunction()
48+
49+
function (compute_target_stdlib_dependencies dependencies_out target)
50+
get_platform_from_target(target_platform ${target})
51+
precondition(target_platform
52+
MESSAGE "Failed to find a platform for ${target_platform}")
53+
compute_stdlib_dependencies(stdlib_dependencies ${target_platform})
54+
set(${dependencies_out} ${stdlib_dependencies} PARENT_SCOPE)
55+
endfunction()
56+
57+
function (add_external_benchmark_suite)
58+
set(name swift-benchmark)
59+
set(src_dir ${SWIFT_SOURCE_DIR}/benchmark)
60+
set(bin_dir ${SWIFT_BINARY_DIR}/external-benchmark/binary)
61+
set(stamp_dir ${SWIFT_BINARY_DIR}/external-benchmark/stamps)
62+
set(prefix_dir ${SWIFT_BINARY_DIR}/external-benchmark/prefix)
63+
64+
set(bench_targets Benchmark_O Benchmark_Onone Benchmark_Ounchecked)
65+
set(library_targets swift-benchmark-macosx-x86_64-external)
66+
67+
set(all_stdlib_dependencies)
68+
foreach (target ${library_targets})
69+
compute_target_stdlib_dependencies(stdlib_dependencies ${target})
70+
precondition(stdlib_dependencies)
71+
# Add dependencies from all of our stdlib dependencies to
72+
# swift-bench-configure. This will ensure the stdlib is ready to be poked at
73+
# in the configure script if we ever want to do so.
74+
list(APPEND all_stdlib_dependencies ${stdlib_dependencies})
75+
endforeach()
76+
77+
llvm_ExternalProject_add(swift-bench ${src_dir}
78+
SOURCE_DIR ${src_dir}
79+
EXCLUDE_FROM_ALL
80+
DEPENDS swift ${all_stdlib_dependencies}
81+
EXTRA_TARGETS ${bench_targets} ${library_targets}
82+
CMAKE_ARGS
83+
-DSWIFT_EXEC=${SWIFT_BINARY_DIR}/bin/swiftc
84+
-DSWIFT_LIBRARY_PATH=${SWIFT_BINARY_DIR}/lib/swift
85+
-DCMAKE_C_COMPILER=${PATH_TO_CLANG_BUILD}/bin/clang
86+
-DCMAKE_CXX_COMPILER=${PATH_TO_CLANG_BUILD}/bin/clang++
87+
PASSTHROUGH_PREFIXES SWIFT_BENCHMARK
88+
)
89+
endfunction()

utils/build-script

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ class HostSpecificConfiguration(object):
127127
test = (
128128
deployment_platform not in invocation.platforms_to_skip_test)
129129
test_host_only = None
130-
build_benchmark = build and deployment_target.supports_benchmark
130+
dt_supports_benchmark = deployment_target.supports_benchmark
131+
build_benchmarks = build and dt_supports_benchmark
132+
build_external_benchmarks = all([build, dt_supports_benchmark,
133+
args.build_external_benchmarks])
134+
131135
# FIXME: Note, `build-script-impl` computed a property here
132136
# w.r.t. testing, but it was actually unused.
133137

@@ -161,13 +165,20 @@ class HostSpecificConfiguration(object):
161165
else:
162166
self.swift_stdlib_build_targets.append(
163167
"swift-test-stdlib-" + name)
164-
if build_benchmark:
168+
if build_benchmarks:
165169
self.swift_benchmark_build_targets.append(
166170
"swift-benchmark-" + name)
167171
# FIXME: This probably should respect `args.benchmark`, but
168172
# a typo in build-script-impl meant we always would do this.
169173
self.swift_benchmark_run_targets.append(
170174
"check-swift-benchmark-" + name)
175+
176+
if build_external_benchmarks:
177+
# Add support for the external benchmarks.
178+
self.swift_benchmark_build_targets.append(
179+
"swift-benchmark-{}-external".format(name))
180+
self.swift_benchmark_run_targets.append(
181+
"check-swift-benchmark-{}-external".format(name))
171182
if test:
172183
if test_host_only:
173184
suffix = "-non-executable"
@@ -506,6 +517,9 @@ class BuildScriptInvocation(object):
506517
"--skip-build-swift"]
507518
if not args.build_benchmarks:
508519
impl_args += ["--skip-build-benchmarks"]
520+
# Currently we do not build external benchmarks by default.
521+
if args.build_external_benchmarks:
522+
impl_args += ["--skip-build-external-benchmarks=0"]
509523
if not args.build_foundation:
510524
impl_args += ["--skip-build-foundation"]
511525
if not args.build_xctest:

utils/build-script-impl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ KNOWN_SETTINGS=(
126126
skip-build-libdispatch "" "set to skip building libdispatch"
127127
skip-build-libicu "" "set to skip building libicu"
128128
skip-build-benchmarks "" "set to skip building Swift Benchmark Suite"
129+
skip-build-external-benchmarks "1" "set to skip building the external Swift Benchmark Suite. (skipped by default)"
129130
skip-build-playgroundlogger "" "set to skip building PlaygroundLogger"
130131
skip-build-playgroundsupport "" "set to skip building PlaygroundSupport"
131132
skip-test-cmark "" "set to skip testing CommonMark"
@@ -1324,6 +1325,7 @@ function calculate_targets_for_host() {
13241325
local test_this_target=1
13251326
local test_host_only=
13261327
local build_benchmark_this_target=
1328+
local build_external_benchmark_this_target=
13271329
local test_benchmark_this_target=
13281330

13291331
case ${stdlib_deployment_target} in
@@ -1352,6 +1354,7 @@ function calculate_targets_for_host() {
13521354
build_for_this_target=$(not ${SKIP_BUILD_OSX})
13531355
test_this_target=$(not ${SKIP_TEST_OSX})
13541356
build_benchmark_this_target=$(not ${SKIP_BUILD_OSX})
1357+
build_external_benchmark_this_target=$(not ${SKIP_BUILD_OSX})
13551358
test_benchmark_this_target=$(not ${SKIP_BUILD_OSX})
13561359
;;
13571360
iphoneos-*)
@@ -1363,10 +1366,12 @@ function calculate_targets_for_host() {
13631366
test_this_target=
13641367
fi
13651368
build_benchmark_this_target=$(not ${SKIP_BUILD_IOS_DEVICE})
1369+
build_external_benchmark_this_target=$(not ${SKIP_BUILD_IOS_DEVICE})
13661370

13671371
# Never build iOS armv7s benchmarks.
13681372
if [[ "${stdlib_deployment_target}" == "iphoneos-armv7s" ]]; then
13691373
build_benchmark_this_target=
1374+
build_external_benchmark_this_target=
13701375
fi
13711376
;;
13721377
iphonesimulator-x86_64)
@@ -1391,6 +1396,7 @@ function calculate_targets_for_host() {
13911396
test_this_target=
13921397
fi
13931398
build_benchmark_this_target=$(not ${SKIP_BUILD_TVOS_DEVICE})
1399+
build_external_benchmark_this_target=$(not ${SKIP_BUILD_TVOS_DEVICE})
13941400
;;
13951401
appletvsimulator-*)
13961402
swift_sdk="TVOS_SIMULATOR"
@@ -1406,6 +1412,7 @@ function calculate_targets_for_host() {
14061412
test_this_target=
14071413
fi
14081414
build_benchmark_this_target=$(not ${SKIP_BUILD_WATCHOS_DEVICE})
1415+
build_external_benchmark_this_target=$(not ${SKIP_BUILD_WATCHOS_DEVICE})
14091416
;;
14101417
watchsimulator-*)
14111418
swift_sdk="WATCHOS_SIMULATOR"
@@ -1443,6 +1450,16 @@ function calculate_targets_for_host() {
14431450
SWIFT_RUN_BENCHMARK_TARGETS+=("check-swift-benchmark-${stdlib_deployment_target}")
14441451
fi
14451452
fi
1453+
1454+
if [[ "$(true_false ${SKIP_BUILD_EXTERNAL_BENCHMARKS})" == "FALSE" ]] &&
1455+
[[ "${build_external_benchmark_this_target}" ]] &&
1456+
[[ "${is_in_build_list}" ]] ; then
1457+
SWIFT_BENCHMARK_TARGETS+=("swift-benchmark-${stdlib_deployment_target}-external")
1458+
if [[ $(not ${SKIP_TEST_BENCHMARK}) ]] ; then
1459+
SWIFT_RUN_BENCHMARK_TARGETS+=("check-swift-benchmark-${stdlib_deployment_target}-external")
1460+
fi
1461+
fi
1462+
14461463
if [[ "${test_this_target}" ]] && [[ "${is_in_build_list}" ]]; then
14471464
test_target_suffix=""
14481465
if [[ -n "${test_host_only}" ]] ; then
@@ -2098,13 +2115,16 @@ for host in "${ALL_HOSTS[@]}"; do
20982115

20992116
# Don't build benchmarks and tests when building cross compiler.
21002117
build_perf_testsuite_this_time=false
2118+
build_external_perf_testsuite_this_time=false
21012119
build_tests_this_time=false
21022120

21032121
native_llvm_tools_path="$(build_directory "${LOCAL_HOST}" llvm)/bin"
21042122
native_clang_tools_path="$(build_directory "${LOCAL_HOST}" llvm)/bin"
21052123
native_swift_tools_path="$(build_directory "${LOCAL_HOST}" swift)/bin"
21062124
else
2125+
# FIXME: Why is the next line not using false_true?
21072126
build_perf_testsuite_this_time=$(true_false "$(not ${SKIP_BUILD_BENCHMARKS})")
2127+
build_external_perf_testsuite_this_time=$(false_true "${SKIP_BUILD_EXTERNAL_BENCHMARKS}")
21082128
build_tests_this_time=${SWIFT_INCLUDE_TESTS}
21092129
fi
21102130

@@ -2162,6 +2182,7 @@ for host in "${ALL_HOSTS[@]}"; do
21622182
-DSWIFT_BUILD_DYNAMIC_SDK_OVERLAY:BOOL=$(true_false "${BUILD_SWIFT_DYNAMIC_SDK_OVERLAY}")
21632183
-DSWIFT_BUILD_STATIC_SDK_OVERLAY:BOOL=$(true_false "${BUILD_SWIFT_STATIC_SDK_OVERLAY}")
21642184
-DSWIFT_BUILD_PERF_TESTSUITE:BOOL=$(true_false "${build_perf_testsuite_this_time}")
2185+
-DSWIFT_BUILD_EXTERNAL_PERF_TESTSUITE:BOOL=$(true_false "${build_external_perf_testsuite_this_time}")
21652186
-DSWIFT_BUILD_EXAMPLES:BOOL=$(true_false "${BUILD_SWIFT_EXAMPLES}")
21662187
-DSWIFT_INCLUDE_TESTS:BOOL=$(true_false "${build_tests_this_time}")
21672188
-DSWIFT_INSTALL_COMPONENTS:STRING="${SWIFT_INSTALL_COMPONENTS}"

utils/build_swift/driver_arguments.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ def _apply_default_arguments(args):
153153
args.build_watchos = False
154154
args.build_android = False
155155
args.build_benchmarks = False
156+
args.build_external_benchmarks = False
156157
args.build_lldb = False
157158
args.build_llbuild = False
158159
args.build_swiftpm = False
@@ -771,6 +772,12 @@ def create_argument_parser():
771772
action=arguments.action.optional_false,
772773
help="skip building Swift Benchmark Suite")
773774

775+
run_build_group.add_argument(
776+
"--build-external-benchmarks",
777+
dest='build_external_benchmarks',
778+
action=arguments.action.optional_true,
779+
help="skip building Swift Benchmark Suite")
780+
774781
skip_test_group = parser.add_argument_group(
775782
title="Skip testing specified targets")
776783
skip_test_group.add_argument(

0 commit comments

Comments
 (0)