Skip to content

Commit 36e0e69

Browse files
committed
[benchmark] Add cmake support for compiling the benchmarks standalone on Linux.
To use this, one needs to first build an installable root for swift (i.e. like the smoke testbot does). Then use the tool ./benchmark/scripts/build_linux.py with the appropriate locations of the build-directory, installable snapshot, and it will build the benchmarks. (There are more arguments, just use --help). rdar://40541972
1 parent 1466b29 commit 36e0e69

File tree

3 files changed

+220
-84
lines changed

3 files changed

+220
-84
lines changed

benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake

Lines changed: 163 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,54 @@
22
include(CMakeParseArguments)
33
include(SwiftBenchmarkUtils)
44

5-
macro (configure_build)
5+
macro(configure_build)
66
add_definitions(-DSWIFT_EXEC -DSWIFT_LIBRARY_PATH -DONLY_PLATFORMS
77
-DSWIFT_OPTIMIZATION_LEVELS -DSWIFT_BENCHMARK_EMIT_SIB)
88

99
if(NOT ONLY_PLATFORMS)
10-
set(ONLY_PLATFORMS "macosx" "iphoneos" "appletvos" "watchos")
10+
set(ONLY_PLATFORMS "macosx" "iphoneos" "appletvos" "watchos" "linux")
1111
endif()
1212

13-
if(NOT SWIFT_EXEC)
14-
runcmd(COMMAND "xcrun" "-f" "swiftc"
15-
VARIABLE SWIFT_EXEC
16-
ERROR "Unable to find Swift driver")
13+
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
14+
if(NOT SWIFT_EXEC)
15+
runcmd(COMMAND "xcrun" "-f" "swiftc"
16+
VARIABLE SWIFT_EXEC
17+
ERROR "Unable to find Swift driver")
18+
endif()
19+
20+
# If the CMAKE_C_COMPILER is already clang, don't find it again,
21+
# thus allowing the --host-cc build-script argument to work here.
22+
get_filename_component(c_compiler ${CMAKE_C_COMPILER} NAME)
23+
24+
if(${c_compiler} STREQUAL "clang")
25+
set(CLANG_EXEC ${CMAKE_C_COMPILER})
26+
else()
27+
runcmd(COMMAND "xcrun" "-toolchain" "${SWIFT_DARWIN_XCRUN_TOOLCHAIN}" "-f" "clang"
28+
VARIABLE CLANG_EXEC
29+
ERROR "Unable to find Clang driver")
30+
endif()
31+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
32+
# We always require SWIFT_EXEC and CLANG_EXEC to be specified explicitly
33+
# when compiling for Linux.
34+
#
35+
# TODO: Investigate if we can eliminate CLANG_EXEC/SWIFT_EXEC and use more
36+
# normal like cmake patterns.
37+
precondition(SWIFT_EXEC)
38+
precondition(CLANG_EXEC)
39+
else()
40+
message(FATAL_ERROR "Unsupported platform?!")
1741
endif()
1842

43+
# We always infer the SWIFT_LIBRARY_PATH from SWIFT_EXEC unless
44+
# SWIFT_LIBRARY_PATH is specified explicitly.
1945
if(NOT SWIFT_LIBRARY_PATH)
2046
get_filename_component(tmp_dir "${SWIFT_EXEC}" DIRECTORY)
2147
get_filename_component(tmp_dir "${tmp_dir}" DIRECTORY)
2248
set(SWIFT_LIBRARY_PATH "${tmp_dir}/lib/swift")
2349
endif()
24-
25-
# If the CMAKE_C_COMPILER is already clang, don't find it again,
26-
# thus allowing the --host-cc build-script argument to work here.
27-
get_filename_component(c_compiler ${CMAKE_C_COMPILER} NAME)
28-
29-
if(${c_compiler} STREQUAL "clang")
30-
set(CLANG_EXEC ${CMAKE_C_COMPILER})
31-
else()
32-
runcmd(COMMAND "xcrun" "-toolchain" "${SWIFT_DARWIN_XCRUN_TOOLCHAIN}" "-f" "clang"
33-
VARIABLE CLANG_EXEC
34-
ERROR "Unable to find Clang driver")
35-
endif()
3650
endmacro()
3751

