Skip to content

Conversation

EricWF
Copy link
Contributor

@EricWF EricWF commented Nov 25, 2017

As Dominic and I have previously discussed, there is some
need/desire to improve the testing situation in Google Benchmark.

One step to fixing this problem is to make it easier to write
unit tests by adding support for GTest, which is what this patch does.

By default it looks for an installed version of GTest. However the
user can specify -DBENCHMARK_BUILD_EXTERNAL_GTEST=ON to instead
download, build, and use copy of gtest from source. This is
quite useful when Benchmark is being built in non-standard configurations,
such as against libc++ or in 32 bit mode.

As Dominic and I have previously discussed, there is some
need/desire to improve the testing situation in Google Benchmark.

One step to fixing this problem is to make it easier to write
unit tests by adding support for GTest, which is what this patch does.

By default it looks for an installed version of GTest. However the
user can specify -DBENCHMARK_BUILD_EXTERNAL_GTEST=ON to instead
download, build, and use copy of gtest from source. This is
quite useful when Benchmark is being built in non-standard configurations,
such as against libc++ or in 32 bit mode.
@AppVeyorBot
Copy link

Build benchmark 848 failed (commit 6cd3b8eda5 by @EricWF)

add_library(gtest UNKNOWN IMPORTED)
add_library(gtest_main UNKNOWN IMPORTED)
set_target_properties(gtest PROPERTIES
IMPORTED_LOCATION ${install_dir}/lib/libgtest.a
Copy link
Collaborator

@LebedevRI LebedevRI Nov 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+ INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/googletest/include

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack.

IMPORTED_LOCATION ${install_dir}/lib/libgtest.a
)
set_target_properties(gtest_main PROPERTIES
IMPORTED_LOCATION ${install_dir}/lib/libgtest_main.a
Copy link
Collaborator

@LebedevRI LebedevRI Nov 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+ INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/googletest/include

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack.

)
add_dependencies(gtest googletest)
add_dependencies(gtest_main googletest)
set(GTEST_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/googletest/include)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- set(GTEST_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/googletest/include)


if (BENCHMARK_ENABLE_GTEST_TESTS)
include(HandleGTest)
include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line still needs to stay for when out-of-tree GTest installations are used. However the SYSTEM can be removed, since it seems to be implicitly specified after adding the INTERFACE_SYSTEM_INCLUDE_DIRECTORIES line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind... You're right.

