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

Handling loose object files #5159

Closed
ohanar opened this issue May 16, 2019 · 6 comments
Closed

Handling loose object files #5159

ohanar opened this issue May 16, 2019 · 6 comments

Comments

@ohanar
Copy link
Contributor

ohanar commented May 16, 2019

I have an interesting package that I'm not quite sure how to handle.

In essence it consists of an object file foo.o and static libraries libX.a and libY.a, and to use the package you need in your link line foo.o libX.a libY.a in that precise order. As far as I can tell there is no real way to specify this information to conan, here is what I've tried:

  • Using
    self.cpp_info.libs = ["X", "Y"]
    self.cpp_info.sharedlinkflags = self.cpp_info.exelinkflags = [os.path.join(self.package_folder, "foo.o")]
    causes issues with cmake as the linkflags are put after the libraries (I should note that if you change the implementation of the linkflags to use the new property INTERFACE_LINK_OPTIONS the order is reversed, see here for cmake's default link line). In any case, I don't think there should be any guarantees of whether the linkflags or libs come first in the link line.
  • Using
    linkflags = [os.path.join(self.package_folder, "foo.o"), *(os.path.join(self.package_folder, "lib", f"lib{lib}.a") for lib in ("X", "Y"))]
    self.cpp_info.sharedlinkflags = self.cpp_info.exelinkflags = linkflags
    causes multiple definition issues with cmake as both the exelinkflags and sharedlinkflags get added to the link line (it seems cmake was smart enough to remove the redundancy in the first case). Given that both the sharedlinkflags and exelinkflags get passed to everything under cmake, there should be a big red warning about this in the documentation.

For now I've hacked around this by just setting sharedlinkflags and not exelinkflags, but this seems potentially brittle with other generators (which I'm not as familiar with, mainly have just used them for various third party libraries). Fundamentally, I think there should be something like a commonlinkflags or just linkflags that are needed by both shared libraries and executables.

More specific to my problem, it seems like I'm looking for something along the lines of cmake's interface sources, so ideally I would have something like the following

self.cpp_info.libs = ["X", "Y"]
self.cpp_info.sources = ["foo.o"] # paths are relative to the package root
# Or maybe something a little more explicit like
self.cpp_info.interface_sources = ["foo.o"]

I don't know what generators could really use this info other than cmake, but it's not like everything is used by every generator (e.g. env_info is not exposed in the cmake generator).

@lasote lasote self-assigned this May 20, 2019
@lasote
Copy link
Contributor

lasote commented May 20, 2019

Hi, thanks for raising the issue.
Could I ask why that package needs that .o file and not another regular library?
About the common link flags I think you are right and makes sense.
And about the sources, we need to think about it, at first sight, it feels a bit weird to start managing sources instead of just libraries as a package manager purpose.

@ohanar
Copy link
Contributor Author

ohanar commented May 21, 2019

I'm not 100% certain, the library is a third-party proprietary library for which I only have binaries, however, I believe they do some pre-main shenanigans.

The only way to really force pre-main functions to be included into an executable or library is to link in an object file. Technically, you could archive the object, then link it in as static library with --whole-archive, but that is fundamentally a no-op, and is less portable (msvc only gain support for it in an update to VS2015). This is presumably the reason why the library authors didn't use that method.


Regarding sources, in the context of cmake, to make a.c an interface source of a library foo, is to say that to use the library foo in your own target bar you must include as a source file a.c for bar. It is analogous to making FOO_IMPORT a interface compile definition for foo, meaning that to consume the library foo in a library bar, you would need use the compile definition FOO_IMPORT when compiling bar.

In practice, I've only rarely seen interface sources in cmake, and they have exclusively been either header files (which don't actually need to be compiled) or object files (which are already compiled, and so just need to be linked in). They aren't used or intended to be used as a way to ship source code, but rather to handle weird edge-cases (like pre-main functions).

@rconde01
Copy link

I have run into this issue. Again, similarly using a commercial library which requires linking to object files. I had to settle and specify as sources in my cmake file.

@rconde01
Copy link

maybe a half fix could be allowing arbitrary info in cpp_info which you can then reference in cmake. It would require a manual step in your cmake still, but at least most of the info would still be handled in the package.

@rconde01
Copy link

I think maybe you can use user_info for that...gonna try.

@memsharded
Copy link
Member

cpp_info learned the cpp_info.objects some time ago, closing this as implemented.

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

No branches or pull requests

4 participants