From e776aa0275e293707b6a0901e0e8d8a8a3679508 Mon Sep 17 00:00:00 2001 From: Alex Strelnikov Date: Fri, 25 May 2018 06:18:58 -0400 Subject: [PATCH] Add benchmark_main target. (#601) * Add benchmark_main library with support for Bazel. * fix newline at end of file * Add CMake support for benchmark_main. * Mention optionally using benchmark_main in README. --- BUILD.bazel | 20 ++++++++++++++++---- README.md | 5 ++++- src/CMakeLists.txt | 15 ++++++++++++++- src/benchmark_main.cc | 17 +++++++++++++++++ test/BUILD | 10 +++++++++- test/CMakeLists.txt | 7 +++++++ test/link_main_test.cc | 8 ++++++++ 7 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 src/benchmark_main.cc create mode 100644 test/link_main_test.cc diff --git a/BUILD.bazel b/BUILD.bazel index 76b85d88e6..6ee69f2907 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -10,10 +10,13 @@ config_setting( cc_library( name = "benchmark", - srcs = glob([ - "src/*.cc", - "src/*.h", - ]), + srcs = glob( + [ + "src/*.cc", + "src/*.h", + ], + exclude = ["src/benchmark_main.cc"], + ), hdrs = ["include/benchmark/benchmark.h"], linkopts = select({ ":windows": ["-DEFAULTLIB:shlwapi.lib"], @@ -23,6 +26,15 @@ cc_library( visibility = ["//visibility:public"], ) +cc_library( + name = "benchmark_main", + srcs = ["src/benchmark_main.cc"], + hdrs = ["include/benchmark/benchmark.h"], + strip_include_prefix = "include", + visibility = ["//visibility:public"], + deps = [":benchmark"], +) + cc_library( name = "benchmark_internal_headers", hdrs = glob(["src/*.h"]), diff --git a/README.md b/README.md index b2e8eb648c..0341c31bd7 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,10 @@ BENCHMARK(BM_StringCopy); BENCHMARK_MAIN(); ``` -Don't forget to inform your linker to add benchmark library e.g. through `-lbenchmark` compilation flag. +Don't forget to inform your linker to add benchmark library e.g. through +`-lbenchmark` compilation flag. Alternatively, you may leave out the +`BENCHMARK_MAIN();` at the end of the source file and link against +`-lbenchmark_main` to get the same default behavior. The benchmark library will reporting the timing for the code within the `for(...)` loop. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 836549e3ca..701804ba0e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,7 @@ file(GLOB *.cc ${PROJECT_SOURCE_DIR}/include/benchmark/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.h) +list(FILTER SOURCE_FILES EXCLUDE REGEX "benchmark_main\\.cc") add_library(benchmark ${SOURCE_FILES}) set_target_properties(benchmark PROPERTIES @@ -39,6 +40,18 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") target_link_libraries(benchmark kstat) endif() +# Benchmark main library +add_library(benchmark_main "benchmark_main.cc") +set_target_properties(benchmark_main PROPERTIES + OUTPUT_NAME "benchmark_main" + VERSION ${GENERIC_LIB_VERSION} + SOVERSION ${GENERIC_LIB_SOVERSION} +) +target_include_directories(benchmark PUBLIC + $ + ) +target_link_libraries(benchmark_main benchmark) + set(include_install_dir "include") set(lib_install_dir "lib/") set(bin_install_dir "bin/") @@ -65,7 +78,7 @@ configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in" "${pkg_config}" @ON if (BENCHMARK_ENABLE_INSTALL) # Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable) install( - TARGETS benchmark + TARGETS benchmark benchmark_main EXPORT ${targets_export_name} ARCHIVE DESTINATION ${lib_install_dir} LIBRARY DESTINATION ${lib_install_dir} diff --git a/src/benchmark_main.cc b/src/benchmark_main.cc new file mode 100644 index 0000000000..b3b2478314 --- /dev/null +++ b/src/benchmark_main.cc @@ -0,0 +1,17 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" + +BENCHMARK_MAIN(); diff --git a/test/BUILD b/test/BUILD index 2b3a391296..3f174c486f 100644 --- a/test/BUILD +++ b/test/BUILD @@ -53,5 +53,13 @@ cc_library( # FIXME: Add support for assembly tests to bazel. # See Issue #556 # https://github.com/google/benchmark/issues/556 - ) for test_src in glob(["*test.cc"], exclude = ["*_assembly_test.cc"]) + ) for test_src in glob(["*test.cc"], exclude = ["*_assembly_test.cc", "link_main_test.cc"]) ] + +cc_test( + name = "link_main_test", + size = "small", + srcs = ["link_main_test.cc"], + copts = TEST_COPTS, + deps = ["//:benchmark_main"], +) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 287e22851a..05ae804bfe 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -41,6 +41,10 @@ macro(compile_benchmark_test name) target_link_libraries(${name} benchmark ${CMAKE_THREAD_LIBS_INIT}) endmacro(compile_benchmark_test) +macro(compile_benchmark_test_with_main name) + add_executable(${name} "${name}.cc") + target_link_libraries(${name} benchmark_main) +endmacro(compile_benchmark_test_with_main) macro(compile_output_test name) add_executable(${name} "${name}.cc" output_test.h) @@ -109,6 +113,9 @@ add_test(map_test map_test --benchmark_min_time=0.01) compile_benchmark_test(multiple_ranges_test) add_test(multiple_ranges_test multiple_ranges_test --benchmark_min_time=0.01) +compile_benchmark_test_with_main(link_main_test) +add_test(link_main_test link_main_test --benchmark_min_time=0.01) + compile_output_test(reporter_output_test) add_test(reporter_output_test reporter_output_test --benchmark_min_time=0.01) diff --git a/test/link_main_test.cc b/test/link_main_test.cc new file mode 100644 index 0000000000..241ad5c390 --- /dev/null +++ b/test/link_main_test.cc @@ -0,0 +1,8 @@ +#include "benchmark/benchmark.h" + +void BM_empty(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(state.iterations()); + } +} +BENCHMARK(BM_empty);