Build Google Test like shared library

2019-07-27 14:19发布

问题:

I have the project with many subprojects, and one of them is google test project. I must build google test library as shared library every time when I build the main project, but single way to build the google test as shared is setting global option "BUILD_SHARED_LIBS=ON". Unfortunately, other projects are depended of this option. So, how to build google test as shared library in this case?

I tried to replace

cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)

with

add_library(gtest SHARED src/gtest-all.cc)
add_library(gtest_main "SHARED src/gtest_main.cc)

but it is no effect.

回答1:

Two possibilities: If you are not at liberty to change the gtest sources, set the BUILD_SHARED_LIBS option before the add_subdirectory call for gtest, and reset it back immediately after:

set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCED)
add_subdirectory(gtest)
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD} CACHE BOOL "" FORCED)

Alternatively, if you do want to change the gtest sources, replace the cxx_library() with calls to cxx_shared_library():

cxx_shared_library(gtest "${cxx_strict}" src/gtest-all.cc)   

This is required because the cxx_library_* macros set some additional stuff for the build that a plain add_library would miss.

Note that you might still want to keep gtest_main as a static library, as it defines the entry point (aka main()) for your program and moving that to a shared library might not have the effect that you intended.



回答2:

Set variable BUILD_SHARED_LIBS to the desired value before stepping into googletest project and restore the variable after that.

Because googletest defines BUILD_SHARED_LIBS as option (that is, cached variable), it is better to assign initial cache value to that variable before inclusion of googletest.

# Need to assign value for cache variable explicitely.
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
...
# Store old value
set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
# Assign desired value for subproject
set(BUILD_SHARED_LIBS ON)
# Step into subproject
add_subdirectory(gtest)
# Restore old value
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD})

Note, that for temporary value's changing you needn't to modify cache: it is sufficient to set normal variable. This is possible because of CMake policy of processing normal and cache variables with the same name.