Skip to content

Commit 43f9df2

Browse files
authored
Merge pull request #23814 from atrick/benchmark-cmake
Benchmark cmake: Allow building from a Swift root.
2 parents 9381dee + b127216 commit 43f9df2

File tree

3 files changed

+111
-20
lines changed

3 files changed

+111
-20
lines changed

benchmark/CMakeLists.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ set(BENCHOPTS_MULTITHREADED
253253
"-whole-module-optimization" "-num-threads" "4")
254254
set(BENCHOPTS_SINGLEFILE "")
255255

256+
option(SWIFT_BENCHMARK_USE_OS_LIBRARIES
257+
"Runtime link against the Swift libraries on the target (/usr/lib/swift)."
258+
FALSE)
259+
256260
configure_build()
257261

258262
#===-----------------------------------------------------------------------===#
@@ -268,10 +272,18 @@ configure_sdks()
268272
message("--")
269273
message("-- Swift Benchmark Suite:")
270274
message("-- SWIFT_BENCHMARK_BUILT_STANDALONE = ${SWIFT_BENCHMARK_BUILT_STANDALONE}")
271-
message("-- SWIFT_EXEC = ${SWIFT_EXEC}")
272-
message("-- SWIFT_BENCHMARK_EXTRA_FLAGS = ${SWIFT_BENCHMARK_EXTRA_FLAGS}")
275+
message("-- SWIFT_BENCHMARK_USE_OS_LIBRARIES = ${SWIFT_BENCHMARK_USE_OS_LIBRARIES}")
276+
message("-- SWIFT_EXEC = ${SWIFT_EXEC}")
273277
message("-- SWIFT_LIBRARY_PATH = ${SWIFT_LIBRARY_PATH}")
274-
message("-- CLANG_EXEC = ${CLANG_EXEC}")
278+
if (SWIFT_RPATH_BASE)
279+
message("-- SWIFT_RPATH_BASE = ${SWIFT_RPATH_BASE}")
280+
endif()
281+
if (SWIFT_RPATH)
282+
message("-- SWIFT_RPATH = ${SWIFT_RPATH}")
283+
message("--- ** WARNING ** Benchmarking against Swift-in-the-OS")
284+
endif()
285+
message("-- CLANG_EXEC = ${CLANG_EXEC}")
286+
message("-- SWIFT_BENCHMARK_EXTRA_FLAGS = ${SWIFT_BENCHMARK_EXTRA_FLAGS}")
275287
message("-- SWIFT_OPTIMIZATION_LEVELS = ${SWIFT_OPTIMIZATION_LEVELS}")
276288
message("-- ONLY_PLATFORMS = ${ONLY_PLATFORMS}")
277289
message("-- PAGE_ALIGNMENT_OPTION = ${PAGE_ALIGNMENT_OPTION}")

benchmark/README.md

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ flags:
2828
OS X benchmark driver binaries are placed in `bin` alongside `swiftc`.
2929
Additional platform binaries are placed in the `benchmark/bin` build directory.
3030

31+
The required Swift standard library dylibs are placed in `lib`. The
32+
drivers dynamically link Swift standard library dylibs from a path
33+
relative to their run-time location (../lib/swift) so the standard
34+
library should be distributed alongside them.
35+
3136
Building Independently
3237
----------------------
3338

@@ -43,15 +48,19 @@ The following build options are available:
4348
* `-DSWIFT_LIBRARY_PATH`
4449
* An absolute path to the Swift standard library to use during compilation
4550
(default: `swiftc_directory`/../lib/swift)
51+
* `-DSWIFT_DARWIN_XCRUN_TOOLCHAIN`
52+
* The Xcode toolchain to use when invoking `xcrun` to find `clang`.
53+
(default: XcodeDefault)
4654
* `-DONLY_PLATFORMS`
4755
* A list of platforms to build the benchmarks for
4856
(default: "macosx;iphoneos;appletvos;watchos")
4957
* `-DSWIFT_OPTIMIZATION_LEVELS`
5058
* A list of Swift optimization levels to build against
5159
(default: "O;Onone;Osize")
52-
* `-DSWIFT_BENCHMARK_EMIT_SIB`
53-
* A boolean value indicating whether .sib files should be generated
54-
alongside .o files (default: FALSE)
60+
* `-DSWIFT_BENCHMARK_USE_OS_LIBRARIES`
61+
* Enable this option to link the benchmark binaries against the target
62+
machine's Swift standard library and runtime installed with the OS.
63+
(default: OFF)
5564

