Почему не удаётся подключить заголовочный файл в Cmake?

Рейтинг: 1Ответов: 2Опубликовано: 30.07.2023

У меня есть такой каталог:

Структура папок
Серийный номер тома: C85A-2EBA
C:.
│   CMakeLists.txt
│
├───build
├───example
│       app.cpp
│
├───shape
│       CMakeLists.txt
│       printer.h
│       shape.cpp
│       shape.h
│
└───square
        CMakeLists.txt
        info.h
        square.cpp
        square.h

Я хочу скомпилировать две dll'ки (shapelib,squarelib) и пока не экспортировать их функции в клиентский app.cpp.

Корневой CMakeLists.txt выглядит так:

cmake_minimum_required(VERSION 3.25)

project(geometry LANGUAGES CXX)

if(MSVC)
    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()

add_library(shapelib SHARED)
add_library(squarelib SHARED)
target_include_directories(squarelib PRIVATE ${PROJECT_SOURCE_DIR})
add_subdirectory("square")
target_include_directories(shapelib PRIVATE ${PROJECT_SOURCE_DIR})
add_subdirectory("shape")

CMakeLists.txt в папке shape:

target_sources(shapelib
    PRIVATE shape.cpp
    PUBLIC FILE_SET HEADERS
    BASE_DIRS ${PROJECT_SOURCE_DIR}/shape # если не писать "/shape", то include в square.h придется писать полностью 
    FILES shape.h)

CMakeLists.txt в папке square:

target_sources(squarelib 
    PRIVATE square.cpp info.h
    PUBLIC FILE_SET HEADERS
    BASE_DIRS ${PROJECT_SOURCE_DIR}
    FILES square.h)

Заголовочный файл square.h:

//#include"shape/shape.h" // этот include работает как надо
#include"shape.h"
class Square: public Shape
{
    public:
            virtual std::string GetName() override;

            void WriteInfo();
};

Но при компиляции появляется ошибка: fatal error C1083: Cannot open include file: 'shape.h': No such file or directory

Однако если использовать закомментированный include и не делать BASE_DIRS ${PROJECT_SOURCE_DIR}/shape, то всё работает как надо. Но я хочу подключать заголовок укороченным способом (по имени), средствами cmake.

Почему появляется ошибка, если я явно указал путь до заголовочного файла с помощью FILE_SET HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR}/shape FILES shape.h

Ответы

▲ 1Принят

Попробуйте вместо FILE_SET HEADERS использовать PUBLIC или INTERFACE.

CMakeLists.txt в папке shape
target_sources(shapelib
    PRIVATE shape.cpp
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/shape.h)
CMakeLists.txt в папке square
target_sources(squarelib 
    PRIVATE square.cpp
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/square.h)
▲ 0

Если я верно интерпретирую прочитанное мною в интернете, то оказывается, что BASE_DIR должен указывать на ту же самую директорию, что и в target_include_directory, то есть ${PROJECT_SOURCE_DIR} без примочек