【问题标题】:CMake can't find file or directoryCMake 找不到文件或目录
【发布时间】:2021-12-19 19:12:52
【问题描述】:

我正在开发一个包含多个子目录的 CMake 项目,但我无法让它工作。我的工作目录如下:

├───main.cpp
├───CMakeLists.txt
├───build
├───States
    └───CMakeLists.txt
└───Elevator
    ├───CMakeLists.txt

构建项目后,我收到Elevator/Elevator.h: No such file or directory 作为错误。我的项目设置方式,电梯包含在状态中,显然 CMake 没有正确链接它们。

我的根 CMakeLists.txt:

cmake_minimum_required(VERSION 3.21.4)
project(Test)
set(CMAKE_CPP_STANDARD 11)
set(CMAKE_CPP_STANDARD_REQUIRED True)

add_subdirectory(Elevator)
add_subdirectory(States)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC Elevator States)

电梯里的那个:

set(elevator_source_files
  Elevator.cpp
  Elevator.h
  Set.cpp
  Set.h
)

add_library(Elevator ${elevator_source_files})

美国的 CMakeLists.txt:

set(state_source_files
  State.h
  State.cpp
  InitialState.h
  InitialState.cpp
  EmergencyState.cpp
  EmergencyState.h
  IdleState.h
  IdleState.cpp
  MaintenanceState.h
  MaintenanceState.cpp
  MovingState.h
  MovingState.cpp
  AllStates.h
  FSM.h
  FSM.cpp

)

add_library(States ${state_source_files})
target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..)
target_link_libraries(States PUBLIC Elevator)

我还是一个新手,所以任何帮助将不胜感激!值得注意的是,States.h 包含 Elevator 和 #include "Elevator/Elevator.h"

更新:项目现在构建并运行。我更新了描述中的 CMake 文件。

【问题讨论】:

  • 我的#include "Elevator/Elevator.h" 确实在 State.h 中,因为 State.h 接收到 Elevator 的实例作为参数。在 State 的 CMake 中更改为该行将不起作用。
  • target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR}) 更改为target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/..)
  • 有效!!!非常感谢!!!!

标签: c++ cmake


【解决方案1】:

要使 #include "Elevator/Elevator.h" 在 States 库中工作,您需要包含包含 Elevator 文件夹的文件夹。

解决这个问题的一种方法是改变

target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR})

target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR} 
${CMAKE_CURRENT_LIST_DIR}/..)

让 CMake 将 State 文件夹及其父文件夹添加到包含目录。

【讨论】:

  • 重新考虑target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) 可能就足够了,因为您通常不需要包含包含源文件的文件夹。
  • 虽然这可行,但干净的解决方案是将Elevator 库的公共标头移动到更深的子文件夹(例如Elevator/include/Elevator/),然后将Elevator/include 导出为公共包含来自Elevator 的目录。因此,即使您甚至没有链接所需的库,您最终也不会包含 everything...
  • 我通常将我的源代码和标题分隔到每个库文件夹内的单独文件夹(src 和 include)中。
  • 您的Elevator 项目可能是添加target_include_directories(Elevator PUBLIC ...) 的更好地方
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 2017-07-19
  • 2018-10-10
  • 2020-02-25
  • 2018-11-03
相关资源
最近更新 更多