conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
7.95k stars 951 forks source link

[question] conan build or cmake --build cannot find header files #16499

Closed kahlenberg closed 1 week ago

kahlenberg commented 1 week ago

What is your question?

Hi, I have a CMake project with imgui, I installed all necessary packages with conan install and I try to build the project with conan build, but I get errors that some header files cannot be found. When conan installs a package, does it install header files as well? Why cannot it find the header files?

conanfile.py:

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.build import check_max_cppstd, check_min_cppstd

class conan_projectRecipe(ConanFile):
    name = "conan_project"
    version = "1.0"
    package_type = "application"

    # Optional metadata
    license = "<Put the package license here>"
    author = "<Put your name here> <And your email here>"
    url = "<Package recipe repository url here, for issues about the package>"
    description = "<Description of conan_project package here>"
    topics = ("<Put some tag here>", "<here>", "<and here>")

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"

    # Sources are located in the same place as this recipe, copy them to the recipe
    exports_sources = "CMakeLists.txt", "src/*"

    def validate(self):
        check_min_cppstd(self, "17")
        check_max_cppstd(self, "20")

    def layout(self):
        cmake_layout(self)

    def generate(self):
        deps = CMakeDeps(self)
        deps.generate()
        tc = CMakeToolchain(self)
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def requirements(self):
        self.requires("opengl/system")
        self.requires("imgui/1.90.5", override=True)
        self.requires("implot/0.16")
        self.requires("libx264/cci.20220602")        
        self.requires("glfw/3.4")
        self.requires("glew/2.2.0")
        self.requires("freetype/2.13.2")
        self.requires("zlib/1.3.1")
        self.requires("nlohmann_json/3.11.3")

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)

project(conan_project CXX)

# Set the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Include the directory for header files
include_directories(${PROJECT_SOURCE_DIR}/include)

# Find all .cpp files in the src directory
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.cpp)

find_package(opengl_system)
find_package(imgui)
find_package(implot)
find_package(glfw3)
find_package(glew)
find_package(libx264)
find_package(freetype)
find_package(ZLIB)
find_package(nlohmann_json)

add_executable(${PROJECT_NAME} ${SRC_FILES})
target_link_libraries(${PROJECT_NAME} imgui::imgui 
                                      implot::implot
                                      libx264::libx264 
                                      glfw 
                                      GLEW::GLEW 
                                      opengl::opengl 
                                      Freetype::Freetype 
                                      ZLIB::ZLIB 
                                      nlohmann_json::nlohmann_json)

install(TARGETS conan_project DESTINATION "."
        RUNTIME DESTINATION bin
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        )

error:

C:\workspace\conan_project\include\GUI.h(5,10): error C1083: Cannot open include file: 'imgui_impl_glfw.h': No such file or directory [C:\workspace\conan_project\build\conan_project.vcxproj]
  (compiling source file '../../src/GUI.cpp')

Have you read the CONTRIBUTING guide?

AbrilRBS commented 1 week ago

Hi @kahlenberg thanks a lot for taking the time to report your issue, we appreciate it

I think this would not be a bug, but expected behaviour. The line self.requires("imgui/1.90.5", override=True) does not create a dependency on imgui by itself due to the override trait, it only means that if imgui is found in the dependency graph, its version should be overriden to that one, not that this package should dependend on that version by force.

You might be looking for the force=True trait, which does what you'd expect in this case: Create the direct dependency, and force it to be this version.

Note however that using these utilities to solve problems with the graph (if this is the case at all!) is not the recommended approach, and should only be used to temporally allow the builds to proceed while the versions get fixed in the problematic nodes in the graph :)

Hope this helps!

kahlenberg commented 1 week ago

Hi, Thank you for answer. I removed override=True and removed and created build directory, run conan install and conan build again, it is still the same error.

kahlenberg commented 1 week ago

Ok, I found it. Some imgui source files needs to be compiled with the project and source and header files need to be copied to project directory. conanfile.py:

...
    def generate(self):
        copy(self, "*glfw*", os.path.join(self.dependencies["imgui"].package_folder,
             "res", "bindings"), os.path.join(self.source_folder, "bindings"))
        copy(self, "*opengl3*", os.path.join(self.dependencies["imgui"].package_folder,
             "res", "bindings"), os.path.join(self.source_folder, "bindings"))
        deps = CMakeDeps(self)
        deps.generate()
        tc = CMakeToolchain(self)
        tc.generate()
...

CMakeLists.txt:

....
# Include the directory for header files
include_directories(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/bindings)

# Find all .cpp files in the src directory
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.cpp)
file(GLOB IMGUI_BINDINGS_FILES ${PROJECT_SOURCE_DIR}/bindings/*.cpp)
....

add_executable(${PROJECT_NAME} ${SRC_FILES} ${IMGUI_BINDINGS_FILES})
...
AbrilRBS commented 1 week ago

Checking the recipe, we do package the files you're looking for, but are not included in the include paths by default, they are in the res folder under the bindings subdirectory

Checking https://github.com/ocornut/imgui/wiki/Getting-Started#setting-up-dear-imgui--backends it seems like the recipe could directly add all backend files to the include paths, we'll take a look into it, see if it makes sense to make it less suprising

Edit: Oops just saw your last message, yes! That seems like the current approach to properly use the backends, we'll see if we can ease that pain in the future :)