Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
danimtb opened this issue Mar 23, 2020 · 8 comments · Fixed by #6871
Closed

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

danimtb opened this issue Mar 23, 2020 · 8 comments · Fixed by #6871

Comments

@danimtb
Copy link
Member

danimtb commented Mar 23, 2020

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"]
@uilianries
Copy link
Member

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

@jgsogo
Copy link
Contributor

jgsogo commented Mar 24, 2020

"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.

@jgsogo
Copy link
Contributor

jgsogo commented Mar 24, 2020

I'll mention it here (not sure if it something for the generators too/only), but we should think about library loops #6530

@shelper
Copy link

shelper commented Aug 4, 2020

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

@memsharded
Copy link
Member

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.

@jgsogo
Copy link
Contributor

jgsogo commented Aug 4, 2020

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).

@shelper
Copy link

shelper commented Aug 4, 2020

@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"]

@jgsogo
Copy link
Contributor

jgsogo commented Aug 5, 2020

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants