conan icon indicating copy to clipboard operation
conan copied to clipboard

[bug] libraries with components broken in editable mode

Open Sickeroni opened this issue 1 year ago • 3 comments

Describe the bug

System details

WSL with ubuntu.22.04 under Windows 11 g++-12 (through apt) cmake 3.29.2 (through snap) Conan 2.2.3

The Problem

Similar to https://github.com/conan-io/conan/issues/16162 but for projects using components (game engine example) in editable mode.

Situation

I use components, since some parts of the lib are compatible for some products (low level embedded without real os vs higher level embedded with linux) For developing editable mode is suggested.

Error

[cmake] CMake Error at out/build/linux_config/conan/build/Release/generators/cmakedeps_macros.cmake:67 (message):
[cmake]   Library 'testman' not found in package.  If 'testman' is a system library,
[cmake]   declare it with 'cpp_info.system_libs' property

This happens only in editable mode.

How to reproduce it

modify conanfile.py with something like that

def package_info(self):
        self.cpp_info.components["testman"].libs = ["testman"]

and your cmakefile needs somethink like

cmake_minimum_required(VERSION 3.28.0)

project(testmanproj
  VERSION 1.0.0
  LANGUAGES CXX
)
add_library(testman "${LIBRARY_SOURCE_DIR}/some/dirs/testman.cpp")
install(TARGETS testman)

more details

even through components dont work properly, without them it works!

self.cpp_info.libs = ["testman"]

This will work out without problems. It is the combination of editable with components in libraries.

Have you read the CONTRIBUTING guide?

  • [X] I've read the CONTRIBUTING guide

Sickeroni avatar Apr 26 '24 16:04 Sickeroni

I think this might be the same as discussed in https://github.com/conan-io/conan/issues/16162#issuecomment-2079815977: it is necessary to model the local development "editable" layout in the layout() method, also for components.

memsharded avatar Apr 26 '24 17:04 memsharded

Feedback

Yeah you're right. It took me some time but I found the problem.

What happened wrong

for some reason, conan is changing one specific line differently in my generated file: consumer/conan/build/Release/generators/testman-release-x86_64-data.cmake

set(testman_LIB_DIRS_RELEASE "${testman_PACKAGE_FOLDER_RELEASE}/lib") should be set(testman_LIB_DIRS_RELEASE "${testman_PACKAGE_FOLDER_RELEASE}/build/Release/.")

Personal opinion

I think this is a bit counterintuitive, but can be fixed in local conanfiles.py also there are more changes, but they are fine so far.

Question: not sure if the behaviour should be like this

if i have following code in package_info():

code result ${testman_LIB_DIRS_RELEASE}
self.cpp_info.libs = ["left"] works ${testman_PACKAGE_FOLDER_RELEASE}/build/Release/.
self.cpp_info.components["left"].libs = ["left"] fails ${testman_PACKAGE_FOLDER_RELEASE}/lib
self.cpp_info.libs = ["left"] self.cpp_info.components["right"].libs = ["right"] fails ${testman_PACKAGE_FOLDER_RELEASE}/lib
self.cpp_info.components["right"].libs = ["right"] self.cpp_info.libs = ["left"] fails ${testman_PACKAGE_FOLDER_RELEASE}/lib

Mixed list does not work either. Ordering is not changing the behaviour. As seen, only the first version is valid. I can't think of a situation where the libs directory should be defaultet to /lib if we already set libs.

It is fixable in a custom conanfile.py, but it feels wrong to be forced to for the mixed case.

Code to test

componentTest.zip To test it: for library in conan cache: (in corresponding directory)

conan build .
conan export-pkg .

for editable mode: (in corresponding directory)

conan add editable .

for the consumer/application

cmake --preset default .

info:

  • it fails at configuration step, no build step necessary
  • example is using the conan provider file
  • provider file was modified (extended) with "--build=editable" to always build editables
  • all test cases can be found in library/conanfily.py/package_info(); just comment/decomment the code
  • library builds 2 dummy libs called left and right

Sickeroni avatar Apr 29 '24 10:04 Sickeroni

Thanks for the detailed feedback and the reproducible code.

I think the issue in this case from what I see in your conanfile.py is that definition of cpp_info in the package_info() method is not enough for modelling the editable layout.

It is necessary to define it in the layout() method, in the self.cpp.xxx.components[] interfaces with xxx=source/build/package.

Please have a look to https://docs.conan.io/2/tutorial/developing_packages/package_layout.html, like:

def layout(self):

        ## define project folder structure

        self.folders.source = "."
        self.folders.build = os.path.join("build", str(self.settings.build_type))
        self.folders.generators = os.path.join(self.folders.build, "generators")

        ## cpp.package information is for consumers to find the package contents in the Conan cache

        self.cpp.package.libs = ["say"]
        self.cpp.package.includedirs = ["include"] # includedirs is already set to 'include' by
                                                   # default, but declared for completion
        self.cpp.package.libdirs = ["lib"]         # libdirs is already set to 'lib' by
                                                   # default, but declared for completion

        ## cpp.source and cpp.build information is specifically designed for editable packages:

        # this information is relative to the source folder that is '.'
        self.cpp.source.includedirs = ["include"] # maps to ./include

It would be like that, but also defining components in those interfaces. The package_info() alone is not enough to model the editable layouts, it must be in the layout() method.

memsharded avatar Apr 29 '24 16:04 memsharded

Hi @Sickeroni

Any further feedback here? Did the above explanation about components definition in layout() helped?

memsharded avatar Sep 04 '24 21:09 memsharded