3

I'm trying to include to make cmake-based project the library vlc-qt, as an external project from github repository.

The project uses recommended way :

FIND_PACKAGE(VLCQt REQUIRED COMPONENTS Widgets)

cmake performs this command at configuration stage so you see that library is not build on that moment.

what is a right way to avoid this?

amigo421
  • 2,429
  • 4
  • 26
  • 55
  • Include external project via [ExternalProject_Add](https://cmake.org/cmake/help/v3.7/module/ExternalProject.html), so it will be configured when your main project is being built. – Tsyvarev Jul 08 '17 at 21:52
  • I'm doing exactly this, but it tries to perform find-package at configuring moment – amigo421 Jul 08 '17 at 21:56
  • You **should** have required librariers when external project is *configured*. Alternative is to **manually** (that is, without `FindVLCQt.cmake` script) fill all *CACHE* variables. But this approach requires knowledge of the script internals (documentation is insufficient), and it may do not work for some packages. – Tsyvarev Jul 08 '17 at 22:05
  • did you mean - "you should have pre-built required external libraries when primary project is going to configure"? – amigo421 Jul 08 '17 at 22:22
  • No, I mean: when **external project** is configured, you should have all libraries required for it. – Tsyvarev Jul 08 '17 at 22:26

1 Answers1

3

Put your own project and the VLCQt project into external projects with ExternalProject_Add and create a top-level CMakeLists.txt file to build them one after another.

Your directory structure will look something like this:

ProjectRoot/
|-- CMakeLists.txt
|-- MyProject/
|   |-- sources/
|   `-- CMakeLists.txt
`-- modules/
    |-- MyProject.cmake
    `-- ExternalVLCQt.cmake

The ProjectRoot/modules/ExternalVLCQt.cmake may look like:

set(VLCQT_ROOT ${EXT_INSTALL_PATH}/vlcqt CACHE INTERNAL "")

ExternalProject_Add(vlcqt
    URL "http://url.of.source/release.0.1.tar.gz"
    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${VLCQT_ROOT}
    INSTALL_COMMAND make install
)

list(APPEND GLOBAL_THIRDPARTY_LIB_ARGS "-DVLCQT_ROOT:PATH=${VLCQT_ROOT}")

The ProjectRoot/modules/MyProject.cmake may look like:

ExternalProject_Add(my_project
    DEPENDS vlcqt
    SOURCE_DIR ${CMAKE_SOURCE_DIR}/MyProject
    CMAKE_ARGS
        ${GLOBAL_THIRDPARTY_LIB_ARGS}
        -DCMAKE_INSTALL_PREFIX=${EXT_INSTALL_PATH}/my_project
    BUILD_COMMAND make
)

Then finally the ProjectRoot/CMakeLists.txt should contain the following:

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(MyProject VERSION 0.1)

set(CMAKE_MODULE_PATH
    "${CMAKE_CURRENT_SOURCE_DIR}/modules"
    ${CMAKE_MODULE_PATH}
)

include(ExternalProject)

set_directory_properties(PROPERTIES EP_BASE ${CMAKE_BINARY_DIR}/ExtProjects)
get_directory_property(EXT_BASE_PATH EP_BASE)

set(EXT_INSTALL_PATH ${EXT_BASE_PATH}/Install)

include(ExternalVLCQt)
include(MyProject)

install(DIRECTORY ${EXT_INSTALL_PATH}/my_project DESTINATION .)

You can read more about this pattern here. By this pattern the ProjectRoot/MyProject/CMakeLists.txt will be configured at the build time of the top-level CMakeLists.txt after the vlcqt is built. Therefore the find_package will find the VLCQt package.

Note: In my example the VLCQT_ROOT will be received by the CMakeLists.txt of MyProject where the find_package command is used. This variable is a hint for the find_package command and for different packages this may vary. Every CMake modules used by the find_package has its own varaible requirements.

Akira
  • 4,385
  • 3
  • 24
  • 46