У меня есть проект C++, разделенный на несколько разных библиотек/исполняемых файлов в дереве исходного кода. Существует файл CMake верхнего уровня, который включает в себя несколько подкаталогов. Одна конечная библиотека B связывается с другой конечной библиотекой A. Однако, несмотря на то, что A публично добавил target_include_directories, в B я получаю сообщение об ошибке C1083 — не удается открыть включаемый файл.
ОС: Win10
Использование комплекта GCC 7.3.0:
-
Команда CMake
"C:\Program Files\CMake\bin\cmake.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:\Qt\Tools\mingw730_64\bin\gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:\Qt\Tools\mingw730_64\bin\g++.exe -Hd:/repos/cmake_sample_project -Bd:/repos/cmake_sample_project/build -G "MinGW Makefiles"
-
Сообщение об ошибке:
[build] D:\repos\cmake_sample_project\src\B\libB.h:5:10: fatal error: libA.h: No such file or directory
[build] #include "libA.h"
[build] ^~~~~~~~
[build] compilation terminated.
Использование комплекта Visual Studio Build Tools 2017 Release — amd64:
-
Команда CMake:
"C:\Program Files\CMake\bin\cmake.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:\repos\cmake_sample_project\src\b\libB.h(5): fatal error C1083: Datei (Include) kann nicht geöffnet werden: "libA.h": No such file or directory [D:\repos\cmake_sample_project\build\src\B\libB-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 $<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 $<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_project/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?
есть мысли? заранее спасибо.
Не могу воспроизвести. Все цели построены успешно. Ваш реальный код кажется другим.
Пожалуйста, предоставьте точное сообщение об ошибке.
Я обновил ответ и, еще раз взглянув на сообщения об ошибках, понял, что файл отсутствует в libB-obj, библиотеке объектов, используемой для создания статической библиотеки. libB-obj не был связан с libA, тогда очевидно, что он не найдет включаемые каталоги. Это было очень легко увидеть после вашего комментария и хорошего сна.