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

Be able to depend on the same package with different options #660

Closed
tru opened this issue Nov 15, 2016 · 15 comments
Closed

Be able to depend on the same package with different options #660

tru opened this issue Nov 15, 2016 · 15 comments

Comments

@tru
Copy link
Contributor

tru commented Nov 15, 2016

Currently we build some packages with different options since the build scripts are very similar. The problem is that we need depend on both versions of that package from our main application. This is currently not allowed with conan.

This means that we need to split the package and duplicate build logic over two different packages.

Possible solutions: be able to change the name of the package depending on options or make it so that you can depend on several packages with different options.

@lasote
Copy link
Contributor

lasote commented Nov 15, 2016

Should be great to have more information about the use case. If we are talking about real libraries it sound rare (link against the same library compiled differently has no much sense) but I assume the use case is for a tool or something like that?

@tru
Copy link
Contributor Author

tru commented Nov 15, 2016

Yeah the most common use case for this will most likely be in a tool yeah. Or a lib with a tool and a option is to just build the tool or the library.

@lasote
Copy link
Contributor

lasote commented Nov 15, 2016

But, it's related to #662? I need more info about what are you trying to do, maybe a little graph picture?
Thanks

@tru
Copy link
Contributor Author

tru commented Nov 15, 2016

In this case we have a toolchain that have several different targets (arm, x86, x86_64, ...) instead of having one separate conanfile per toolchain target we created one conanfile that takes a target option. But that means that there is no way to pull in x86 and x86_64 toolchain into the same package (which we need in some places). So now I need to separate these packages into different conanfiles just to give them different names and duplicate all that code to build the toolchain even if it's just the same build with different configure flags.

@lasote
Copy link
Contributor

lasote commented Nov 15, 2016

What about creating a new option "x86-x86_64"?

@tru
Copy link
Contributor Author

tru commented Nov 15, 2016

Definitely a possibility.

@lasote lasote closed this as completed Jun 29, 2018
@Viatorus
Copy link

I have a similar need for this.

I would like to export only the headers of package B for package A without build. And my main package should depend on package A and B - B should now be build.

We need this setup to calculate some sizes from the header without building them (embedded, static allocation).

@lasote
Copy link
Contributor

lasote commented Apr 25, 2019

Sorry, I don't get the idea.

@Viatorus
Copy link

We have an OS abstraction layer above freeRTOS, pthreads and WIN32.

In order to support static allocation (especially for embedded freeRTOS). We determine the needed implementation size without actually include the headers. We use CMakes CheckTypeSize.

Its a pimpl ideom without using heap allocation. Example:

class mutex {
public:
    void lock();
// ...
private:
    class impl;
    storage<impl, native::mutex_size> impl_;
};

native::mutex_size is the needed size for the implementation (freeRTOS, pthreads...) of impl. We don't want include the header directly because of the annoying defines and missing namespaces.

If we could have the same package with different options, we could automatic generate the sizes (without running build of the freeRTOS abstraction layer implementation) and later, compile and link the implementation.

@lasote
Copy link
Contributor

lasote commented Apr 29, 2019

I more or less get the idea now.
Maybe you can avoid specifying in the recipe the "name" and even the "version" field and specify it when exporting/creating the package: conan create . lib/1.0@user/channel, so you can use the same recipe with different names, one for calculating the sizes and a different one to build?

@Carsten87
Copy link

@lasote sorry to revive this old thread, but it seemed fitting...

I have a very similar question. We need to link against different libraries (components) from the same package with different options. To be specific we "require" boost and for some reason have to link against boost_thread in the dynamic variant (boost:shared=True) and some other boost components in the static variant (boost:shared=False). Is it somehow possible to set options per component? I could not find anything like it in the docs

@memsharded
Copy link
Member

Hi @Carsten87

This is challenging with Conan 1.X, depending on the same package with different options. You might depend on requires = "pkg(0.1" and build_requires = "pkg/0.1" (even different versions), and even try to define different options using -o:b and -o:h (options:build and options host), or using profile:build and profile:host to define different options for the two contexts.

This will become a first class feature in Conan 2.0, check #10112 for example, scheduled for next alpha2 (we are already in alpha1), and defining options for individual requirements, and allowing way more finer control over dependencies will be possible. Please keep an eye on 2.0 releases, and feedback very welcome over those features.

@Carsten87
Copy link

@memsharded thanks a lot for your super quick response. We were planning on having a look at Conan 2.0 anyway, one more reason to do so sooner 😉 In the meantime the build_requires approach seems hacky but workable. I will give it a try thanks again for your input!

@Carsten87
Copy link

