【问题标题】:What would cause VS2010 to fail to include from header files, but not from implementation files?什么会导致 VS2010 无法从头文件中包含,但不能从实现文件中包含?
【发布时间】:2013-01-22 06:20:49
【问题描述】:

我有一个由 CMake 使用 SFML 库生成的 VS2010 项目。项目是这样设置的,将 lib/SFML-2.0-rc/include 添加到包含目录:

/lib
+   /SFML-2.0-rc
    +   /include
        +   /SFML
            +   Graphics.hpp
    +   /lib
/project
+   /src
    +   /engine
        +   /assets
            +   CMakeLists.txt
            +   asset.hpp
        +   CMakeLists.txt
        +   engine.hpp
        +   engine.cpp
    +   CMakeLists.txt
    +   main.cpp
+   CMakeLists.txt

我正在尝试使用 assets.hpp 中的#include <SFML/Graphics.hpp>,但出现以下错误:

fatal error C1083: Cannot open include file: 'SFML/Graphics.hpp': No such file or directory

我在尝试从 engine.hpp 中包含时也遇到了该错误。但是,在 engine.cpp 中,我已经在使用该包含行,并且可以成功构建和运行该项目。

Visual Studio 能够自动完成 SFML 包含路径,并且在 Configuration Properties > C/C++ > Additional Include Directories 我可以看到所有库都已配置。

所以我的问题是:只有在包含头文件时才会发生此错误?

CMakeLists 文件

这些是生成 VS2010 解决方案的 CMake 构建文件。

项目/CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (project)

set (project_SOURCE 
    ""
)
include_directories("src")
add_subdirectory (src)

add_executable (project ${project_SOURCE})
target_link_libraries (project Engine)

project/src/CMakeLists.txt

set (project_SOURCE
    ${project_SOURCE}
    "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
    PARENT_SCOPE
)
include_directories ("engine")
add_subdirectory (engine)

project/src/engine/CMakeLists.txt

set (HEADERS
    "${CMAKE_CURRENT_SOURCE_DIR}/engine.hpp"
)
set (SOURCE
    "${CMAKE_CURRENT_SOURCE_DIR}/engine.cpp"
)
include_directories("assets")
add_subdirectory(assets)
add_library(Engine 
    ${SOURCE} ${HEADERS}
)

set (LIBS_ROOT "" CACHE PATH "Root directory of external libs")
set (LIBS_SFML_FOLDER "SFML-2.0-rc" CACHE STRING "Name of the SFML external folder")
set (SFMLDIR "${LIBS_ROOT}/${LIBS_SFML_FOLDER}")

## SFML
if (NOT SFMLDIR)
    message (FATAL_ERROR "SFML directory hasn't been specified")
endif()

set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SFMLDIR}/cmake/Modules")
set (SFML_STATIC_LIBRARIES TRUE)
set (SFML_COMPONENTS system window graphics network audio main)
find_package (SFML 2 COMPONENTS ${SFML_COMPONENTS} REQUIRED)
if (SFML_FOUND)
    include_directories(${SFML_INCLUDE_DIR})
    target_link_libraries (Engine ${SFML_LIBRARIES})
endif ()

project/src/engine/assets/CMakeLists.txt

set (HEADERS
    ${HEADERS}
    "${CMAKE_CURRENT_SOURCE_DIR}/asset.hpp"
    PARENT_SCOPE
)

【问题讨论】:

  • 收到该错误时生成的构建报告包含什么?更具体地说,使用了哪些编译器标志?在 VS 中添加包含路径可能看起来不错,但我不得不重新启动该工具才能真正让它正确解析设置并解决类似问题。

标签: c++ visual-studio-2010 cmake sfml


【解决方案1】:

长答案

通过一个include链,应用项目中的main.cpp通过engine/engine.hpp间接包含“engine/assets/asset.hpp*”。因此,在应用程序项目构建期间 asset.hpp 试图包含一个 SFML 库,但无法找到它。

engine.cpp(和其他实现文件)能够包含 SMFL 标头的原因是它们的依赖关系在库项目构建期间被链接,该库项目已配置依赖关系。实现所需的外部库中的所有内容都包含在生成的 Engine.lib 文件中。

TL;DR

简单地说,问题在于解决方案分为两个项目:引擎库和应用程序可执行文件。前者被配置为访问 SFML 库,但后者没有。

修复

解决方案是将外部库包含到应用程序项目配置中,或者更加小心地在头文件中公开库依赖项。

很遗憾,我没有在原始问题中发布必要的详细信息来查明问题,因此我添加了 CMakeLists.txt 文件的内容,这有助于揭示问题。

【讨论】:

    【解决方案2】:

    指示的目录结构表明您需要编写

    #include <SFML/include/Graphics.hpp>
    

    这可以解释错误。

    【讨论】:

    • 项目将 lib/SFML/include 添加到包含目录。我应该让结构更清晰:在 lib/SFML/include 里面有一个 SFML 文件夹。我现在就编辑它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2013-10-11
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多