CMake integration

7087 views
Skip to first unread message

tsh

unread,
May 19, 2011, 3:03:04 AM5/19/11
to Google C++ Testing Framework
Hi all,

does anybody know, how to use gtest (1.5.0, 1.6.0) under windows with
cmake (..2.8.4) in another project?

When I put the following line into the CMakeList.txt:
FIND_PACKAGE(GTest REQUIRED)

The FindGTest.cmake fails to find gtest and I get an error (even when
I provide the GTEST_ROOT):
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/
Modules/FindPackageHandleStandardArgs.cmake:91 (MESSAGE):
Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR
GTEST_MAIN_LIBRARY)
Call Stack (most recent call first):
C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/
FindPackageHandleStandardArgs.cmake:252 (_FPHSA_FAILURE_MESSAGE)
C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/
FindGTest.cmake:150 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
test/CMakeLists.txt:1 (FIND_PACKAGE)

Configuring incomplete, errors occurred!

And I have to setup the paths to libraries manually. This happens
because the FindGTest module was fitted to the obsolete gtest building
using the solution file in the msvc directory. It has already been
discussed in the cmake's bug tracker:
http://www.itk.org/Bug/view.php?id=10229
But the resolution was that the error is rather on the side of gtest.

What would be IMO the best solution is to produce a GTestConfig.cmake
file in the build directory. If needed I can help creating it. What do
you think?

Best regards,

Tomas

Vlad Losev

unread,
May 19, 2011, 10:03:46 PM5/19/11
to tsh, Google C++ Testing Framework
Hi Tomas,

Please note, Google Test devs consider using installed libraries dangerous and do not support it. The authoritative text on the topic is at https://groups.google.com/forum/#!msg/googletestframework/Zo7_HOv1MJ0/F4ZBGjh_ePcJ.

CMake, the advice is to include Google Test's CMakeLists.txt into one's project directly and use the gtest and gtest_main targets defined in it.

Best regards,
Vlad

Tomáš Kazmar

unread,
May 20, 2011, 3:40:32 AM5/20/11
to Vlad Losev, Google C++ Testing Framework
Hi Vlad,

thank you for the clarification. Although, what I had in mind was not installing
the library but having a GTestConfig.cmake generated inside the build directory,
as for example, ITK, or OpenCV do it, and which is anyhow what every CMake
library should do:
http://www.cmake.org/Wiki/CMake:How_to_create_a_ProjectConfig.cmake_file
I think this was also the reason why the CMake bug was resolved as
"not fixable".

If there is a real concern about mixing different compiler flags, than checking
for the differences inside the generated config file would provide the same
as using the included CMakeLists.cmake.

Best regards,

Tomas


# Od: Vlad Losev <vl...@losev.com>
# Předmět: Re: [googletest] CMake integration
# Datum: 20.5.2011 04:29:31
# Hi Tomas,
#
# Please note, Google Test devs consider using installed libraries dangerous
# and do not support it. The authoritative text on the topic is at
# https://groups.google.com/forum/#!msg/googletestframework/Zo7_HOv1MJ0/F4ZBGjh_ePcJ
# .
#
# CMake, the advice is to include Google Test's CMakeLists.txt into one's
# project directly and use the gtest and gtest_main targets defined in it.
#
# Best regards,
# Vlad
#
# On Thu, May 19, 2011 at 12:03 AM, tsh <tomash...@seznam.cz> wrote:
#
# > Hi all,
# >
# > does anybody know, how to use gtest (1.5.0, 1.6.0) under windows with
# > cmake (..2.8.4) in another project?
# >
# > When I put the following line into the CMakeList.txt:
# > FIND_PACKAGE(GTest REQUIRED)
# >
# > The FindGTest.cmake fails to find gtest and I get an error (even when
# > I provide the GTEST_ROOT):
# > CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/
# > Modules/FindPackageHandleStandardArgs.cmake:91 (MESSAGE):
# > Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR
# > GTEST_MAIN_LIBRARY)
# > Call Stack (most recent call first):
# > C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/
# > FindPackageHandleStandardArgs.cmake:252 (_FPHSA_FAILURE_MESSAGE)
# > C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/
# > FindGTest.cmake:150 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
# > test/CMakeLists.txt:1 (FIND_PACKAGE)
# >
# > Configuring incomplete, errors occurred!
# >
# > And I have to setup the paths to libraries manually. This happens
# > because the FindGTest module was fitted to the obsolete gtest building
# > using the solution file in the msvc directory. It has already been
# > discussed in the cmake's bug tracker:
# > http://www.itk.org/Bug/view.php?id=10229
# > But the resolution was that the error is rather on the side of gtest.
# >
# > What would be IMO the best solution is to produce a GTestConfig.cmake
# > file in the build directory. If needed I can help creating it. What do
# > you think?
# >
# > Best regards,
# >
# > Tomas
#
#
#

