2017-09-19 2 views
0

Mein Projekt enthält zwei Dienstprogramm Bibliothek. Ich suche nach dem besten Weg, CMake-Konfigurationen für die Bibliotheken zu schreiben.Include-Header mit einer Bibliothek in CMake

/my_project 
--> CMakeLists.txt 
--> main.cpp 
--> /utils 
     --> CMakeLists.txt 
     --> common.h 
     --> /base_c 
      --> CMakeLists.txt 
      --> base_c.c 
      --> base_c.h 
     --> /base_cpp 
      --> CMakeLists.txt 
      --> base_cpp.cpp 
      --> base_cpp.hpp 

Meine aktuellen CMake Dateien:

/my_project/CMakeLists.txt

cmake_minimum_requared(VERSION 3.8) 
project(my_project) 

add_subdirectory(utils) 

add_executable(main main.c) 
target_link_libraries(main utils base_c base_cpp) 

/my_project/utils/CMakeLists.txt

add_subdirectory(base_c) 
add_subdirectory(base_cpp) 

add_library(utils) 
target_sources(utils PUBLIC common.h) 

/my_project/utils/base_c /CmakeLists.txt

/my_project/utils/base_cpp/CMakeLists.txt

add_library(base_cpp base_cpp.cpp) 
target_sources(base_cpp PUBLIC base_cpp.hpp) 

find_library(BASEC base_c ../base_c) 
target_link_libraries(base_cpp BASEC) 

Das Problem ist, dass base_cpp finden sich nicht von base_c enthält. Wie sollte ich die Konfiguration reparieren?

Ich schaffte es mit target_include_directories(base_cpp PRIVATE ../base_c) arbeiten, aber das ist hässlich und sollte nicht notwendig sein, nach INTERFACE_INCLUDE_DIRECTORIES documentation.

+0

Wie Dokumentation für INTERFACE_INCLUDE_DIRECTORIES bedeutet, dass 'target_include_directories' benötigt wird, nicht wahr? Ich bin gespannt, wie Sie es geschafft haben, auch einzelne Bibliotheken ohne 'include_directories' oder' target_include_directories' zu kompilieren. – Tsyvarev

+0

@Tsyvarev Ich kann damit völlig falsch liegen. Können Sie erklären, wie ich 'INTERFACE_INCLUDE_DIRECTORIES' einer Bibliothek verwenden kann? – voddan

+0

Welches Build-System verwendest du nach CMake? Makefiles? Visual Studio-Projekte? Können Sie diese Dateien untersuchen, welche Verzeichnisse tatsächlich als include-Verzeichnisse übergeben werden? – Anedar

Antwort

0

Wie @Anedar erwähnt, diese Situation ein target_include_directories mit PUBLIC oder INTERFACE Optionen in der Bibliothek CMakeLists.txt muss lösen. Das füllt INTERFACE_INCLUDE_DIRECTORIES des Bibliotheksziels, das von target_link_libraries auf der konsumierenden Seite verwendet wird.

Meine Arbeitskonfiguration:

/my_project/CMakeLists.txt

cmake_minimum_requared(VERSION 3.8) 
project(my_project) 

add_subdirectory(utils) 

add_executable(main main.c) 
target_link_libraries(main utils base_c base_cpp) 

/my_project/utils/CMakeLists.txt

add_subdirectory(base_c) 
add_subdirectory(base_cpp) 

add_library(utils) 
target_sources(utils PUBLIC common.h) 
target_include_directories(utils INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 

/my_project/utils/base_c/CMakeLists.txt

add_library(base_c base_c.c) 
target_sources(base_c PUBLIC base_c.h) 
target_include_directories(base_c INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 

/my_project/utils/base_cpp/CMakeLists.txt

add_library(base_cpp base_cpp.cpp) 
target_sources(base_cpp PUBLIC base_cpp.hpp) 
target_include_directories(base_cpp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 

target_link_libraries(base_cpp base_c) 
1

target_include_directories) ist, was Sie suchen, aber nicht die PRIVATE Option.

Nach dem target_include_directories() documentation die PRIVATE Option für Verzeichnisse nur in diesem Ziel verwendet wird, ist INTERFACE für Verzeichnisse nur durch abhängige Ziele verwendet und PUBLIC ist für beide.

ich in schlage vor, mit /my_project/utils/base_c/CMakeLists.txt

target_include_directories(base_c INTERFACE ${CMAKE_CURRENT_LIST_DIR}) 

Auf diese Weise können „link“ das Verzeichnis, in dem Ziel enthalten gehört es und alle Ziele von ihm abhängig sind automatisch das Verzeichnis .

Zusätzlich möchten Sie möglicherweise Ihre öffentlichen Header in einen eigenen Unterordner /my_project/utils/base_c/base_c/ verschieben und sie dann als #include "base_c/base_c.h" einschließen. Dies führt eine Art "Namespace" zu den Headern ein und verhindert, dass Header mit demselben Namen aus verschiedenen Projekten mehrdeutig sind.

+0

Muss ich irgendetwas auf der konsumierenden Seite in 'base_cpp' tun? Zur Zeit 'find_library' gibt' BASEC-NOTFOUND' zurück – voddan

+1

Sie brauchen find_library nicht im selben Projekt. Verwenden Sie einfach 'target_link_libraries (base_cpp base_c)' – Anedar

+0

Ok, ich habe das getan, aber es kann die Header nicht auflösen. Vielleicht brauche ich 'target_include_directories (base_cpp )'? – voddan

Verwandte Themen