38-
macro (configure_sdks)
52+
macro(configure_sdks_darwin)
3953
set(macosx_arch "x86_64")
4054
set(iphoneos_arch "arm64" "armv7")
4155
set(appletvos_arch "arm64")
@@ -54,6 +68,7 @@ macro (configure_sdks)
5468
set(sdks)
5569
set(platforms)
5670
foreach(platform ${ONLY_PLATFORMS})
71+
set(${platform}_is_darwin TRUE)
5772
execute_process(
5873
COMMAND "xcrun" "--sdk" "${platform}" "--show-sdk-path"
5974
OUTPUT_VARIABLE ${platform}_sdk
@@ -66,6 +81,31 @@ macro (configure_sdks)
6681
endforeach()
6782
endmacro()
6883

84+
macro(configure_sdks_linux)
85+
# TODO: Get the correct triple.
86+
set(linux_arch "x86_64")
87+
set(linux_ver "") # Linux doesn't use the ver field
88+
set(linux_vendor "unknown")
89+
set(linux_triple_platform "linux")
90+
set(linux_sdk "") # Linux doesn't use sdks.
91+
set(linux_is_darwin FALSE)
92+
93+
# This is not applicable on linux since on linux we do not use
94+
# SDKs/frameworks when building our benchmarks.
95+
set(sdks "N/A")
96+
set(platforms "linux")
97+
endmacro()
98+
99+
macro(configure_sdks)
100+
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
101+
configure_sdks_darwin()
102+
elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
103+
configure_sdks_linux()
104+
else()
105+
message(FATAL_ERROR "Unsupported system: ${CMAKE_SYSTEM_NAME}?!")
106+
endif()
107+
endmacro()
108+
69109
function (add_swift_benchmark_library objfile_out sibfile_out)
70110
cmake_parse_arguments(BENCHLIB "" "MODULE_PATH;SOURCE_DIR;OBJECT_DIR" "SOURCES;LIBRARY_FLAGS;DEPENDS" ${ARGN})
71111

@@ -229,11 +269,13 @@ endfunction()
229269

230270
function (swift_benchmark_compile_archopts)
231271
cmake_parse_arguments(BENCH_COMPILE_ARCHOPTS "" "PLATFORM;ARCH;OPT" "" ${ARGN})
272+
set(is_darwin ${${BENCH_COMPILE_ARCHOPTS_PLATFORM}_is_darwin})
232273
set(sdk ${${BENCH_COMPILE_ARCHOPTS_PLATFORM}_sdk})
274+
set(vendor ${${BENCH_COMPILE_ARCHOPTS_PLATFORM}_vendor})
233275
set(ver ${${BENCH_COMPILE_ARCHOPTS_PLATFORM}_ver})
234276
set(triple_platform ${${BENCH_COMPILE_ARCHOPTS_PLATFORM}_triple_platform})
235277

236-
set(target "${BENCH_COMPILE_ARCHOPTS_ARCH}-apple-${triple_platform}${ver}")
278+
set(target "${BENCH_COMPILE_ARCHOPTS_ARCH}-${vendor}-${triple_platform}${ver}")
237279

238280
set(objdir "${CMAKE_CURRENT_BINARY_DIR}/${BENCH_COMPILE_ARCHOPTS_OPT}-${target}")
239281
file(MAKE_DIRECTORY "${objdir}")
@@ -250,12 +292,16 @@ function (swift_benchmark_compile_archopts)
250292

251293
set(common_options
252294
"-c"
253-
"-sdk" "${sdk}"
254295
"-target" "${target}"
296+
"-${BENCH_COMPILE_ARCHOPTS_OPT}")
297+
298+
if (is_darwin)
299+
list(APPEND common_options
300+
"-I" "${srcdir}/utils/ObjectiveCTests"
255301
"-F" "${sdk}/../../../Developer/Library/Frameworks"
256-
"-${BENCH_COMPILE_ARCHOPTS_OPT}"
257-
"-no-link-objc-runtime"
258-
"-I" "${srcdir}/utils/ObjectiveCTests")
302+
"-sdk" "${sdk}"
303+
"-no-link-objc-runtime")
304+
endif()
259305

