cmakecmake-modules

CMake: Using add_subproject with a library using Include ends up in wrong relative path


Global CMakeLists.txt

This CMakeLists.txt compiles a few C++ files (Qt5/...) with MOC and is not 'special' in any regards.

The code in question is this:

add_subdirectory(third-party/libwebrtc)
include_directories(third-party/libwebrtc)
target_link_libraries(${PROJECT_NAME} libwebrtc)

libwebrtc CMakeLists.txt

cmake_minimum_required(VERSION 3.3)
project(libwebrtc)

# Allow the use of IN_LIST operand
cmake_policy(SET CMP0057 NEW)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
    ${CMAKE_SOURCE_DIR}/CMakeModules)

find_package(Git REQUIRED)

include(FindLibraries)
include(Version)
include(Options)
include(TargetOsAndCpu)
...

Full libwebrtc source -> https://github.com/cloudwebrtc/libwebrtc-build/blob/dev/CMakeLists.txt

Error on 'cmake ..'

If I run mkdir build; cd build; cmake .. I can see that CMake searches the include() in the top-level project and not in its subdirectory as I had expected it.

joachim@thinkpad-x1:[~/projects/client/build]: cmake ..
-- CMAKE_SYSTEM_INFO_FILE: 
-- CMAKE_SYSTEM_NAME:      
-- CMAKE_SYSTEM_PROCESSOR: 
-- CMAKE_SYSTEM:           
-- CMAKE_C_COMPILER:       /usr/bin/clang
-- CMAKE_CXX_COMPILER:     /usr/bin/clang++
CMake Error at sources/third-party/libwebrtc/CMakeLists.txt:13 (include):
  include could not find load file:

    FindLibraries


CMake Error at sources/third-party/libwebrtc/CMakeLists.txt:14 (include):
  include could not find load file:

    Version

Question (original)

Is there something I can do about that other than integrating the library into my base-project by copying the includes from the CMakeModules directory?

Thanks this has been answered below, still leaving this here.

Question about dependencies

The add_subdirectory call builds the libwebrtc correctly, but my include_directories call, the one from the top level CMakeLists.txt (not the libwebrtc library), wants to include files which are only available after the complete build:

include_directories(
  ${CMAKE_CURRENT_BINARY_DIR}/sources/third-party/libwebrtc/include/webrtc
  ${CMAKE_CURRENT_BINARY_DIR}/sources/third-party/libwebrtc/include/webrtc/third_party/libyuv/include/
  ${CMAKE_CURRENT_BINARY_DIR}/sources/third-party/libwebrtc/webrtc/src/third_party/abseil-cpp
)

How to make cmake depend on the complete build of the library and then build the main program onwards? Usually one uses add_custom_command(..) but since we are using add_subdirectory(..) we can't also use add_custom_command(..).

My hack to this problem was to rename the library to project(libwebrtcx) inside libwebrtc/CMakeLists.txt and also the ExternalProject_Add(libwebrtcx ...) and add a add_dependencies(${PROJECT_NAME} libwebrtcx) but can it be done without that hack?


Solution

  • Wrong CMAKE_SOURCE_DIR

    In my opinion the error seems to be within here

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
        ${CMAKE_SOURCE_DIR}/CMakeModules)
    

    CMAKE_SOURCE_DIR will be the path to your main source-Dir. Change this into

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
        ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)
    

    Use as external dependendecy

    Another idea is to build the project by its own and use it within your project as an external dependecy.

    find_package(LibWebRTC REQUIRED)
    include(${LIBWEBRTC_USE_FILE})
    
    target_link_libraries(my-app ${LIBWEBRTC_LIBRARIES})