I would like to set a variable that is available for modification in a third-party library which I have included as a subdirectory (add_subdirectory(.../third_party/libA)
). The library allows me to enable/disable certain portions of the build process such as to including testing targets, for example: set(BUILD_TESTS OFF)
.
However, what am I to do if multiple libraries contain the same option, named the same? I understand there exists the PARENT_SCOPE
option of set()
for the “opposite direction” of what I am looking to accomplish, but is there a way to restrict the scope somehow such that I can do the following (simulated behavior below):
project(my_project)
set(libA_BUILD_TESTS OFF) # I DO NOT want to build tests for libA
add_subdirectory("${my_project_SOURCE_DIR}/third_party/libA")
set(libB_BUILD_TESTS ON) # I DO want to build tests for libB
add_subdirectory("${my_project_SOURCE_DIR}/third_party/libB")
Because I have no control over the variable names of the third-party library, variables libA_BUILD_TESTS
and libB_BUILD_TESTS
do not actually exist. They both simply have BUILD_TESTS
.
-
Would it be possible to do this and expect each should be set properly? I am not familiar with
how CMake handles the timing of variable resolution…set(BUILD_TESTS OFF) add_subdirectory(.../third_party/libA) set(BUILD_TESTS ON) add_subdirectory(.../third_party/libB)
-
Is there a more explicit/safe way to declare that I want those two to be different
beyond sharing the same variable name? To me, reusing the same variable name seems
fundamentally prone to error and particularly “gross.” I do not like this because it
makes the variable “stateful” which makes things harder to track during the build. -
Am I even thinking about this fundamental variable-setting process correctly? Perhaps
my feelings in #2 are simply not “the way things are done.”
Some random things I tried (unsuccessfully):
Settings properties specific to the subdirectory:
set(libA_dir "${my_project_SOURCE_DIR}/third_party/libA")
set(libB_dir "${my_project_SOURCE_DIR}/third_party/libB")
set_property(DIRECTORY ${libA_dir} PROPERTY BUILD_TESTS OFF)
set_property(DIRECTORY ${libB_dir} PROPERTY BUILD_TESTS ON)
Settings target properties (doesn’t work as target doesn’t yet exist):
# does not work because the libA target does not yet exist
set_target_properties(libA PROPERTIES BUILD_TESTS OFF)
add_subdirectory("${my_project_SOURCE_DIR}/third_party/libA")
# this does work based on how the third party CMake was written...
find_package(libA REQUIRED)
Setting target properties after target is defined (doesn’t work because the logic has
already been processed before seeing my set_target_properties):
add_subdirectory("${my_project_SOURCE_DIR}/third_party/libA")
# does not work because the subdir was already included and seems to have not respected
# the options here due to timing/ordering.
set_target_properties(libA PROPERTIES BUILD_TESTS OFF)
# this does work based on how the third party CMake was written...
find_package(libA REQUIRED)
Ultimately: I am looking to understand methods for ensuring “isolation” of variable assignment between these two libraries, especially when the same variable would have two different values (i.e. “I want to build tests for libA but not for libB”). Thank you.