Conan: [feature] Components: implement internal dependencies and link order resolution

Created on 23 Mar 2020  路  8Comments  路  Source: conan-io/conan

Coming from #5090

Use deps or require to indicate the list of components that a component depends on:

self.cpp_info.components["comp1"].deps = ["comp2", "comp3"]

or prepare to model components depending on other components of a different library:

self.cpp_info.components["liba"].requires = ["::comp2", "other_lib::comp3"]
queue feature

Most helpful comment

I'll mention it here (not sure if it something for the generators too/only), but we should think about library loops https://github.com/conan-io/conan/issues/6530

All 8 comments

"other_lib::comp3" is c++, why not just a simple dot? other_lib.comp3

"other_lib::comp3" is c++, why not just a simple dot? other_lib.comp3

We need a symbol forbidden as a package name, the dot is already used by approvaltests.cpp. Current regex: "^[a-zA-Z0-9_][a-zA-Z0-9_\+\.-]{%s,%s}$"

I think :: is a good one, it resembles the CMake targets notation.

I'll mention it here (not sure if it something for the generators too/only), but we should think about library loops https://github.com/conan-io/conan/issues/6530

I tested with the latest 1.27.1 conan, seems the internal order of the static libs is not automatically setted up, i still have to do something like:
self.cpp_info.libs = [c_that_needs_b, b_that_needs_a, a]

since this issue is closed, is there anything availabe? why i could not find the documentation for this? and the .components does not seem to be a member of cpp_info. or did i miss anything here?
@jgsogo

Hi @shelper

Not clear what you mean. The components feature will put the libs in order, if you declare them, something like:

self.info.components["CompA"]
self.info.components["CompA"].libs = ["libA"]
self.info.components["CompB"].requires = ["CompA"]
self.info.components["CompB"].libs = ["libB"]
self.info.components["CompC"].requires = ["CompB"]
self.info.components["CompC"].libs = ["libC"]

That will put the libs libA, libB and libC in the right order.

Hi, @shelper. Components are ordered according to the dependencies between them, but libraries listed in the cpp_info.libs attribute must be ordered by the user, I think there is nothing Conan should do to order these libraries (if the linker itself doesn't do this task, probably it is too much for a more generic tool like Conan).

@jgsogo for instance , i have a package that generate the following lib files: lib_a, lib_b, lib_c, lib_d, and i know that lib_b&c depend on lib_a, lib_d depend on lib_b, one way i can do to ensure the link order is to define:
self.cpp_info.libs=[lib_d, lib_c, lib_b, lib_a]

but i dont want to manually define this order, how should i use the components? if I understand correctly, i should do something like below?

# self.cpp_info.libs=[lib_d, lib_c, lib_b, lib_a] # if this line is removed, how conan knows the full list of libs of my package
self.cpp_info.components["b_c"].libs = ["lib_b", "lib_c"]
self.cpp_info.components["d"].libs = ["lib_d"]
self.cpp_info.components["b_c"].requires = ["lib_a"]
self.cpp_info.components["d"].requires = ["lib_b"]

Almost there, requires is a list of components (or dependencies), you would write:

# Definitions for component 'a'
self.cpp_info.components["a"].libs = ["lib_a"]

# Definitions for component 'b'
self.cpp_info.components["b"].libs = ["lib_b",]
self.cpp_info.components["b"].requires = ["a",]

# Definitions for component 'c'
self.cpp_info.components["c"].libs = ["lib_c",]
self.cpp_info.components["c"].requires = ["a",]

# Definitions for component 'd'
self.cpp_info.components["d"].libs = ["lib_d",]
self.cpp_info.components["d"].requires = ["b",]

Conan will generate the graph of dependencies and you can consume the required target that will link the libraries in the proper order:

find_package(your-pkg)

# Link with all the components (Conan manages the order)
target_link_library(library PUBLIC your-pkg::your-pkg)

# Link only with component 'b' (Conan transitively will add the required components)
target_link_library(library PUBLIC your-pkg::b)
Was this page helpful?
0 / 5 - 0 ratings