Transfer between scopes in cmake

242 Views Asked by At

I do have a multi-component application, modeled with having one parent and two childs. The first one defines libraries, include files, etc. The second one wants to use that information. How can I do that, without coding those names manually?

parent/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
set(MYNAME1 MyName1)
set(MYLINKNAME MyLinkName)
add_subdirectory(sub1)
message("Parent1: " ${MYNAME1} " " ${MYNAME2} " " ${MYNAME3} " " ${MYLINKNAME})
add_subdirectory(sub2)
message("Parent2: " ${MYNAME1} " " ${MYNAME2} " " ${MYNAME3} " " ${MYLINKNAME})

sub1/CMakeLists.txt

set(MYNAME1 MySub1 PARENT_SCOPE)
set(MYNAME2 MySub2 PARENT_SCOPE)
set(MYNAME3 MySub3)
set(MYLINKNAME IsLinked)
message("Sub1: " ${MYNAME1} " " ${MYNAME2} " " ${MYNAME3} " " ${MYLINKNAME})

sub1/CMakeLists.txt

message("Sub2: " ${MYNAME1} " " ${MYNAME2} " " ${MYNAME3} " " ${MYLINKNAME})
set(MYNAME2 OtherName)

The result is:

Sub1: MyName1  MySub3 IsLinked
Parent1: MySub1 MySub2  MyLinkName
Sub2: MySub1 MySub2  MyLinkName
Parent1: MySub1 MySub2  MyLinkName

Which means that I can transfer information using PARENT_SCOPE from sub1 to sub2. However, I would like to avoid patching packages for testing, logging, etc. Any suggestions?

1

There are 1 best solutions below

2
tamas.kenez On BEST ANSWER

Replying to the question in your comment:

Transferring the location of the include files from a standard package to your main program

You can find an example for this in the official FindZLIB.cmake module:

add_library(ZLIB::ZLIB UNKNOWN IMPORTED)
set_target_properties(ZLIB::ZLIB PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}")

The find-module creates an imported library ZLIB::ZLIB and set its INTERFACE_INCLUDE_DIRECTORIES property to the location of the zlib include files.

Later, in your main program you invoke the find-module:

find_package(ZLIB REQUIRED)

add your main target:

add_executable(mymain main.cpp)

and add ZLIB as dependency:

target_link_libraries(mymain ZLIB::ZLIB)

The location of the zlib include files will be available in main.cpp but you can also query it in your CMakeLists.txt:

get_target_property(zlib_incl_dirs ZLIB::ZLIB INTERFACE_INCLUDE_DIRECTORIES)

The same method works also for

  • config-module which is like a find-module but it's shipped with the library
  • child-projects:

In main/child1/CMakeLists.txt you can write:

add_library(child1 ...)
target_include_directories(child1 ... PUBLIC ... )

In main/child2/CMakeLists.txt you can write

add_executable(child2 child2.cpp)
target_link_libraries(child2 child1)

In child2.cpp the PUBLIC include directories will be added to the include path. You can also query it in your main/child2/CMakeLists.txt:

get_target_property(child1_incl_dirs child1 INTERFACE_INCLUDE_DIRECTORIES)