Включить один и тот же заголовочный файл для разных библиотек - PullRequest
3 голосов
/ 20 октября 2019

У меня есть проект C ++ со следующей структурой:

CMakeLists.txt
code/
  libClient/
     CMakeLists.txt
     include/
        LibClient/
          lib_client.h
     src/
        lib_client.cpp
  libServer/
     CMakeLists.txt
     include/
        LibServer/
          lib_server.h
     src/
        lib_server.cpp
  libSDK/
     include/
       CMakeLists.txt
       LibSDK/
         lib.h

Мой корневой файл CMakeLists.txt имеет следующее содержимое:

cmake_minimum_required(VERSION 3.0)

project(libExample)


set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

add_subdirectory(code/libClient)
add_subdirectory(code/libServer)
add_subdirectory(code/libSDK)

Теперь я хотел бы собрать библиотекидля сервера и для клиента в виде .a файлов. lib_client.cpp включает в себя заголовочные файлы с

#include <LibClient/lib_client.h>

До этого мне все ясно, но заголовочный файл lib_client.h включает в себя lib.h, который находитсяна /code/libSDK/include/LibSDK/lib.h с

#ifndef LIBCLIENT_H
#define LIBCLIENT_H

#include <string>
#include <LibSDK/lib.h>

Чтобы сделать эту работу, я написал следующее содержимое в CMakelists.txt для ClientLib:

project(LIBCLIENT)

add_library(
    Client_lib STATIC
    src/lib_client.cpp
        include/LibClient/lib_client.h
    )

target_include_directories(egoClient_lib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_include_directories(egoClient_lib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../libSDK/include")   ###this line I think should be different.

Мой вопрос сейчас, возможно ли эточтобы избежать этой линии с жестко закодированным путем? Это lib.h также используется (включено) в других заголовочных файлах в этом проекте.

CMakelists.txt для этого lib.h до сих пор имеет только содержимое:

cmake_minimum_required(VERSION 3.0)

project(LIBSDK)

Я думал об использовании метода CMake find_package() и записи файла Find<package>.cmake,но я не вижу никаких преимуществ в этом, потому что внутри этого файла я также должен написать пути?

Заранее большое спасибо.

Ответы [ 2 ]

3 голосов
/ 20 октября 2019

Если Client_lib использует SDK_lib, вы должны использовать следующее в Client_lib CMakeLists.txt:

target_link_libraries(Client_lib SDK_lib)

Это сообщит CMake, что Client_lib использует SDK_lib. Это также автоматически сделает доступными пути PUBLIC или INTERFACE, настроенные для SDK_lib (с target_include_directories в SDK_lib CMakeLists.txt) для Client_lib.

0 голосов
/ 21 октября 2019

Во-первых, если ваши libClient и libServer зависят от libSDK, вы должны изменить свой CMake верхнего уровня, чтобы он выглядел так, как показано ниже. Кроме того, исходя из структуры вашего примера проекта, ваш add_subdirectory() для SDK должен быть code/libSDK/include:

cmake_minimum_required(VERSION 3.0)

project(libExample)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

add_subdirectory(code/libSDK/include)
add_subdirectory(code/libClient)
add_subdirectory(code/libServer)

Вы хотите быть уверены, что сначала соберете информацию о вашем SDK, до переход к каталогам клиента и сервера.


Во-вторых, если вы не собираетесь встраивать libSDK в библиотеку, а просто используете ее заголовки, вы можете просто определить новую переменную в вашем libSDK Файл CMake для указания расположения заголовков:

project(LIBSDK)

set(SDK_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "My SDK headers directory.")

Теперь с помощью кэшированной переменной из каталога libSDK мы можем использовать ее в других файлах CMake:

project(LIBCLIENT)

add_library(Client_lib STATIC
    src/lib_client.cpp
)

target_include_directories(Client_lib PUBLIC 
    "${CMAKE_CURRENT_SOURCE_DIR}/include"
    "${SDK_INCLUDE_DIRECTORY}"
)

РЕДАКТИРОВАТЬ : Как отмечено, во избежание использования переменных кэша вы также можете установить переменную include directoryies с помощью PARENT_SCOPE, чтобы сделать эту переменную доступной из вашегофайлы CMake клиента и сервера:

project(LIBSDK)

set(SDK_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
...