Skip to content

Commit eb4cebb

Browse files
authored
Merge 4660646 into 27e0b43
2 parents 27e0b43 + 4660646 commit eb4cebb

File tree

6 files changed

+201
-4
lines changed

6 files changed

+201
-4
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,7 @@ rules.ninja
4444
# out-of-source build top-level folders.
4545
build/
4646
_build/
47+
48+
# in-source dependancies
49+
/googletest/
50+

CMakeLists.txt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ project (benchmark)
55
foreach(p
66
CMP0054 # CMake 3.1
77
CMP0056 # export EXE_LINKER_FLAGS to try_run
8+
CMP0057 # Support no if() IN_LIST operator
89
)
910
if(POLICY ${p})
1011
cmake_policy(SET ${p} NEW)
@@ -18,6 +19,14 @@ option(BENCHMARK_USE_LIBCXX "Build and test using libc++ as the standard library
1819
option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF)
1920
option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON)
2021

22+
# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which
23+
# may require downloading the source code.
24+
option(BENCHMARK_DOWNLOAD_DEPENDENCIES "Allow the downloading and in-tree building of unmet dependencies" OFF)
25+
26+
# This option can be used to disable building and running unit tests which depend on gtest
27+
# in cases where it is not possible to build or find a valid version of gtest.
28+
option(BENCHMARK_ENABLE_GTEST_TESTS "Enable building the unit tests which depend on gtest" ON)
29+
2130
# Make sure we can import out CMake functions
2231
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
2332

@@ -96,9 +105,7 @@ else()
96105
if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
97106
add_cxx_compiler_flag(-fno-exceptions)
98107
endif()
99-
if (NOT BENCHMARK_USE_LIBCXX)
100-
add_cxx_compiler_flag(-Wzero-as-null-pointer-constant)
101-
endif()
108+
102109
if (HAVE_CXX_FLAG_FSTRICT_ALIASING)
103110
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel") #ICC17u2: Many false positives for Wstrict-aliasing
104111
add_cxx_compiler_flag(-Wstrict-aliasing)
@@ -196,5 +203,8 @@ add_subdirectory(src)
196203

197204
if (BENCHMARK_ENABLE_TESTING)
198205
enable_testing()
206+
if (BENCHMARK_ENABLE_GTEST_TESTS)
207+
include(HandleGTest)
208+
endif()
199209
add_subdirectory(test)
200210
endif()

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,29 @@ IRC channel: https://freenode.net #googlebenchmark
1313

1414
[Additional Tooling Documentation](docs/tools.md)
1515

16+
## Building
17+
18+
The basic steps for configuring and building the library look like this:
19+
20+
```bash
21+
$ git clone https://github.com/google/benchmark.git
22+
# Benchmark requires GTest as a dependency. Add the source tree as a subdirectory.
23+
$ git clone https://github.com/google/googletest.git benchmark/googletest
24+
$ mkdir build && cd build
25+
$ cmake -G <generator> [options] ../benchmark
26+
# Assuming a makefile generator was used
27+
$ make
28+
```
29+
30+
Note that Google Benchmark requires GTest to build and run the tests. This
31+
dependency can be provided three ways:
32+
33+
* Checkout the GTest sources into `benchmark/googletest`.
34+
* Specify `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` when configuring to allow the
35+
library to automatically download and build required dependencies.
36+
* Otherwise, do nothing and CMake will use `find_package(GTest REQUIRED)` to
37+
resolve the required GTest dependency.
38+
1639
## Example usage
1740
### Basic usage
1841
Define a function that executes the code to be measured.

cmake/HandleGTest.cmake

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
2+
macro(split_list listname)
3+
string(REPLACE ";" " " ${listname} "${${listname}}")
4+
endmacro()
5+
6+
macro(build_external_gtest)
7+
include(ExternalProject)
8+
set(GTEST_FLAGS "")
9+
if (BENCHMARK_USE_LIBCXX)
10+
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
11+
list(APPEND GTEST_FLAGS -stdlib=libc++)
12+
else()
13+
message(WARNING "Unsupported compiler (${CMAKE_CXX_COMPILER}) when using libc++")
14+
endif()
15+
endif()
16+
if (BENCHMARK_BUILD_32_BITS)
17+
list(APPEND GTEST_FLAGS -m32)
18+
endif()
19+
if (NOT "${CMAKE_CXX_FLAGS}" STREQUAL "")
20+
list(APPEND GTEST_FLAGS ${CMAKE_CXX_FLAGS})
21+
endif()
22+
string(TOUPPER "${CMAKE_BUILD_TYPE}" GTEST_BUILD_TYPE)
23+
if ("${GTEST_BUILD_TYPE}" STREQUAL "COVERAGE")
24+
set(GTEST_BUILD_TYPE "DEBUG")
25+
endif()
26+
split_list(GTEST_FLAGS)
27+
ExternalProject_Add(googletest
28+
EXCLUDE_FROM_ALL ON
29+
GIT_REPOSITORY https://github.com/google/googletest.git
30+
GIT_TAG master
31+
PREFIX "${CMAKE_BINARY_DIR}/googletest"
32+
INSTALL_DIR "${CMAKE_BINARY_DIR}/googletest"
33+
CMAKE_CACHE_ARGS
34+
-DCMAKE_BUILD_TYPE:STRING=${GTEST_BUILD_TYPE}
35+
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
36+
-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
37+
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
38+
-DCMAKE_CXX_FLAGS:STRING=${GTEST_FLAGS}
39+
-Dgtest_force_shared_crt:BOOL=ON
40+
)
41+
42+
ExternalProject_Get_Property(googletest install_dir)
43+
44+
add_library(gtest UNKNOWN IMPORTED)
45+
add_library(gtest_main UNKNOWN IMPORTED)
46+
47+
set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
48+
set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
49+
50+
if("${GTEST_BUILD_TYPE}" STREQUAL "DEBUG")
51+
set(LIB_SUFFIX "d${CMAKE_STATIC_LIBRARY_SUFFIX}")
52+
endif()
53+
file(MAKE_DIRECTORY ${install_dir}/include)
54+
set_target_properties(gtest PROPERTIES
55+
IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}gtest${LIB_SUFFIX}
56+
INTERFACE_INCLUDE_DIRECTORIES ${install_dir}/include
57+
)
58+
set_target_properties(gtest_main PROPERTIES
59+
IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}gtest_main${LIB_SUFFIX}
60+
INTERFACE_INCLUDE_DIRECTORIES ${install_dir}/include
61+
)
62+
add_dependencies(gtest googletest)
63+
add_dependencies(gtest_main googletest)
64+
set(GTEST_BOTH_LIBRARIES gtest gtest_main)
65+
#set(GTEST_INCLUDE_DIRS ${install_dir}/include)
66+
endmacro(build_external_gtest)
67+
68+
if (BENCHMARK_ENABLE_GTEST_TESTS)
69+
if (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/googletest)
70+
add_subdirectory(${CMAKE_SOURCE_DIR}/googletest)
71+
set(GTEST_BOTH_LIBRARIES gtest gtest_main)
72+
elseif(BENCHMARK_DOWNLOAD_DEPENDENCIES)
73+
build_external_gtest()
74+
else()
75+
find_package(GTest REQUIRED)
76+
endif()
77+
endif()