260306
set(opt_view_main_dir)
261307
if(SWIFT_BENCHMARK_GENERATE_OPT_VIEW AND LLVM_HAVE_OPT_VIEWER_MODULES)
@@ -274,12 +320,15 @@ function (swift_benchmark_compile_archopts)
274320

275321
set(common_options_driver
276322
"-c"
277-
"-sdk" "${sdk}"
278323
"-target" "${target}"
324+
"-${driver_opt}")
325+
326+
if (is_darwin)
327+
list(APPEND common_options_driver
328+
"-sdk" "${sdk}"
279329
"-F" "${sdk}/../../../Developer/Library/Frameworks"
280-
"-${driver_opt}"
281330
"-no-link-objc-runtime")
282-
331+
endif()
283332
set(bench_library_objects)
284333
set(bench_library_sibfiles)
285334
set(opt_view_dirs)
@@ -490,65 +539,97 @@ function (swift_benchmark_compile_archopts)
490539
"${source}")
491540
list(APPEND SWIFT_BENCH_OBJFILES "${objdir}/${module_name}.o")
492541

493-
if("${BENCH_COMPILE_ARCHOPTS_PLATFORM}" STREQUAL "macosx")
494-
set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}")
495-
else()
496-
set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}-${target}")
542+
set(objcfile)
543+
if (is_darwin)
544+
set(objcfile "${objdir}/ObjectiveCTests.o")
545+
add_custom_command(
546+
OUTPUT "${objcfile}"
547+
DEPENDS "${srcdir}/utils/ObjectiveCTests/ObjectiveCTests.m"
548+
"${srcdir}/utils/ObjectiveCTests/ObjectiveCTests.h"
549+
COMMAND
550+
"${CLANG_EXEC}"
551+
"-fno-stack-protector"
552+
"-fPIC"
553+
"-Werror=date-time"
554+
"-fcolor-diagnostics"
555+
"-O3"
556+
"-target" "${target}"
557+
"-isysroot" "${sdk}"
558+
"-fobjc-arc"
559+
"-arch" "${BENCH_COMPILE_ARCHOPTS_ARCH}"
560+
"-F" "${sdk}/../../../Developer/Library/Frameworks"
561+
"-m${triple_platform}-version-min=${ver}"
562+
"-I" "${srcdir}/utils/ObjectiveCTests"
563+
"${srcdir}/utils/ObjectiveCTests/ObjectiveCTests.m"
564+
"-c"
565+
"-o" "${objcfile}")
497566
endif()
498567

499-
set(objcfile "${objdir}/ObjectiveCTests.o")
500-
add_custom_command(
501-
OUTPUT "${objcfile}"
502-
DEPENDS "${srcdir}/utils/ObjectiveCTests/ObjectiveCTests.m"
503-
"${srcdir}/utils/ObjectiveCTests/ObjectiveCTests.h"
504-
COMMAND
505-
"${CLANG_EXEC}"
506-
"-fno-stack-protector"
507-
"-fPIC"
508-
"-Werror=date-time"
509-
"-fcolor-diagnostics"
510-
"-O3"
511-
"-target" "${target}"
512-
"-isysroot" "${sdk}"
513-
"-fobjc-arc"
514-
"-arch" "${BENCH_COMPILE_ARCHOPTS_ARCH}"
515-
"-F" "${sdk}/../../../Developer/Library/Frameworks"
516-
"-m${triple_platform}-version-min=${ver}"
517-
"-I" "${srcdir}/utils/ObjectiveCTests"
518-
"${srcdir}/utils/ObjectiveCTests/ObjectiveCTests.m"
519-
"-c"
520-
"-o" "${objcfile}")
568+
if(is_darwin)
569+
# If host == target.
570+
if("${BENCH_COMPILE_ARCHOPTS_PLATFORM}" STREQUAL "macosx")
571+
set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}")
572+
else()
573+
set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}-${target}")
574+
endif()
575+
else()
576+
# If we are on Linux, we do not support cross compiling.
577+
set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}")
578+
endif()
521579

