conan-io / conan

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

[bug] CMake generator not setting include path? #15718

Closed ehargitt closed 8 months ago

ehargitt commented 8 months ago

Environment details

Steps to reproduce

Sorry ahead of time for all the code snippets. Also, if I'm missing anything, please let me know.

I'm having trouble running conan create on my project. When it tries to build the test package, it fails with:

/home/ehargitt/projects/volconvert_frankenstein/test_package/src/example.cpp:3:10: fatal error: VolConvertApplication.h: No such file or directory
    3 | #include "VolConvertApplication.h"

I looked at the generated package to see if it was malformed, but it appeared ok:

(venv) ehargitt@CV-1045-HargittE:~/.conan2/p/b/volcof1a7a6929c166/p$ tree .
.
├── conaninfo.txt
├── conanmanifest.txt
├── include
│   ├── Algorithm.h
│   ├── ...
│   ├── VolConvertApplication.h
│   ├── ...
│   └── vol.h
└── lib
    └── libvolconvert.so -> libvolconvert.so.2024.02.21-preview

I noticed in test_package/build/gcc-9-x86_64-17-release/generators/volconvert-release-x86_64-data.cmake that the include dirs variable wasn't set, but not sure if this is relevant:

set(volconvert_INCLUDE_DIRS_RELEASE )
set(volconvert_RES_DIRS_RELEASE )
set(volconvert_DEFINITIONS_RELEASE )
set(volconvert_SHARED_LINK_FLAGS_RELEASE )
set(volconvert_EXE_LINK_FLAGS_RELEASE )
set(volconvert_OBJECTS_RELEASE )
set(volconvert_COMPILE_DEFINITIONS_RELEASE )
set(volconvert_COMPILE_OPTIONS_C_RELEASE )
set(volconvert_COMPILE_OPTIONS_CXX_RELEASE )
set(volconvert_LIB_DIRS_RELEASE "${volconvert_PACKAGE_FOLDER_RELEASE}/lib")
set(volconvert_BIN_DIRS_RELEASE "${volconvert_PACKAGE_FOLDER_RELEASE}/bin")
set(volconvert_LIBRARY_TYPE_RELEASE UNKNOWN)
set(volconvert_IS_HOST_WINDOWS_RELEASE 0)
set(volconvert_LIBS_RELEASE )
set(volconvert_SYSTEM_LIBS_RELEASE )
set(volconvert_FRAMEWORK_DIRS_RELEASE )
set(volconvert_FRAMEWORKS_RELEASE )
set(volconvert_BUILD_DIRS_RELEASE )
set(volconvert_NO_SONAME_MODE_RELEASE FALSE)

I have a project structure that looks like this:

.
├── CMakeLists.txt
├── CMakeUserPresets.json
├── README.md
├── blacklist.txt
├── build_local.sh
├── conanfile.py
├── out.txt
├── package_version
├── requirements.txt
├── scripts
│   └── install_py_dependencies.sh
├── src
│   ├── *.h
│   └── *.cpp
├── test_package
│   ├── CMakeLists.txt
│   ├── CMakeUserPresets.json
│   ├── build
│   │   └── ...
│   ├── conanfile.py
│   └── src
│       └── example.cpp
└── volconvert_frankenstein.code-workspace

This is my ./conanfile.py:

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.files import copy
from os.path import join