test/CMakeLists.txt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ macro(compile_output_test name)
4242
${BENCHMARK_CXX_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
4343
endmacro(compile_output_test)
4444

45-
4645
# Demonstration executable
4746
compile_benchmark_test(benchmark_test)
4847
add_test(benchmark benchmark_test --benchmark_min_time=0.01)
@@ -135,6 +134,29 @@ endif()
135134
compile_output_test(complexity_test)
136135
add_test(complexity_benchmark complexity_test --benchmark_min_time=${COMPLEXITY_MIN_TIME})
137136

137+
###############################################################################
138+
# GoogleTest Unit Tests
139+
###############################################################################
140+
141+
if (BENCHMARK_ENABLE_GTEST_TESTS)
142+
macro(compile_gtest name)
143+
add_executable(${name} "${name}.cc")
144+
if (TARGET googletest)
145+
add_dependencies(${name} googletest)
146+
endif()
147+
target_link_libraries(${name} benchmark
148+
"${GTEST_BOTH_LIBRARIES}" ${CMAKE_THREAD_LIBS_INIT})
149+
endmacro(compile_gtest)
150+
151+
macro(add_gtest name)
152+
compile_gtest(${name})
153+
add_test(${name} ${name})
154+
endmacro()
155+
156+
add_gtest(statistics_test)
157+
endif(BENCHMARK_ENABLE_GTEST_TESTS)
158+
159+
138160
# Add the coverage command(s)
139161
if(CMAKE_BUILD_TYPE)
140162
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)

test/statistics_test.cc

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===---------------------------------------------------------------------===//
2+
// statistics_test - Unit tests for src/statistics.cc
3+
//===---------------------------------------------------------------------===//
4+
5+
#include "../src/statistics.h"
6+
#include "gtest/gtest.h"
7+
8+
namespace {
9+
TEST(StatisticsTest, Mean) {
10+
std::vector<double> Inputs;
11+
{
12+
Inputs = {42, 42, 42, 42};
13+
double Res = benchmark::StatisticsMean(Inputs);
14+
EXPECT_DOUBLE_EQ(Res, 42.0);
15+
}
16+
{
17+
Inputs = {1, 2, 3, 4};
18+
double Res = benchmark::StatisticsMean(Inputs);
19+
EXPECT_DOUBLE_EQ(Res, 2.5);
20+
}
21+
{
22+
Inputs = {1, 2, 5, 10, 10, 14};
23+
double Res = benchmark::StatisticsMean(Inputs);
24+
EXPECT_DOUBLE_EQ(Res, 7.0);
25+
}
26+
}
27+
28+
TEST(StatisticsTest, Median) {
29+
std::vector<double> Inputs;
30+
{
31+
Inputs = {42, 42, 42, 42};
32+
double Res = benchmark::StatisticsMedian(Inputs);
33+
EXPECT_DOUBLE_EQ(Res, 42.0);
34+
}
35+
{
36+
Inputs = {1, 2, 3, 4};
37+
double Res = benchmark::StatisticsMedian(Inputs);
38+
EXPECT_DOUBLE_EQ(Res, 2.5);
39+
}
40+
{
41+
Inputs = {1, 2, 5, 10, 10};
42+
double Res = benchmark::StatisticsMedian(Inputs);
43+
EXPECT_DOUBLE_EQ(Res, 5.0);
44+
}
45+
}
46+
47+
TEST(StatisticsTest, StdDev) {
48+
std::vector<double> Inputs;
49+
{
50+
Inputs = {101, 101, 101, 101};
51+
double Res = benchmark::StatisticsStdDev(Inputs);
52+
EXPECT_DOUBLE_EQ(Res, 0.0);
53+
}
54+
{
55+
Inputs = {1, 2, 3};
56+
double Res = benchmark::StatisticsStdDev(Inputs);
57+
EXPECT_DOUBLE_EQ(Res, 1.0);
58+
}
59+
}
60+
61+
} // end namespace

0 commit comments

Comments
 (0)