522-
add_custom_command(
523-
OUTPUT "${OUTPUT_EXEC}"
524-
DEPENDS
525-
${bench_library_objects} ${bench_driver_objects} ${SWIFT_BENCH_OBJFILES}
526-
"${objcfile}" ${opt_view_dirs}
527-
COMMAND
528-
"${CLANG_EXEC}"
529-
"-fno-stack-protector"
530-
"-fPIC"
531-
"-Werror=date-time"
532-
"-fcolor-diagnostics"
533-
"-O3"
534-
"-Wl,-search_paths_first"
535-
"-Wl,-headerpad_max_install_names"
536-
"-target" "${target}"
537-
"-isysroot" "${sdk}"
538-
"-arch" "${BENCH_COMPILE_ARCHOPTS_ARCH}"
539-
"-F" "${sdk}/../../../Developer/Library/Frameworks"
540-
"-m${triple_platform}-version-min=${ver}"
541-
"-lobjc"
542-
"-L${SWIFT_LIBRARY_PATH}/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
543-
"-Xlinker" "-rpath"
544-
"-Xlinker" "@executable_path/../lib/swift/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
545-
${bench_library_objects}
546-
${bench_driver_objects}
547-
${SWIFT_BENCH_OBJFILES}
548-
${objcfile}
549-
"-o" "${OUTPUT_EXEC}"
550-
COMMAND
580+
# TODO: Unify the linux and darwin builds here.
581+
#
582+
# We are avoiding this for now until it is investigated if swiftc and clang
583+
# both do exactly the same thing with both sets of arguments. It also lets us
584+
# avoid issues around code-signing.
585+
if (is_darwin)
586+
add_custom_command(
587+
OUTPUT "${OUTPUT_EXEC}"
588+
DEPENDS
589+
${bench_library_objects} ${bench_driver_objects} ${SWIFT_BENCH_OBJFILES}
590+
"${objcfile}" ${opt_view_dirs}
591+
COMMAND
592+
"${CLANG_EXEC}"
593+
"-fno-stack-protector"
594+
"-fPIC"
595+
"-Werror=date-time"
596+
"-fcolor-diagnostics"
597+
"-O3"
598+
"-Wl,-search_paths_first"
599+
"-Wl,-headerpad_max_install_names"
600+
"-target" "${target}"
601+
"-isysroot" "${sdk}"
602+
"-arch" "${BENCH_COMPILE_ARCHOPTS_ARCH}"
603+
"-F" "${sdk}/../../../Developer/Library/Frameworks"
604+
"-m${triple_platform}-version-min=${ver}"
605+
"-lobjc"
606+
"-L${SWIFT_LIBRARY_PATH}/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
607+
"-Xlinker" "-rpath"
608+
"-Xlinker" "@executable_path/../lib/swift/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
609+
${bench_library_objects}
610+
${bench_driver_objects}
611+
${SWIFT_BENCH_OBJFILES}
612+
${objcfile}
613+
"-o" "${OUTPUT_EXEC}"
614+
COMMAND
551615
"codesign" "-f" "-s" "-" "${OUTPUT_EXEC}")
616+
else()
617+
# TODO: rpath.
618+
add_custom_command(
619+
OUTPUT "${OUTPUT_EXEC}"
620+
DEPENDS
621+
${bench_library_objects} ${bench_driver_objects} ${SWIFT_BENCH_OBJFILES}
622+
"${objcfile}" ${opt_view_dirs}
623+
COMMAND
624+
"${SWIFT_EXEC}"
625+
"-O"
626+
"-target" "${target}"
627+
"-L${SWIFT_LIBRARY_PATH}/${BENCH_COMPILE_ARCHOPTS_PLATFORM}"
628+
${bench_library_objects}
629+
${bench_driver_objects}
630+
${SWIFT_BENCH_OBJFILES}
631+
"-o" "${OUTPUT_EXEC}")
632+
endif()
552633
set(new_output_exec "${OUTPUT_EXEC}" PARENT_SCOPE)
553634
endfunction()
554635

benchmark/scripts/build_linux.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import os
5+
import subprocess
6+
7+
8+
def main():
9+
p = argparse.ArgumentParser()
10+
p.add_argument('cmake_path', help='The cmake binary to use')
11+
p.add_argument('swift_src_dir', help='The swift source directory')
12+
p.add_argument('clang', help='The path to the clang binary to use')
13+
p.add_argument('swift_root_dir',
14+
help='A path to a swift root produced by installing '
15+
'Swift and Foundation together. We infer swiftc '
16+
'from here')
17+
p.add_argument('destdir', help='The directory to perform the actual '
18+
'build in')
19+
p.add_argument('--clean', action='store_true',
20+
help='Delete destdir before performing a build.')
21+
args = p.parse_args()
22+
23+
if args.clean:
24+
print("Asked to clean... Cleaning!")
25+
subprocess.check_output(['/bin/rm', '-rfv', args.destdir])
26+
subprocess.check_call(['/bin/mkdir', '-p', args.destdir])
27+
os.chdir(args.destdir)
28+
configureInvocation = [
29+
args.cmake_path, '-GNinja',
30+
'-DSWIFT_EXEC={}/bin/swiftc'.format(args.swift_root_dir),
31+
'-DCLANG_EXEC={}'.format(args.clang),
32+
'-DSWIFT_LIBRARY_PATH={}/lib/swift'.format(args.swift_root_dir),
33+
'{}/benchmark'.format(args.swift_src_dir)
34+
]
35+
print('COMMAND: {}'.format(' '.join(configureInvocation)))
36+
subprocess.check_call(configureInvocation)
37+
38+
buildInvocation = [
39+
args.cmake_path, '--build', args.destdir, '--',
40+
'swift-benchmark-linux-x86_64'
41+
]
42+
print('COMMAND: {}'.format(' '.join(buildInvocation)))
43+
subprocess.check_call(buildInvocation)
44+
45+
46+
if __name__ == "__main__":
47+
main()

benchmark/single-source/DataBenchmarks.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ import Glibc
9696
@inline(__always)
9797
func getRandomBuf(_ arg: UnsafeMutableBufferPointer<UInt8>) {
9898
#if os(Linux)
99-
getrandom(arg.baseAddress, arg.count, 0)
99+
let fd = open("/dev/urandom", O_RDONLY)
100+
defer { if (fd >= 0) { close(fd) } }
101+
if fd >= 0 {
102+
read(fd, arg.baseAddress, arg.count)
103+
}
100104
#else
101105
arc4random_buf(arg.baseAddress, arg.count)
102106
#endif
@@ -105,7 +109,11 @@ func getRandomBuf(_ arg: UnsafeMutableBufferPointer<UInt8>) {
105109
@inline(__always)
106110
func getRandomBuf(baseAddress: UnsafeMutablePointer<UInt8>, count: Int) {
107111
#if os(Linux)
108-
getrandom(arg.baseAddress, arg.count, 0)
112+
let fd = open("/dev/urandom", O_RDONLY)
113+
defer { if (fd >= 0) { close(fd) } }
114+
if fd >= 0 {
115+
read(fd, baseAddress, count)
116+
}
109117
#else
110118
arc4random_buf(baseAddress, count)
111119
#endif

0 commit comments

Comments
 (0)