5665
The following build targets are available:
5766

@@ -66,13 +75,40 @@ Build steps (with example options):
6675
1. `$ cd benchmark`
6776
2. `$ mkdir build`
6877
3. `$ cd build`
69-
4. `$ cmake ..`
70-
5. `$ make -j8 swift-benchmark-macosx-x86_64`
78+
4. `$ cmake ../benchmark -G Ninja -DSWIFT_EXEC=[path to built swiftc]`
79+
5. `$ ninja swift-benchmark-macosx-x86_64`
80+
81+
Benchmark binaries are placed in `bin`.
82+
83+
The binaries dynamically link Swift standard library dylibs from a
84+
path determined by the configuration. If `SWIFT_LIBRARY_PATH` is set,
85+
they link against the absolute path provided, regardless of where the
86+
binaries are installed. Otherwise, the runtime library path is
87+
relative to the benchmark binary at the time it was executed
88+
(`@executable_path/../lib/swift/<platform>`).
89+
90+
For example, to benchmark against a locally built `swiftc`, including
91+
any standard library changes in that build, you might configure using:
92+
93+
cmake ../benchmark -G Ninja -DSWIFT_EXEC=<src>/swift/build/swift-macosx-x86_64/bin/swiftc
94+
ninja swift-benchmark-iphoneos-arm64
95+
96+
To build against the installed Xcode, simply omit SWIFT_EXEC:
97+
98+
cmake ../benchmark -G Ninja
99+
ninja swift-benchmark-iphoneos-arm64
100+
101+
In both examples above, to run the benchmarks on a device, the dynamic
102+
libraries must then be copied onto the device into the library path
103+
relative to `swiftc`. To benchmark against the target machine's
104+
installed libraries instead, enable
105+
`SWIFT_BENCHMARK_USE_OS_LIBRARIES`.
106+
107+
cmake ../benchmark -G Ninja -DSWIFT_BENCHMARK_USE_OS_LIBRARIES=ON
108+
ninja swift-benchmark-iphoneos-arm64
71109

72-
Benchmark driver binaries are placed in `build/bin` and the required Swift
73-
standard library dylibs are placed in `build/lib`. The drivers dynamically link
74-
Swift standard library dylibs from a path relative to their location
75-
(../lib/swift) so the standard library should be distributed alongside them.
110+
This will reflect the performance of the Swift standard library
111+
installed on the device, not the one included in the Swift root.
76112

77113
Using the Benchmark Driver
78114
--------------------------

benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ macro(configure_build)
2424
if(${c_compiler} STREQUAL "clang")
2525
set(CLANG_EXEC ${CMAKE_C_COMPILER})
2626
else()
27+
if(NOT SWIFT_DARWIN_XCRUN_TOOLCHAIN)
28+
set(SWIFT_DARWIN_XCRUN_TOOLCHAIN "XcodeDefault")
29+
endif()
2730
runcmd(COMMAND "xcrun" "-toolchain" "${SWIFT_DARWIN_XCRUN_TOOLCHAIN}" "-f" "clang"
2831
VARIABLE CLANG_EXEC
2932
ERROR "Unable to find Clang driver")
@@ -57,12 +60,47 @@ macro(configure_build)
5760
endif()
5861
endif()
5962

