Skip to content

Walkthrough of example dependency external project

Joe Maley edited this page Sep 11, 2020 · 3 revisions

Dependency EP Example

To see how TileDB's dependencies work, let's take the example of the Blosc dependency. During the superbuild, the FindBlosc_EP.cmake file gets loaded by TileDB-Superbuild.cmake with the command include(.../FindBlosc_EP.cmake). At the beginning of FindBlosc_EP.cmake, we see:

set(BLOSC_PATHS ${TILEDB_EP_INSTALL_PREFIX})

find_path(BLOSC_INCLUDE_DIR
  NAMES blosc.h
  PATHS ${BLOSC_PATHS}
  PATH_SUFFIXES include
  ${TILEDB_DEPS_NO_DEFAULT_PATH}
)

This sets the search path for the file blosc.h to include the external projects installation directory TILEDB_EP_INSTALL_PREFIX. This way, if Blosc is installed with an EP, it will be found by the find_path() command. The TILEDB_DEPS_NO_DEFAULT_PATH variable controls whether or not system paths are also searched. System paths are not searched if TileDB was configured with bootstrap --force-build-all-deps.

Next we see the following:

if (TILEDB_USE_STATIC_BLOSC)
  find_library(BLOSC_LIBRARIES
    NAMES
      libblosc${CMAKE_STATIC_LIBRARY_SUFFIX}
    PATHS ${BLOSC_PATHS}
    PATH_SUFFIXES lib
    ${TILEDB_DEPS_NO_DEFAULT_PATH}
  )
else()
  find_library(BLOSC_LIBRARIES
    NAMES
      blosc libblosc
    PATHS ${BLOSC_PATHS}
    PATH_SUFFIXES lib bin
    ${TILEDB_DEPS_NO_DEFAULT_PATH}
  )
endif()

The if statement checks the value of the boolean TILEDB_USE_STATIC_BLOSC, which (shown later in the example) is set during the superbuild when Blosc is not already found on the system, and thus when Blosc is added as an external project. We preferentially build our dependencies as static libraries. If the boolean is set, we search for the static Blosc library, otherwise we search for the dynamic library.

Next we see:

if (NOT BLOSC_FOUND)
  if (TILEDB_SUPERBUILD)
    message(STATUS "Adding BLOSC as an external project")
    ExternalProject_Add(ep_blosc
      ...
    )
    list(APPEND TILEDB_EXTERNAL_PROJECTS ep_blosc)
    list(APPEND FORWARD_EP_CMAKE_ARGS
      -DTILEDB_USE_STATIC_BLOSC=TRUE
    )
  endif()
endif()

The full EP is omitted for brevity. After attempting to locate blosc.h and libblosc.a, if they are not found and the superbuild is active, we add the external project ep_blosc. We also add ep_blosc to the list TILEDB_EXTERNAL_PROJECTS of external projects that are built, and we define the the TILEDB_USE_STATIC_BLOSC boolean seen earlier.

The FORWARD_EP_CMAKE_ARGS variable is used in TileDB-Superbuild.cmake with the ExternalProject_Add(tiledb) command that adds the non-superbuild TileDB project. So the FORWARD_EP_CMAKE_ARGS variable is just passed directly to the non-superbuild (the variable is "forwarded" to the non-superbuild):

# In file TileDB-Superbuild.cmake
ExternalProject_Add(tiledb
  SOURCE_DIR ${PROJECT_SOURCE_DIR}
  CMAKE_ARGS
    -DTILEDB_SUPERBUILD=OFF
    ${INHERITED_CMAKE_ARGS}
    ${FORWARD_EP_CMAKE_ARGS}
  INSTALL_COMMAND ""
  BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/tiledb
  DEPENDS ${TILEDB_EXTERNAL_PROJECTS}
)

Back to FindBlosc_EP.cmake, we see at the end of the file:

if (BLOSC_FOUND AND NOT TARGET Blosc::Blosc)
  add_library(Blosc::Blosc UNKNOWN IMPORTED)
  set_target_properties(Blosc::Blosc PROPERTIES
    IMPORTED_LOCATION "${BLOSC_LIBRARIES}"
    INTERFACE_INCLUDE_DIRECTORIES "${BLOSC_INCLUDE_DIR}"
  )
endif()

if (TILEDB_USE_STATIC_BLOSC AND TILEDB_INSTALL_STATIC_DEPS)
  install_target_libs(Blosc::Blosc)
endif()

Here we create the imported Blosc::Blosc target if Blosc was successfully found, either after building it as an EP, or pre-installed on the system. This imported target can then be used e.g. target_link_libraries(MyExe PRIVATE Blosc::Blosc). Finally we check if we should install the Blosc static library. When the user configures to build a static TileDB library, TILEDB_INSTALL_STATIC_DEPS will be set to true. If that is true, and we built the EP as a static library (TILEDB_USE_STATIC_BLOSC), we call install_target_libs() from TileDBCommon.cmake. This simply gets the imported location for the given Blosc::Blosc target and adds it to the TileDB installation manifest.