#c #cmake
Вопрос:
У меня есть проект на c , разделенный на несколько разных библиотек/исполняемых файлов в дереве исходных текстов. Существует файл CMake верхнего уровня, который включает в себя некоторые подкаталоги. Одна конечная библиотека B ссылается на другую конечную библиотеку A. Однако, несмотря на то, что A публично добавил каталоги target_include_, в B я получаю ошибку C1083 — не удается открыть включаемый файл.
ОС: Win10
Использование комплекта GCC 7.3.0:
- Команда CMake
"C:Program FilesCMakebincmake.EXE" --no-warn-unused-cli -DMOCK_SIMCONNECT:BOOL=TRUE "-DP3D_SDK_ROOT:STRING=C:/Program Files/Lockheed Martin/Prepar3D v4 SDK 4.5.14.34698" -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=C:QtToolsmingw730_64bingcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:QtToolsmingw730_64bing .exe -Hd:/repos/cmake_sample_project -Bd:/repos/cmake_sample_project/build -G "MinGW Makefiles"
- сообщение об ошибке:
[build] D:reposcmake_sample_projectsrcBlibB.h:5:10: fatal error: libA.h: No such file or directory
[build] #include "libA.h"
[build] ^~~~~~~~
[build] compilation terminated.
Использование набора средств сборки Visual Studio 2017 выпуска — amd64:
- Команда CMake:
"C:Program FilesCMakebincmake.EXE" --no-warn-unused-cli -DMOCK_SIMCONNECT:BOOL=TRUE "-DP3D_SDK_ROOT:STRING=C:/Program Files/Lockheed Martin/Prepar3D v4 SDK 4.5.14.34698" -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -Hd:/repos/cmake_sample_project -Bd:/repos/cmake_sample_project/build -G "Visual Studio 15 2017" -T host=x64 -A x64
- сообщение об ошибке:
d:reposcmake_sample_projectsrcblibB.h(5): fatal error C1083: Datei (Include) kann nicht geöffnet werden: "libA.h": No such file or directory [D:reposcmake_sample_projectbuildsrcBlibB-obj.vcxproj]
sample_cmake_project
| CMakeLists.txt
|
---src
| | CMakeLists.txt
| |
| ---A
| | | CMakeLists.txt
| | | libA.cpp
| | |
| | ---public
| | libA.h
| |
| ---B
| CMakeLists.txt
| libB.cpp
| libB.h
|
---tests
CMakeLists.txt
sample_cmake_project/CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(sample_project LANGUAGES CXX)
add_subdirectory(src)
enable_testing()
add_subdirectory(tests)
sample_cmake_project/src/CMakeLists.txt
add_subdirectory(A)
add_subdirectory(B)
sample_cmake_project/src/A/CMakeLists.txt
add_library(libA-obj OBJECT "") target_sources(libA-obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/libA.cpp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/public/libA.h # <-- header is added as public source. ) add_library(libA STATIC
lt;TARGET_OBJECTS:libA-obj>)
target_include_directories(libA PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/public) # <-- public dir is added to the target's PUBLIC include directories.
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/public)
sample_cmake_project/src/B/CMakeLists.txt:add_library(libB-obj OBJECT "") target_sources(libB-obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/libB.cpp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libB.h ) add_library(libB STATIC
lt;TARGET_OBJECTS:libA-obj>)
target_link_libraries(libB PRIVATE libA)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
sample_cmake_project/src/A/public/libA.h:#ifndef __LIBA_H #define __LIBA_H #include <iostream> class A { public: A() { std::cout << "hello" << std::endl; }; ~A() { std::cout << "bye bye" << std::endl; }; void saySomething(); }; #endif
sample_cmake_project/src/A/libA.cpp:
#include "libA.h" void A::saySomething() { std::cout << "something..." << std::endl; }
sample_cmake_проект/src/B/libB.h:
#ifndef __LIB_B #define __LIB_B #include <iostream> #include "libA.h" class B { public: B(); ~B(); void saySomething(); private: A _a; }; #endif
sample_cmake_project/src/B/libB.cpp:
#include "libB.h" B::B() : _a(A()) { std::cout << "Hello from lib B" << std::endl; _a.saySomething(); }
Я чувствую, что мне может не хватать чего-то фундаментального, но я думал, что, добавив sample_cmake_project/A/public в каталоги включения цели libA, libA.заголовок h должен быть доступен для библиотек, которые ссылаются на libA, например libB?
какие-нибудь вопросы? заранее спасибо.
Комментарии:
1. Не может размножаться. Все цели построены успешно. Ваш реальный код, кажется, отличается.
2. Пожалуйста, укажите точное сообщение об ошибке .
3. Я обновил ответ и, еще раз взглянув на сообщения об ошибках, я понял, что файл отсутствует в libB-obj, библиотеке объектов, используемой для создания статической библиотеки. libB-obj не был связан с libA, тогда очевидно, что он не нашел бы включенные каталоги. Это было очень легко увидеть после вашего комментария и хорошего ночного сна.
Ответ №1:
Это было тривиально и вроде как очевидно, но я не обратил на это внимания. Сообщения об ошибках относятся к libB-obj, библиотеке объектов, используемой для создания статической библиотеки libB. libB-obj не был связан с libA, поэтому общедоступные каталоги включения из libA были недоступны для libB-obj.
add_library(libB-obj OBJECT "")
target_sources(libB-obj
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/libB.cpp
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/libB.h
)
add_library(libB STATIC
lt;TARGET_OBJECTS:libA-obj>)
target_link_libraries(libB-obj PRIVATE libA) # --> link libB-obj instead of static library libB!
include_directories(${CMAKE_CURRENT_SOURCE_DIR})