class volconvertRecipe(ConanFile):
    name = "volconvert"
    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 volconvert 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/*"

    requires = "qt/6.5.3"
    default_options = {
        "qt/*:qt5compat": True,
        "qt/*:with_dbus": True
    }

    def layout(self):
        cmake_layout(self)

    def generate(self):
        deps = CMakeDeps(self)
        deps.generate()
        tc = CMakeToolchain(self)
        tc.variables["CONAN_PACKAGE_VERSION"] = self.version
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()
        cmake.build(target="package")

    def package(self):
        # copying headers from source_folder
        copy(self, "*.h", join(self.source_folder, "src"), join(self.package_folder, "include"))
        # copying compiled .lib from build folder
        copy(self, "*.so", self.build_folder, join(self.package_folder, "lib"), keep_path=False)

    def package_info(self):
        self.cpp_info.libs = ["volconvert"]
        # conan sets libdirs = ["lib"] and includedirs = ["include"] by default
        self.cpp_info.libdirs = ["lib"]
        self.cpp_info.includedirs = ["include"]

This is my ./CMakeLists.txt:

cmake_minimum_required(VERSION 3.19)
project(volconvert CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")

# Find Qt6 package
find_package(Qt6 REQUIRED COMPONENTS
    Concurrent
    Core
    Core5Compat
    DBus
    Network
    Sql
    Xml
)
qt_standard_project_setup()

#---------------------------
# Build the library
#---------------------------

# Get all .cpp files in the src directory
file(GLOB SOURCES "src/*.cpp")
# Exclude specific file
list(FILTER SOURCES EXCLUDE REGEX "src/main.cpp")
# Add an executable target using all the .cpp files
qt_add_library(volconvert SHARED ${SOURCES})
# Set properties for the shared library, such as its version and visibility
set_target_properties(volconvert PROPERTIES
    VERSION ${CONAN_PACKAGE_VERSION}
)
# Link against Qt6 libraries
target_link_libraries(volconvert PRIVATE
    Qt6::Concurrent
    Qt6::Core
    Qt6::Core5Compat
    Qt6::DBus
    Qt6::Network
    Qt6::Sql
    Qt6::Xml
)
target_compile_definitions(volconvert PRIVATE VERSION=${CONAN_PACKAGE_VERSION})

#---------------------------
# Build the executable
#---------------------------

qt_add_executable(exe "src/main.cpp")
set_target_properties(exe PROPERTIES
    VERSION ${CONAN_PACKAGE_VERSION}
    OUTPUT_NAME volconvert
)
target_link_libraries(exe PRIVATE volconvert)

#---------------------------
# Set up the Debian package
#---------------------------

# Note: This install is not used for Conan, but for CPack
install(
    TARGETS exe volconvert
    DESTINATION "/"
    RUNTIME DESTINATION bin
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
)

# Create a CPack configuration file
set(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGE_NAME "volconvert")
set(CPACK_PACKAGE_VERSION ${CONAN_PACKAGE_VERSION})
set(CPACK_PACKAGE_CONTACT "Climavision")
set(CPACK_PACKAGE_DESCRIPTION "Tool to convert Pulse volumes to other file types, and apply correction chains.")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/Climavision/volconvert_frankenstein")
include(CPack)

And ./test_package/conanfile.py:

import os

from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout
from conan.tools.build import can_run

class volconvertTestConan(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeDeps", "CMakeToolchain"

    def requirements(self):
        self.requires(self.tested_reference_str)

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

    def layout(self):
        cmake_layout(self)

    def test(self):
        if can_run(self):
            cmd = os.path.join(self.cpp.build.bindir, "example")
            self.run(cmd, env="conanrun")

And the ./test_package/CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(PackageTest CXX)

find_package(volconvert CONFIG REQUIRED)

add_executable(example src/example.cpp)
target_link_libraries(example volconvert::volconvert)

And finally, the test_package/src/example.cpp:

// Copyright Climavision 2024. Do not steal, thx.

#include "VolConvertApplication.h"

int main(int argc, char **argv)
{
    using namespace Edge;
    VolConvertApplication::setInitDebug(false);
    VolConvertApplication::setInitSettings(false);
    VolConvertApplication::setInitEventLog(false);
}

Logs

Here is the output of conan create build_log.txt

Here is the entire test_package directory with the build folder created by the aforementioned conan create call. test_package.zip

ehargitt commented 8 months ago

Also, I realized that my profile is asking for gcc 9 but CMake is building with gcc 11. Probably not relevant, but something I need to fix.

ehargitt commented 8 months ago

Edit: Updated the build_log.txt attachment (forgot to save 🙃)

memsharded commented 8 months ago

Hi @ehargitt

Thanks for your report.

The issue seems to be in package_type = "application". Your package is not an application. It is a library that you are trying to link with. Please change it to package_type = "shared-library" (you should use package_type = "library" if you were using theoption = {"shared": ..`` to make it optionally static/shared).

Once that you define it as a library, the headers, libs and targets will be populated correctly, please try and let us know.

ehargitt commented 8 months ago

Ah, thank you for catching that! I split my app into a separate library, but forgot to change that line.

memsharded commented 8 months ago

Good, please keep us posted, if changing that line fixes it, let us know so we could close the issue if solved. Thanks!

ehargitt commented 8 months ago

Yeah, all good now. Thanks.