Zhanyong Wan (λx.x x)

unread,
May 23, 2011, 1:44:46 PM5/23/11
to Tomáš Kazmar, Vlad Losev, Google C++ Testing Framework
Hi Tomas,

2011/5/20 Tomáš Kazmar <Tomash...@seznam.cz>:


> Hi Vlad,
>
> thank you for the clarification. Although, what I had in mind was not installing
> the library but having a GTestConfig.cmake generated inside the build directory,
> as for example, ITK, or OpenCV do it, and which is anyhow what every CMake
> library should do:
>  http://www.cmake.org/Wiki/CMake:How_to_create_a_ProjectConfig.cmake_file
> I think this was also the reason why the CMake bug was resolved as
> "not fixable".

Let me make sure I understand your plan. Is it true that:

1. Your project includes a copy of gtest's source files and cmake scripts.

2. When you build your project, you want gtest to be automatically
built using the settings specified by its cmake scripts -- you don't
want to write a cmake script for gtest yourself.

3. In order to implement #2, you want to use find_package() from your
project to find gtest.

?

Assuming my understanding is correct...

#1 and #2 sound reasonable. As to #3, is find_package() the
recommended way to find a library that's already *included* as part of
your project? I'm not a CMake power user, but my impression is that
CMake scripts can be made recursive such that your top-level CMake
script can reference a CMake script in a sub-directory, without using
find_package(). Will this work for you?

Thanks,

--
Zhanyong

Pat Notz

unread,
May 24, 2011, 12:24:31 AM5/24/11
to Zhanyong Wan (λx.x x), Tomáš Kazmar, Vlad Losev, Google C++ Testing Framework
2011/5/23 Zhanyong Wan (λx.x x) <w...@google.com>:

There appears to be a chicken-and-egg problem with using
find_package(GTest) because it will only succeed if gtest is already
built. I'm sure the CMake gurus could make it first build gtest and
then do the find_package() and continue the build but that's beyond my
skill level...

After struggling with this myself, and wanting reliable builds of my
code and tests with different compilers, I finally decided to include
the gtest code in a subdirectory of my project (gtest-1.6.0) and build
it along with the rest of my code. It only adds two compiles so for me
it's a small price to pay.

For a very simple project of mine, here's the CMakeLists.txt file I'm
using. Perhaps you'll find it useful.

---- CMakeLists.txt ----
cmake_minimum_required(VERSION 2.6)

PROJECT(FastArray CXX C)

find_package(Threads)

################################################################################
# GTest
# See: http://code.google.com/p/googletest/
################################################################################
if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_HAS_PTHREAD=1")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_HAS_PTHREAD=0")
endif()
set(GTEST_DIR gtest-1.6.0)
set(GTEST_INCLUDE_DIRECTORIES ${GTEST_DIR}/include ${GTEST_DIR}
${GTEST_DIR}/src)
include_directories(${GTEST_INCLUDE_DIRECTORIES})
add_library(gtest ${GTEST_DIR}/src/gtest-all.cc ${GTEST_DIR}/src/gtest_main.cc)
enable_testing(true)

################################################################################
# FastArray - header file only so unit-tests are the only executable
################################################################################
include_directories(src ${GTEST_INCLUDE_DIRS})
add_executable(unit-tests src/unit-tests.cpp)
target_link_libraries(unit-tests gtest ${CMAKE_THREAD_LIBS_INIT})
add_test(unit-tests unit-tests)

Zhanyong Wan (λx.x x)

unread,
May 24, 2011, 1:10:22 AM5/24/11
to Pat Notz, Tomáš Kazmar, Vlad Losev, Google C++ Testing Framework
Hi Pat,

2011/5/23 Pat Notz <pat...@gmail.com>

This sounds like exactly the right solution: we want the users to
include a copy of gtest's source code in their own project, instead of
depending on whichever version of gtest that may or may be present on
the machine. :)

