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

[question] Correct way to set dependency options #7148

Closed
Tridacnid opened this issue Jun 4, 2020 · 5 comments
Closed

[question] Correct way to set dependency options #7148

Tridacnid opened this issue Jun 4, 2020 · 5 comments
Assignees

Comments

@Tridacnid
Copy link

Tridacnid commented Jun 4, 2020

$ conan --version
Conan version 1.22.2

My project consumes lib1 and lib2, both of which consume boost.

ERROR: boost/1.68.0: lib1 tried to change boost/1.68.0 option header_only to False
but it was already assigned to True by lib2

For both link performance as well as only "linking what you use", I try to keep the boost project's options aligned with what's needed using a combination of header_only and the without_X options.

I thought I had set up my default_options correctly, but I clearly have something messed up.
lib1 requires specific submodules of boost, and therefore does not want the header_only option enabled. The relevant portions of lib1's conanfile look something like:

required_boost_modules = [
    "iostreams",
    "program_options",
    "regex",
]

boost_modules = [
    'math', 'wave', 'container', 'contract', 'exception', 'graph', 'iostreams', 'locale', 'log',
    'program_options', 'random', 'regex', 'mpi', 'serialization',
    'coroutine', 'fiber', 'context', 'timer', 'thread', 'chrono', 'date_time',
    'atomic', 'filesystem', 'system', 'graph_parallel', 'python',
    'stacktrace', 'test', 'type_erasure'
]

class lib1Conanfile(Conanfile):
...
    requires = "boost/1.68.0"
    options = {
        "shared": [True, False],
        "fPIC": [True, False],
    }
    default_options = {
        "shared": False,
        "fPIC": True,
    }
    default_options.update({"boost:without_%s" % module: True for module in [boost_module for boost_module in boost_modules if boost_module not in required_boost_modules]})
...
    def configure(self):
       ...
        # Set our required boost options
        boost = self.options["boost"]
        boost.header_only = False
        for module in required_boost_modules:
            setattr(boost, "without_%s" % module, False)

lib2's conanfile.py is simple, the relevant options look something like:

class lib2Conanfile(Conanfile):
    requires = ..., "boost/1.68.0"
    options = {
        "fPIC": [True, False],
        "shared": [True, False],
    }
    default_options = {
        "fPIC": True,
        "shared": False,

        # options for consumed packages
        "boost:header_only": True
    }

If I had to guess, lib1's conanfile is at fault. What is the correct way to override options for a dependency when you 100% need them to be set a certain way?

@Tridacnid Tridacnid changed the title [question] SHORT DESCRIPTION [question] Correct way to set dependency options Jun 4, 2020
@Tridacnid
Copy link
Author

Tridacnid commented Jun 4, 2020

Maybe I should move the boost:header_only = False to the default_options of lib1? How do I enforce that strictly though?

@memsharded
Copy link
Member

Hi @Tridacnid

To solve the conflict by defining boost:header_only=False in the downstream consumer (in the package requiring both lib1 and lib2, to override lib2 definition. The downstream consumers always have higher precedence and override the upstream values. Is that your question?

@Tridacnid
Copy link
Author

Tridacnid commented Jun 4, 2020

Ok, just want to make sure I'm setting default and needed options correctly. Thanks!

@jgsogo jgsogo self-assigned this Jun 5, 2020
@jgsogo
Copy link
Contributor

jgsogo commented Jun 5, 2020

Hi! @Tridacnid , take into account that there will be only one boost package in your host graph and all the consumers will use that package. If there is a conflict in the graph (because of a diamond) you should override the options downstream activating all needed ones as said above... and then each consumer will choose which libraries to link* using the specific CMake targets (Boost::headers, Boost::filesystem,...)

*To be able to use these targets, #7108 has to be merged (next 1.26 release) and the boost recipe should declare these components (I'm sure the community will add components to the boost recipe as soon as it is released 🚀)

@Tridacnid
Copy link
Author

Makes sense, and the Conan errors are descriptive enough for me to quickly figure out how to resolve the problem.

That upcoming functionality looks nice, I'll look into switching to use that once it's available. Thanks again!

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

3 participants