From 4c8bab04c6a0f9e09e4e091d831b146f77842ed9 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 14 May 2020 10:59:16 -0700 Subject: [PATCH] build: add a CMake based build for swift-benchmarks (#22) This adds a CMake based build system for swift-benchmark, enabling support on Windows. This support includes optionally building the example programs and covers the test suite. The exports file also is generated for ease in using in other projects. The test suite is best run in an automated fashion using `cmake --build /BinaryCache/current/swift-benchmark --target test` (aka `ninja test`). --- CMakeLists.txt | 27 ++++++ Sources/Benchmark/CMakeLists.txt | 25 +++++ .../BenchmarkMinimalExample/CMakeLists.txt | 4 + Sources/BenchmarkSuiteExample/CMakeLists.txt | 5 + Sources/CMakeLists.txt | 5 + Tests/BenchmarkTests/CMakeLists.txt | 11 +++ Tests/CMakeLists.txt | 12 +++ cmake/modules/BenchmarkConfig.cmake.in | 3 + cmake/modules/CMakeLists.txt | 8 ++ cmake/modules/SwiftSupport.cmake | 92 +++++++++++++++++++ 10 files changed, 192 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 Sources/Benchmark/CMakeLists.txt create mode 100644 Sources/BenchmarkMinimalExample/CMakeLists.txt create mode 100644 Sources/BenchmarkSuiteExample/CMakeLists.txt create mode 100644 Sources/CMakeLists.txt create mode 100644 Tests/BenchmarkTests/CMakeLists.txt create mode 100644 Tests/CMakeLists.txt create mode 100644 cmake/modules/BenchmarkConfig.cmake.in create mode 100644 cmake/modules/CMakeLists.txt create mode 100644 cmake/modules/SwiftSupport.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ec7ecbb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.16.0) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) + +project(swift-benchmark + LANGUAGES Swift) + +option(BUILD_SHARED_LIBS "build shared libraries by default" YES) +option(BUILD_EXAMPLES "build examples" NO) + +include(CTest) +include(SwiftSupport) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift) + +find_package(dispatch CONFIG QUIET) +find_package(Foundation CONFIG QUIET) +find_package(ArgumentParser CONFIG QUIET) + +add_subdirectory(Sources) +if(BUILD_TESTING) + add_subdirectory(Tests) +endif() +add_subdirectory(cmake/modules) diff --git a/Sources/Benchmark/CMakeLists.txt b/Sources/Benchmark/CMakeLists.txt new file mode 100644 index 0000000..44db5d2 --- /dev/null +++ b/Sources/Benchmark/CMakeLists.txt @@ -0,0 +1,25 @@ +add_library(Benchmark + Benchmark.swift + BenchmarkClock.swift + BenchmarkCommand.swift + BenchmarkFilter.swift + BenchmarkMain.swift + BenchmarkReporter.swift + BenchmarkResult.swift + BenchmarkRunner.swift + BenchmarkSetting.swift + BenchmarkSuite.swift + Stats.swift) +# NOTE: workaround for CMake <3.17 which does not propagate the property +set_target_properties(Benchmark PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) +target_compile_options(Benchmark PRIVATE + $<$:-enable-testing>) +target_link_libraries(Benchmark PUBLIC + dispatch + swiftDispatch + ArgumentParser + Foundation) + +_install_target(Benchmark) +set_property(GLOBAL APPEND PROPERTY Benchmark_EXPORTS Benchmark) diff --git a/Sources/BenchmarkMinimalExample/CMakeLists.txt b/Sources/BenchmarkMinimalExample/CMakeLists.txt new file mode 100644 index 0000000..b567797 --- /dev/null +++ b/Sources/BenchmarkMinimalExample/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(BenchmarkMinimalExample + main.swift) +target_link_libraries(BenchmarkMinimalExample PRIVATE + Benchmark) diff --git a/Sources/BenchmarkSuiteExample/CMakeLists.txt b/Sources/BenchmarkSuiteExample/CMakeLists.txt new file mode 100644 index 0000000..1fc0406 --- /dev/null +++ b/Sources/BenchmarkSuiteExample/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(BenchmarkSuiteExample + AddStringBenchmarks.swift + main.swift) +target_link_libraries(BenchmarkSuiteExample PRIVATE + Benchmark) diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt new file mode 100644 index 0000000..5c452bb --- /dev/null +++ b/Sources/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(Benchmark) +if(BUILD_EXAMPLES) + add_subdirectory(BenchmarkMinimalExample) + add_subdirectory(BenchmarkSuiteExample) +endif() diff --git a/Tests/BenchmarkTests/CMakeLists.txt b/Tests/BenchmarkTests/CMakeLists.txt new file mode 100644 index 0000000..a3b1167 --- /dev/null +++ b/Tests/BenchmarkTests/CMakeLists.txt @@ -0,0 +1,11 @@ +add_library(BenchmarkTests + BenchmarkCommandTests.swift + BenchmarkRunnerTests.swift + BenchmarkSettingTests.swift + BlackHoleReporter.swift + StatsTests.swift + XCTTestManifests.swift) +target_link_libraries(BenchmarkTests PUBLIC + Benchmark + Foundation + XCTest) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt new file mode 100644 index 0000000..378b330 --- /dev/null +++ b/Tests/CMakeLists.txt @@ -0,0 +1,12 @@ +find_package(XCTest CONFIG QUIET) + +add_subdirectory(BenchmarkTests) + +add_executable(BenchmarkTestRunner + LinuxMain.swift) +target_link_libraries(BenchmarkTestRunner PRIVATE + BenchmarkTests + XCTest) + +add_test(NAME Benchmark + COMMAND BenchmarkTestRunner) diff --git a/cmake/modules/BenchmarkConfig.cmake.in b/cmake/modules/BenchmarkConfig.cmake.in new file mode 100644 index 0000000..c64538a --- /dev/null +++ b/cmake/modules/BenchmarkConfig.cmake.in @@ -0,0 +1,3 @@ +if(NOT TARGET Benchmark) + include(@Benchmark_EXPORTS_FILE@) +endif() diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt new file mode 100644 index 0000000..aaaec4a --- /dev/null +++ b/cmake/modules/CMakeLists.txt @@ -0,0 +1,8 @@ +set(Benchmark_EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/BenchmarkExports.cmake) + +configure_file(BenchmarkConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/BenchmarkConfig.cmake) + +get_property(Benchmark_EXPORTS GLOBAL PROPERTY Benchmark_EXPORTS) +export(TARGETS ${Benchmark_EXPORTS} + FILE ${Benchmark_EXPORTS_FILE}) diff --git a/cmake/modules/SwiftSupport.cmake b/cmake/modules/SwiftSupport.cmake new file mode 100644 index 0000000..066f122 --- /dev/null +++ b/cmake/modules/SwiftSupport.cmake @@ -0,0 +1,92 @@ +# Returns the architecture name in a variable +# +# Usage: +# get_swift_host_arch(result_var_name) +# +# Sets ${result_var_name} with the converted architecture name derived from +# CMAKE_SYSTEM_PROCESSOR. +function(get_swift_host_arch result_var_name) + if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + set("${result_var_name}" "x86_64" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") + set("${result_var_name}" "aarch64" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64") + set("${result_var_name}" "powerpc64" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le") + set("${result_var_name}" "powerpc64le" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x") + set("${result_var_name}" "s390x" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l") + set("${result_var_name}" "armv6" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") + set("${result_var_name}" "armv7" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a") + set("${result_var_name}" "armv7" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") + set("${result_var_name}" "x86_64" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64") + set("${result_var_name}" "itanium" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86") + set("${result_var_name}" "i686" PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") + set("${result_var_name}" "i686" PARENT_SCOPE) + else() + message(FATAL_ERROR "Unrecognized architecture on host system: ${CMAKE_SYSTEM_PROCESSOR}") + endif() +endfunction() + +# Returns the os name in a variable +# +# Usage: +# get_swift_host_os(result_var_name) +# +# +# Sets ${result_var_name} with the converted OS name derived from +# CMAKE_SYSTEM_NAME. +function(get_swift_host_os result_var_name) + if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + set(${result_var_name} macosx PARENT_SCOPE) + else() + string(TOLOWER ${CMAKE_SYSTEM_NAME} cmake_system_name_lc) + set(${result_var_name} ${cmake_system_name_lc} PARENT_SCOPE) + endif() +endfunction() + +function(_install_target module) + get_swift_host_os(swift_os) + get_target_property(type ${module} TYPE) + + if(type STREQUAL STATIC_LIBRARY) + set(swift swift_static) + else() + set(swift swift) + endif() + + install(TARGETS ${module} + ARCHIVE DESTINATION lib/${swift}/${swift_os} + LIBRARY DESTINATION lib/${swift}/${swift_os} + RUNTIME DESTINATION bin) + if(type STREQUAL EXECUTABLE) + return() + endif() + + get_swift_host_arch(swift_arch) + get_target_property(module_name ${module} Swift_MODULE_NAME) + if(NOT module_name) + set(module_name ${module}) + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + install(FILES $/${module_name}.swiftdoc + DESTINATION lib/${swift}/${swift_os}/${module_name}.swiftmodule + RENAME ${swift_arch}.swiftdoc) + install(FILES $/${module_name}.swiftmodule + DESTINATION lib/${swift}/${swift_os}/${module_name}.swiftmodule + RENAME ${swift_arch}.swiftmodule) + else() + install(FILES + $/${module_name}.swiftdoc + $/${module_name}.swiftmodule + DESTINATION lib/${swift}/${swift_os}/${swift_arch}) + endif() +endfunction()