add_dependencies(${name} googletest)
endif()
target_link_libraries(${name} benchmark
${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so now ${GTEST_BOTH_LIBRARIES} will properly add gtest include dirs.

Copy link
Collaborator

@LebedevRI LebedevRI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${} when not wrapped into "" will likely break when spaces are present.

@AppVeyorBot
Copy link

Build benchmark 849 failed (commit 9d0bacadd0 by @EricWF)

@AppVeyorBot
Copy link

Build benchmark 850 failed (commit 497ff83244 by @EricWF)

@AppVeyorBot
Copy link

Build benchmark 851 failed (commit dbdcb0b7c4 by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling f50c919 on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 852 failed (commit f8f8985666 by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling 0d971fd on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 853 failed (commit 647665d819 by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling 1cafd58 on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 854 failed (commit 0c90eb3b8b by @EricWF)

@AppVeyorBot
Copy link

Build benchmark 855 failed (commit 7813239f2e by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling 1cafd58 on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 857 failed (commit decddf1fe5 by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling cc5ce7e on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 858 completed (commit c32affa913 by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling 18bf4e1 on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 859 failed (commit 8b1aed6a5b by @EricWF)

CMakeLists.txt Outdated

# This option is useful when building Benchmark in odd configurations, such as 32bit mode
# or against libc++.
option(BENCHMARK_BUILD_GTEST_INTREE "Download and build a custom copy of GTest to use" ON)
Copy link
Collaborator

@LebedevRI LebedevRI Nov 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be two options:

  1. build gtest
  2. if build gtest, is downloading allowed? this really really should default to false.
    build systems downloading stuff from internet is such a disgrace :/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM. Thanks for the feedback.

```bash
$ git clone https://github.com/google/benchmark.git
# Benchmark requires GTest as a dependency. Add the source tree as a subdirectory.
$ git clone https://github.com/google/googletest.git benchmark/googletest
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd highly recommend

  1. providing an option specifying the path to the gtest sources
  2. defaulting to /usr/src/googletest/, since that is the natural location, and is where debian puts it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, I don't really care to allow users to specify random/arbirtrary out-of-tree GTest source directories. We already have a mechanism to allow users to specify arbitrary GTest installation using CMAKE_MODULE_PATH to influence find_package(GTest).

I've changed the build, as you've suggested, to only download dependencies if -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON is specified. So GTest installations among /usr/ and /usr/local/ should work by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not git submodules?

PREFIX "${CMAKE_BINARY_DIR}/googletest"
INSTALL_DIR "${CMAKE_BINARY_DIR}/googletest"
CMAKE_CACHE_ARGS
-DCMAKE_BUILD_TYPE:STRING=${GTEST_BUILD_TYPE}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all this is just to propagate the current params, maybe it would be simpler to just use 2-step approach?
Here is how it looks in practice: [0] [1]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked into 2 step approaches, but I think that they're less idiomatic CMake.
If CMake meant for you to download and load subdirectories during configuration time, they would have provided an actually supported way to do so.

Copy link
Collaborator

@LebedevRI LebedevRI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more thoughts since the small project i maintain has already had gone through the similar gtest integration.

@AppVeyorBot
Copy link

Build benchmark 860 failed (commit eb4cebbe3a by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling d4ba15d on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 861 completed (commit 670f5304d8 by @EricWF)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.04%) to 86.815% when pulling 6a209b9 on efcs:add-googletest into 27e0b43 on google:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.06%) to 86.799% when pulling 969426f on efcs:add-googletest into 27e0b43 on google:master.

@AppVeyorBot
Copy link

Build benchmark 862 completed (commit ec5d73f757 by @EricWF)

@AppVeyorBot
Copy link

Build benchmark 865 completed (commit e1d1cd3986 by @EricWF)

Copy link
Collaborator

@LebedevRI LebedevRI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the first step looks great!

* Otherwise, if `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` is specified during
configuration, the library will automatically download and build any required
dependencies.
* Otherwise, if nothing is done, CMake will use `find_package(GTest REQUIRED)`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be the default, no? ie, why do we have it required to have it in-tree instead of just letting cmake do the right thing?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/usr/share/doc/googletest/README.Debian:

	Use of precompiled libgtest Not Recommended
	-------------------------------------------

The Google C++ Testing Framework uses conditional compilation for some
things.  Because of the C++ "One Definition Rule", gtest and gmock
must be compiled with exactly the same flags as your C++ code under
test.  Because this is hard to manage, upstream no longer recommends
using precompiled libraries [1].


	Using GTest with your project
	-----------------------------

See the upstream README for instructions on using gtest with your
project.  The sources for libgtest are installed into
/usr/src/googletest/googletest along with CMakeLists.txt for use with
cmake.

If your build system uses CMake, the ExternalProject command can be
used to build gtest, then FindGTest can be used to find the built
library.


	Using gmock with your project
	-----------------------------

See the upstream README for instructions on using gmock with your
project.  The sources for libgmock are installed into
/usr/src/googletest/googlemock along with CMakeLists.txt for use with
cmake.

With this Debian package something like the following should be enough to build 
a static library (which also includes gtest):

g++ -I/usr/src/googletest/googlemock -c /usr/src/googletest/googlemock/src/gmock-all.cc
g++ -I/usr/src/googletest/googletest -c /usr/src/googletest/googletest/src/gtest-all.cc
ar -rv libgmock.a gmock-all.o gtest-all.o



[1] http://groups.google.com/group/googletestframework/browse_thread/thread/668eff1cebf5309d

 -- Steve M. Robbins <[email protected]>, Sat, 19 Nov 2016 21:58:04 -0600

@EricWF EricWF merged commit 7db02be into google:master Dec 13, 2017
@EricWF EricWF deleted the add-googletest branch December 13, 2017 23:27
@coveralls
Copy link

Coverage Status

Coverage remained the same at 86.926% when pulling fb279be on efcs:add-googletest into de725e5 on google:master.

JBakamovic pushed a commit to JBakamovic/benchmark that referenced this pull request Dec 6, 2018
* Add support for GTest based unit tests.

As Dominic and I have previously discussed, there is some
need/desire to improve the testing situation in Google Benchmark.

One step to fixing this problem is to make it easier to write
unit tests by adding support for GTest, which is what this patch does.

By default it looks for an installed version of GTest. However the
user can specify -DBENCHMARK_BUILD_EXTERNAL_GTEST=ON to instead
download, build, and use copy of gtest from source. This is
quite useful when Benchmark is being built in non-standard configurations,
such as against libc++ or in 32 bit mode.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants