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

和自甴很熟 提交于 2020-04-17 21:51:23

问题


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?


回答1:


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})



回答2:


So what I basically did was this:

libwebrtc project structure

  • renamed the folder to libwebrtcx
  • renamed the project

    project(libwebrtcx)
    
  • modified the CMAKE_MODULE_PATH

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
    -    ${CMAKE_SOURCE_DIR}/CMakeModules)
    +    ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)
    

libwebrtc CMakeLists.txt

replaced these all:

  • CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR and
  • CMAKE_BINARY_DIR with CMAKE_CURRENT_BINARY_DIR and with using

my project's CMakeLists.txt

add_dependencies(${PROJECT_NAME} libwebrtcx)
add_subdirectory(third-party/libwebrtcx)
include_directories(
  ${CMAKE_BINARY_DIR}/sources/third-party/libwebrtcx/include/webrtc
  ${CMAKE_BINARY_DIR}/sources/third-party/libwebrtcx/include/webrtc/third_party/libyuv/include/
  ${CMAKE_BINARY_DIR}/sources/third-party/libwebrtcx/webrtc/src/third_party/abseil-cpp
)

add_library(libwebrtc STATIC IMPORTED)
set_property(TARGET libwebrtc PROPERTY IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/sources/third-party/libwebrtcx/webrtc/src/out/Release/obj/libwebrtc.a")
target_link_libraries(${PROJECT_NAME} libwebrtc)

summary

With this I get the library libwebrtcx to build before it is actually used because of the add_dependencies call. But for the linker I needed the original 'libwebrtc' name, so I basically introduced another dependency called libwebrtc.

I wonder if that can be done in a better way, too?!



来源:https://stackoverflow.com/questions/61007492/cmake-using-add-subproject-with-a-library-using-include-ends-up-in-wrong-relati

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!