@memsharded I don't seem to get the workaround running and I'm running out of ideas. As you can see in the output of conan install I set boost:shared differently for build and host context but nonetheless in both cases boost/1.76.0:847654ce15b50bdbb96596fa75b793c981bdc204 (which is shared=True) is used. But even if two different variants of boost were to be downloaded wouldn't the generated conanbuildinfo.cmake / FindBoost.cmake overwrite each other? I tried with cmake and cmake_find_package generators (see conanfile.py further down)

C:\conan_boost>conan install .. -pr:h ../prh.txt -pr:b ../prb.txt

Configuration (profile_host):
[settings]
arch=x86_64
build_type=Release
compiler=Visual Studio
compiler.runtime=MD
compiler.version=16
os=Windows
[options]
boost:shared=True
[build_requires]
[env]

Configuration (profile_build):
[settings]
arch=x86_64
build_type=Release
compiler=Visual Studio
compiler.runtime=MD
compiler.version=16
os=Windows
[options]
boost:shared=False
[build_requires]
[env]

conanfile.py: Installing package
Requirements
    boost/1.76.0 from 'conanio' - Cache
    bzip2/1.0.8 from 'conanio' - Cache
    zlib/1.2.11 from 'conanio' - Cache
Packages
    boost/1.76.0:847654ce15b50bdbb96596fa75b793c981bdc204 - Cache
    bzip2/1.0.8:d16a91eadaaf5829b928b12d2f836ff7680d3df5 - Cache
    zlib/1.2.11:3fb49604f9c2f729b85ba3115852006824e72cab - Cache
Build requirements
    boost/1.76.0 from 'conanio' - Cache
    bzip2/1.0.8 from 'conanio' - Cache
    zlib/1.2.11 from 'conanio' - Cache
Build requirements packages
    boost/1.76.0:847654ce15b50bdbb96596fa75b793c981bdc204 - Cache
    bzip2/1.0.8:d16a91eadaaf5829b928b12d2f836ff7680d3df5 - Cache
    zlib/1.2.11:3fb49604f9c2f729b85ba3115852006824e72cab - Cache

Installing (downloading, building) binaries...
bzip2/1.0.8: Already installed!
bzip2/1.0.8: Appending PATH environment variable: E:\dev\.conan\data\bzip2\1.0.8\_\_\package\d16a91eadaaf5829b928b12d2f836ff7680d3df5\bin
bzip2/1.0.8: Appending PATH environment variable: E:\dev\.conan\data\bzip2\1.0.8\_\_\package\d16a91eadaaf5829b928b12d2f836ff7680d3df5\bin
zlib/1.2.11: Already installed!
boost/1.76.0: Already installed!
boost/1.76.0: Disabled magic autolinking (smart and magic decisions)
boost/1.76.0: Disabled magic autolinking (smart and magic decisions)
conanfile.py: Applying build-requirement: boost/1.76.0
conanfile.py: Applying build-requirement: zlib/1.2.11
conanfile.py: Applying build-requirement: bzip2/1.0.8
conanfile.py: Generator cmake_find_package created FindBoost.cmake
conanfile.py: Generator cmake_find_package created FindZLIB.cmake
conanfile.py: Generator cmake_find_package created FindBZip2.cmake
conanfile.py: Generator txt created conanbuildinfo.txt
conanfile.py: Generator cmake created conanbuildinfo.cmake
conanfile.py: Aggregating env generators
conanfile.py: Generated conaninfo.txt
conanfile.py: Generated graphinfo
from conans import ConanFile, CMake

class ConanTest(ConanFile):
    settings = "os", "compiler", "arch", "build_type"
    generators = "cmake", "cmake_find_package"
    requires =["boost/1.76.0@"]
    build_requires =["boost/1.76.0@"]

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package_info(self):
        self.cpp_info.requires = ['boost::thread']
        self.cpp_info.build_requires = ['boost::random']

@memsharded
Copy link
Member

With the new generators like CMakeDeps, the "build" context do not generate by default xxx-config.cmake, and if you want it to generate, you can tell it explicitly, and you can even control the name of the file, so it can generate for example a xxx-build-config.cmake to differentiate it from the "host" one. Otherwise, things in build-requires are assumed to be executable tools, like cmake or other build system, and they are put in the PATH via environment, but not via cmake scripts.

So please, have a look to the new generators, it seems the previous ones don't have the features to be able to handle this case.

Also cpp_info.build_requires doesn't exist, only cpp_info.requires. And only for host context. build_requires are not and cannot be propagated to consumers, because they are only for build time exclusively.

It seems that your case might be also a bit too challenging for build_requires and will only be able to be implemented in Conan 2.0 (and also doing some extra work if you want to be able to find_package() too different flavors of boost, that will also require some extra work, not specifically because of Conan, with bare cmake you cannot do find_package() for 2 different things that are called the same, that is impossible in CMake.

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

No branches or pull requests

5 participants