60-
# We always infer the SWIFT_LIBRARY_PATH from SWIFT_EXEC unless
61-
# SWIFT_LIBRARY_PATH is specified explicitly.
62-
if(NOT SWIFT_LIBRARY_PATH)
63-
get_filename_component(tmp_dir "${SWIFT_EXEC}" DIRECTORY)
64-
get_filename_component(tmp_dir "${tmp_dir}" DIRECTORY)
65-
set(SWIFT_LIBRARY_PATH "${tmp_dir}/lib/swift")
63+
# Set LIBRARY_PATH and either RPATH or RPATH_BASE. To build and run
64+
# for multiple platforms, RPATH_BASE must be set instead of RPATH. It
65+
# is the platform-independent runtime library directory. The platform
66+
# subdirectory name will be appended to form a different RPATH for
67+
# on platform.
68+
69+
# If requested, use Swift-in-the-OS. This way, the benchmarks may be built
70+
# standalone on the host, and the binaries can run directly from a temp dir
71+
# on any target machine. Of course, this factors out performance changes in
72+
# stdlib or overlays.
73+
if(SWIFT_BENCHMARK_USE_OS_LIBRARIES)
74+
set(SWIFT_RPATH "/usr/lib/swift")
75+
endif()
76+
77+
# When SWIFT_LIBRARY_PATH is specified explicitly for a standalone
78+
# build, use it as an absolute RPATH_BASE. This only works when
79+
# running benchmarks on the host machine. Otherwise, RPATH is set
80+
# assuming that libraries will be installed later (manually)
81+
# relative to the benchmark binaries.
82+
#
83+
# When not building standalone, SWIFT_LIBRARY_PATH is set by LLVM
84+
# cmake to the build directory for Swift dylibs. Otherwise, assume
85+
# that the dylibs are built relative to SWIFT_EXEC.
86+
if(SWIFT_LIBRARY_PATH AND SWIFT_BENCHMARK_BUILT_STANDALONE)
87+
if (NOT SWIFT_RPATH)
88+
set(SWIFT_RPATH_BASE ${SWIFT_LIBRARY_PATH})
89+
endif()
90+
else()
91+
if (NOT SWIFT_LIBRARY_PATH)
92+
get_filename_component(tmp_dir "${SWIFT_EXEC}" DIRECTORY)
93+
get_filename_component(tmp_dir "${tmp_dir}" DIRECTORY)
94+
set(SWIFT_LIBRARY_PATH "${tmp_dir}/lib/swift")
95+
endif()
96+
if (NOT SWIFT_RPATH)
97+
# If the benchmarks are built against a local swift build, assume that
98+
# either the benchmarks will be installed in the swift build dir,
99+
# or the swift libraries will be installed in the benchmark location in
100+
# a platform specific subdirectory.
101+
# This way, performance always factors in changes to the libraries.
102+
set(SWIFT_RPATH_BASE "@executable_path/../lib/swift")
103+
endif()
66104
endif()
67105
endmacro()
68106

@@ -571,6 +609,11 @@ function (swift_benchmark_compile_archopts)
571609
# both do exactly the same thing with both sets of arguments. It also lets us
572610
# avoid issues around code-signing.
573611
if (is_darwin)
612+
if (SWIFT_RPATH)
613+
set(SWIFT_LINK_RPATH "${SWIFT_RPATH}")
614+
else()
615+
set(SWIFT_LINK_RPATH "${SWIFT_RPATH_BASE}/${BENCH_COMPILE_ARCHOPTS_PLATFORM}")
616+
endif()
574617
add_custom_command(
575618
OUTPUT "${OUTPUT_EXEC}"
576619
DEPENDS
@@ -593,7 +636,7 @@ function (swift_benchmark_compile_archopts)
593636
"-lobjc"
594637
"-L${SWIFT_LIBRARY_PATH}/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
595638
"-Xlinker" "-rpath"
596-
"-Xlinker" "@executable_path/../lib/swift/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
639+
"-Xlinker" "${SWIFT_LINK_RPATH}"
597640
${bench_library_objects}
598641
${bench_driver_objects}
599642
${SWIFT_BENCH_OBJFILES}
@@ -612,7 +655,7 @@ function (swift_benchmark_compile_archopts)
612655
"${SWIFT_EXEC}"
613656
"-O"
614657
"-target" "${target}"
615-
"-L${SWIFT_LIBRARY_PATH}/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
658+
"-L${SWIFT_LIBRARY_PATH}"
616659
${bench_library_objects}
617660
${bench_driver_objects}
618661
${SWIFT_BENCH_OBJFILES}

0 commit comments

Comments
 (0)