I have a CMake project that depends on Google Test library.
I've added Google Test using ExternalProject_Add
and add_subdirectory
as described here (https://github.com/google/googletest/tree/master/googletest section Incorporating Into An Existing CMake Project
).
Now, after command add_subdirectory
I want to check version of included project gtest
and gmock
, however gtest_VERSION
and gmock_VERSION
variables is undefined. Is it possible to get project version added by add_subdirectory
?
Since you don't have direct access to sub-directories local variables, I wanted to add my variants of making the gtest_VERSION
variable CACHED
and therefore globally accessible:
CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE
A CMake language file or module to be included by the
project()
command. This is intended for injecting custom code into project builds without modifying their source.
file(
WRITE "${CMAKE_BINARY_DIR}/SetProjectVersion.cmake"
[=[
set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION}" CACHE INTERNAL "")
]=]
)
set(
CMAKE_PROJECT_gtest_INCLUDE
"${CMAKE_BINARY_DIR}/SetProjectVersion.cmake"
)
Overwrite the project()
command
cmake_policy(SET CMP0048 NEW)
macro(project)
_project(${ARGN})
set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION}" CACHE INTERNAL "")
endmacro()
Variable <PROJECT-NAME>_VERSION has a local scope. Thus a version variable, defined by a subproject, is not visible by a main project.
Assuming a subproject's CMakeLists.txt
performs project()
call like
project(<project-name> VERSION <version-string> ...)
version string can be easily extracted with regular expressions:
# subproject_version(<subproject-name> <result-variable>)
#
# Extract version of a sub-project, which was previously included with add_subdirectory().
function(subproject_version subproject_name VERSION_VAR)
# Read CMakeLists.txt for subproject and extract project() call(s) from it.
file(STRINGS "${${subproject_name}_SOURCE_DIR}/CMakeLists.txt" project_calls REGEX "[ \t]*project\\(")
# For every project() call try to extract its VERSION option
foreach(project_call ${project_calls})
string(REGEX MATCH "VERSION[ ]+([^ )]+)" version_param "${project_call}")
if(version_param)
set(version_value "${CMAKE_MATCH_1}")
endif()
endforeach()
if(version_value)
set(${VERSION_VAR} "${version_value}" PARENT_SCOPE)
else()
message("WARNING: Cannot extract version for subproject '${subproject_name}'")
endif()
endfunction(subproject_version)
# The function's usage:
subproject_version(gtest gtest_version)
message("VERSION for gtest: ${gtest_version}")
Implementation above uses variable <PROJECT-NAME>_SOURCE_DIR, which contains source directory of the subproject. Unlike to <PROJECT-NAME>_VERSION
variable, variable with source directory has global visibility (it is CACHED, actually), thus it can be used outside of the subproject.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With