Keeblebrox
Keeblebrox

Reputation: 382

What would cause VS2010 to fail to include from header files, but not from implementation files?

I have a VS2010 project that's being generated by CMake, using the SFML library. The project is set up like so, with lib/SFML-2.0-rc/include added to the include directories:

/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

I am trying to use #include <SFML/Graphics.hpp> from assets.hpp, but I get the following error:

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

I also get that error when trying to include from engine.hpp. However, in engine.cpp I was already using that include line, and I could build and run the project successfully.

Visual Studio is able to auto-complete the SFML include paths, and in Configuration Properties > C/C++ > Additional Include Directories I can see all of the libraries are configured.

So my question is this: what could cause this error to only happen when including from a header file?

CMakeLists files

These are the CMake build files that generated the VS2010 solution.

project/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
)

Upvotes: 2

Views: 1696

Answers (2)

Keeblebrox
Keeblebrox

Reputation: 382

Long Answer

Through a chain of includes, main.cpp in the application project is indirectly including "engine/assets/asset.hpp* through engine/engine.hpp. Therefore, during the application project build asset.hpp was attempting to include an SFML library, and wasn't able to find it.

The reason engine.cpp (and other implementation files) are able to include SMFL headers is that their dependencies are linked during the library project build, which has the dependencies configured. Everything the implementation needs from the external libraries is included in the resulting Engine.lib file.

TL;DR

Put simply, the issue was that the solution was split into two projects: the engine library and the application executable. The former was configured to access the SFML library, but the latter was not.

Fix

The solution is to either include the external libraries to the application project configuration, or to be more careful about exposing library dependencies in header files.

Unfortunately I didn't post the necessary details to pinpoint the issue in the original question, so I added the CMakeLists.txt files' contents, which help reveal the problem.

Upvotes: 0

HonkyTonk
HonkyTonk

Reputation: 2039

The indicated directory structure dictates that you need to write

#include <SFML/include/Graphics.hpp>

This would explain the error.

Upvotes: 0

Related Questions