> For a very simple project of mine, here's the CMakeLists.txt file I'm
> using. Perhaps you'll find it useful.

Thanks for sharing!

>
> ---- CMakeLists.txt ----
> cmake_minimum_required(VERSION 2.6)
>
> PROJECT(FastArray CXX C)
>
> find_package(Threads)
>
> ################################################################################
> # GTest
> # See: http://code.google.com/p/googletest/
> ################################################################################
> if (CMAKE_USE_PTHREADS_INIT)  # The pthreads library is available and allowed.
>  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_HAS_PTHREAD=1")
> else()
>  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_HAS_PTHREAD=0")
> endif()
> set(GTEST_DIR gtest-1.6.0)
> set(GTEST_INCLUDE_DIRECTORIES ${GTEST_DIR}/include ${GTEST_DIR}
> ${GTEST_DIR}/src)

IIRC, we shouldn't need ${GTEST_DIR}/src in the include search path.

> include_directories(${GTEST_INCLUDE_DIRECTORIES})
> add_library(gtest ${GTEST_DIR}/src/gtest-all.cc ${GTEST_DIR}/src/gtest_main.cc)
> enable_testing(true)

This looks good. It would be even nicer if some CMake expert can show
us a way to extract the above definitions from gtest's own CMake
script instead.

Thanks,

>
> ################################################################################
> # FastArray - header file only so unit-tests are the only executable
> ################################################################################
> include_directories(src ${GTEST_INCLUDE_DIRS})
> add_executable(unit-tests src/unit-tests.cpp)
> target_link_libraries(unit-tests gtest ${CMAKE_THREAD_LIBS_INIT})
> add_test(unit-tests unit-tests)

--
Zhanyong

Pat Notz

unread,
May 24, 2011, 1:29:57 PM5/24/11
to Zhanyong Wan (λx.x x), Tomáš Kazmar, Vlad Losev, Google C++ Testing Framework

Yes, you're correct. Thanks.

>
>> include_directories(${GTEST_INCLUDE_DIRECTORIES})
>> add_library(gtest ${GTEST_DIR}/src/gtest-all.cc ${GTEST_DIR}/src/gtest_main.cc)
>> enable_testing(true)
>
> This looks good.  It would be even nicer if some CMake expert can show
> us a way to extract the above definitions from gtest's own CMake
> script instead.
>

I think that's what Tomáš was suggesting with the suggestion of a
GTestConfig.cmake file. However, these project files are only intended
to work with prebuilt projects. So, you'd have to go run cmake && make
in the gtest project and then run cmake && make in client code's
project. In defense of that idea, I think that's what he was
originally asking to do. That may be a little fragile (you have to
make sure to use the same compiler and flags in both projects) but
there's nothing wrong with that. In cmake, this is even designed to
work for projects that aren't "installed" -- they're just built in
place.

