Build library dependencies from anywhere in the source tree.

If you already have all your libraries under your project root, you don't need this.

Manifest Utils

include(/path/to/ManifestFile)

# Add a library from anywhere in the source tree, only once, as a "subdirectory"
function(builddep\_find\_lib lib_name)
    # Already loaded?
    get_property(${lib_name}\_defined\_globally GLOBAL PROPERTY global_${lib_name}_loaded DEFINED)

    if(NOT ${lib_name}\_defined\_globally)
        define_property(GLOBAL PROPERTY global_${lib_name}_loaded 
            BRIEF_DOCS "Boolean variable indicating whether a lib was loaded"
            FULL_DOCS "See Brief Docs")
        set_property(GLOBAL PROPERTY global_${lib_name}_loaded FALSE)
    endif(NOT ${lib_name}\_defined\_globally)

    get_property(${lib_name}\_loaded GLOBAL PROPERTY global\_${lib_name}_loaded)

    # Use the two arg form of add\_subdirectory to specify the binary\_dir for the dependency
    if(NOT ${lib_name}_loaded)
        set_property(GLOBAL PROPERTY global_${lib_name}_loaded TRUE)
        string(TOUPPER ${lib_name} lib\_name\_upper)
        add_subdirectory(${${lib\_name\_upper}\_IMPORT\_DIR} ${CMAKE\_BINARY\_DIR}/${lib_name})
    endif(NOT ${lib_name}_loaded)
endfunction()


# Add just the library's public includes.
# Only needed to handle circular header deps.
#
function(builddep\_target\_add\_headers target\_name scope lib_name)
  string(TOUPPER ${lib_name} lib\_name\_upper)
  target\_include\_directories(${target_name} ${scope} ${${lib\_name\_upper}\_IMPORT\_DIR}/include)
endfunction()

Manifest File

set(FOO\_IMPORT\_DIR /path/to/foo)
set(BAR\_IMPORT\_DIR /path/to/bar)

Usage

builddep\_find\_lib(foo)
builddep\_find\_lib(bar)

add_executable(helloworld
  helloworld.cpp
)

target\_link\_libraries(helloworld
  PRIVATE
    foo
    bar
)