I think another approach would be to include gtest in your project (as
I've done here) and rely on GTests's CMakeLists.txt file to build it.
In that case, I'd replace the above cmake lines with :

add_subdirectory(gtest-1.6.0).

For that to work, we need gtest's CMakeLists.txt file define some
variables that we can use in the rest of the client code. Probably
just ${GTEST_INCLUDE_DIRECTORIES} and ${GTEST_LIBRARIES} (or two for
the case with and without main()).

If I have some time I may take a crack at that...

~ Pat

Zhanyong Wan (λx.x x)

unread,
May 24, 2011, 1:38:44 PM5/24/11
to Pat Notz, Tomáš Kazmar, Vlad Losev, Google C++ Testing Framework
2011/5/24 Pat Notz <pat...@gmail.com>:

Thanks for clarifying.

> I think another approach would be to include gtest in your project (as
> I've done here) and rely on GTests's CMakeLists.txt file to build it.

Yes, this is what we recommend the users to do.

> In that case, I'd replace the above cmake lines with :
>
> add_subdirectory(gtest-1.6.0).
>
> For that to work, we need gtest's CMakeLists.txt file define some
> variables that we can use in the rest of the client code. Probably
> just ${GTEST_INCLUDE_DIRECTORIES} and ${GTEST_LIBRARIES} (or two for
> the case with and without main()).
>
> If I have some time I may take a crack at that...

Sounds great! ;-)

>
>  ~ Pat
>
>
>> Thanks,
>>
>>>
>>> ################################################################################
>>> # FastArray - header file only so unit-tests are the only executable
>>> ################################################################################
>>> include_directories(src ${GTEST_INCLUDE_DIRS})
>>> add_executable(unit-tests src/unit-tests.cpp)
>>> target_link_libraries(unit-tests gtest ${CMAKE_THREAD_LIBS_INIT})
>>> add_test(unit-tests unit-tests)
>>
>>
>>
>> --
>> Zhanyong
>>
>

--
Zhanyong

Vlad Losev

unread,
May 24, 2011, 1:58:31 PM5/24/11
to Pat Notz, Zhanyong Wan (λx.x x), Tomáš Kazmar, Google C++ Testing Framework
Pat -

2011/5/24 Pat Notz <pat...@gmail.com>
In my experience, if you add_subdirectory() with gtest to your project, the targets gtest and gtest_main defined by gtest's CMakeLists.txt are visible and can be passed into target_link_libraries. That removes the need for ${GTEST_LIBRARIES}. Do you find it not to be the case?

Also it makes sense to expose GTEST_CXX_FLAGS and GTEST_LINK_FLAGS. They should be computed based on the result of gtest's pthreads detection.

If I have some time I may take a crack at that...

 ~ Pat


> Thanks,
>
>>
>> ################################################################################
>> # FastArray - header file only so unit-tests are the only executable
>> ################################################################################
>> include_directories(src ${GTEST_INCLUDE_DIRS})
>> add_executable(unit-tests src/unit-tests.cpp)
>> target_link_libraries(unit-tests gtest ${CMAKE_THREAD_LIBS_INIT})
>> add_test(unit-tests unit-tests)
>
>
>
> --
> Zhanyong
>

- Vlad

Pat Notz

unread,
May 24, 2011, 6:15:42 PM5/24/11
to Vlad Losev, Zhanyong Wan (λx.x x), Tomáš Kazmar, Google C++ Testing Framework
2011/5/24 Vlad Losev <vl...@losev.com>:
> Pat -

>
> In my experience, if you add_subdirectory() with gtest to your project, the
> targets gtest and gtest_main defined by gtest's CMakeLists.txt are visible
> and can be passed into target_link_libraries. That removes the need
> for ${GTEST_LIBRARIES}. Do you find it not to be the case?
> Also it makes sense to expose GTEST_CXX_FLAGS and GTEST_LINK_FLAGS. They
> should be computed based on the result of gtest's pthreads detection.

Ahh, that's much better and works great! At this point, it doesn't
look like I need GTEST_CXX_FLAGS and GTEST_LINK_FLAGS but that may be
a good idea to establish those for future proofing; also, it may be
that there are some flags necessary for different compilers that I'm
not using. For now, all I needed was gtest, gtest_main and
${gtest_SOURCE_DIR} (see below).

In reading through gtest's CMakeLists.txt file I see that this was in
the comments all along -- shame on me. Still, I think it'd be a good
idea to put usage comments like that at the top of the CMakeLists.txt
file and/or in the README.

In case anyone is interested, here's what my super-simple project
CMakeLists.txt file now looks like. I have gtest 1.6.0 as a
subdirectory in my project. I've tried this on Darwin 10.5.8 with GCC
4.4.6 and 4.5.3 and on Linux RHEL 5.6 with GCC 4.4.4 and Intel 11.1.
Thanks for all the help! Things are working seamlessly for me now.

---- CMakeLists.txt ----
cmake_minimum_required(VERSION 2.6)

PROJECT(FastArray)

################################################################################
# GTest - http://code.google.com/p/googletest/
################################################################################
add_subdirectory(gtest-1.6.0)
enable_testing(true)

################################################################################
# FastArray (header file only library)
################################################################################
include_directories(src ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
add_executable(unit-tests src/unit-tests.cpp)
target_link_libraries(unit-tests gtest gtest_main)
add_test(unit-tests unit-tests)

Tomáš Kazmar

unread,
May 25, 2011, 2:51:25 AM5/25/11
to Pat Notz, Zhanyong Wan (λx.x x), Vlad Losev, Google C++ Testing Framework
# >> > Let me make sure I understand your plan.  Is it true that:
# >> >
# >> > 1. Your project includes a copy of gtest's source files and cmake scripts.
# >> >
# >> > 2. When you build your project, you want gtest to be automatically
# >> > built using the settings specified by its cmake scripts -- you don't
# >> > want to write a cmake script for gtest yourself.
# >> >
# >> > 3. In order to implement #2, you want to use find_package() from your
# >> > project to find gtest.
# >> >
# >> > ?
# >> >
# >> > Assuming my understanding is correct...
# >> >
# >> > #1 and #2 sound reasonable.  As to #3, is find_package() the
# >> > recommended way to find a library that's already *included* as part of
# >> > your project?  I'm not a CMake power user, but my impression is that
# >> > CMake scripts can be made recursive such that your top-level CMake
# >> > script can reference a CMake script in a sub-directory, without using
# >> > find_package().  Will this work for you?

Actually, what I originally intended was having a single pre-compiled copy
of gtest. In my setting this is perfectly correct as all of my projects work with
a different common library (which uses gtest for testing as well), hence
they have the same compilation flags anyway.
This kind of usage would be much simpler, if the GTestConfig.cmake is
generated inside the _gtest_ build directory. Inside this file you can check
for the same compilation flags, so there is no downside compared to
the current state. And one can even have multiple copies of gtest built,
each one with its GTestConfig.cmake and select by seting the GTest_DIR
variable.

Anyhow, after reading the discussion, I think I will stick with using gtest
through ADD_SUBDIRECTORY. Maybe there should be a short notice
about how to do this in the readme file or in the CMakeLists.txt.

However, there are things I still do not understand. For example, if you
want to ensure that there are the same compilation flags for the project
and for gtest, why is there the option gtest_force_shared_crt? Especially,
when there is the following in the readme:

Please note that one must use
the same option to compile both gtest and the test code. If you use
Visual Studio 2005 or above, we recommend the -md version as /MD is
the default for new projects in these versions of Visual Studio.

Would not this easily lead to a trouble, when the project uses
the default CMake settings, ie. shared crt and gtest gets compiled with its
default, ie. static crt? What is the reason for tweaking this setting inside
gtest?

Best regards,

Tomas


Vlad Losev

unread,
May 25, 2011, 12:35:36 PM5/25/11
to Tomáš Kazmar, Pat Notz, Zhanyong Wan (λx.x x), Google C++ Testing Framework


2011/5/24 Tomáš Kazmar <Tomash...@seznam.cz>
This is a Windows-only option. When you tell CMake to build gtest as a static library by setting BUILD_SHARED_LIBS to OFF, CMake will configure compiler flags to use the static version of the C++ runtime library. If the binary links to other DLLs, this will lead to multiple copies of static data in it, violating the ODR rule and resulting in bugs. This option is provided to override that behavior and force linking to the DLL version of the runtime library, resulting in a single copy of static data.

Best regards,

Tomas



Ryan W Sims

unread,
Jun 8, 2011, 10:39:00 PM6/8/11
to googletes...@googlegroups.com
When I use this method, ctest tries to run all the gtest unit tests, unless I pass -E gtest to exclude them. They're not getting *built*, because the flag isn't set, but for some reason ctest tries to run them and of course they fail. Is this expected behavior?

Pat Notz

unread,
Jun 9, 2011, 6:13:53 PM6/9/11
to googletes...@googlegroups.com

Just to be clear, I think you're saying that if you haven't built yet
and just run "ctest" or "make test" the ctest tries to run your unit
tests but fails since they aren't built. But, if you run "make; make
test" or "make all test" or "make ; ctest" then things are okay. Is
that what you're seeing?

That's the behavior I see. It seems wrong to me but I guess I got used
to it and forgot to mention it. It does seem like there should be a
dependency that triggers a build before the test is run. I'll check
the cmake documentation to see if I can figure out what's missing.

Pat Notz

unread,
Jun 9, 2011, 6:27:27 PM6/9/11
to googletes...@googlegroups.com

According this this post on Stack Overflow it appears to be a bug in
cmake/ctest:

http://stackoverflow.com/questions/733475/cmake-ctest-make-test-doesnt-build-tests

There, they propose adding a new target ("make check") that has the
right dependency or using "make all test".

Ryan Sims

unread,
Jun 9, 2011, 6:57:12 PM6/9/11
to Pat Notz, googletes...@googlegroups.com

I don't want them to be built, that's what the option is there for in gtest's CmakeLists. My understanding, and afaict the intent of the option, is that those tests should be neither built not run unless I explicitly want them to be. The fact that they aren't built is correct; the fact that they are run is not.

Reply all
Reply to author
Forward
0 new messages