conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.27k stars 981 forks source link

Question N configs -> 1 package #5341

Open mietzen opened 5 years ago

mietzen commented 5 years ago

To help us debug your issue please explain:

I'm not getting this example

$ git clone https://github.com/memsharded/hello_multi_config
$ cd hello_multi_config
$ conan create . user/channel -s build_type=Release
$ conan create . user/channel -s build_type=Debug --build=missing
class Pkg(ConanFile):
    # build_type has been omitted. It is not an input setting.
    settings = "os", "compiler", "arch"

    def configure(self):
        # it is also necessary to remove the VS runtime
        if self.settings.compiler == "Visual Studio":
            del self.settings.compiler.runtime

    def build(self):
        cmake = CMake(self)
        if cmake.is_multi_configuration:
            cmmd = 'cmake "%s" %s' % (self.source_folder, cmake.command_line)
            self.run(cmmd)
            self.run("cmake --build . --config Debug")
            self.run("cmake --build . --config Release")
        else:
            for config in ("Debug", "Release"):
                self.output.info("Building %s" % config)
                self.run('cmake "%s" %s -DCMAKE_BUILD_TYPE=%s'
                        % (self.source_folder, cmake.command_line, config))
                self.run("cmake --build .")
                shutil.rmtree("CMakeFiles")
                os.remove("CMakeCache.txt")

Why do I've to call conan create twice in Debug and Release ? Isn't the conan file taking care of build both types? And when i'm trying to apply this example on my own code the dependencies are missing for one build type. If I call -s build_type=Release first the Debug libs are missing and also the other way around. Do my dependencies also have to be multi config pkgs? Or am I missing something?

In the end I want all my libs to be available in release and debug in one pkg.

danimtb commented 5 years ago

Hi @mietzen and thanks for the question.

I think this part in our documentation is wrong using two create calls. Only one of them is needed as it is a unique package with both release and debug configs.

I think it came from the readme in https://github.com/memsharded/hello_multi_config, where you can see that multi-config packages can still be used with one config package (that is why you see the -s build_type flag, it is to affect other packages, not the multi-config one).

I will try to fix it in the docs and update that section.

mietzen commented 5 years ago

But am I right to assume that our build requirements have to be multi config pkgs as well?

danimtb commented 5 years ago

No, not really.

The setting values are just part of the input to Conan. If you define the build type in your profile, the recipes that care about it will pick the right value and the recipes that don't care will just pick the multi-config package.

So although specifying the build type for your multi-config package makes no sense for it, it does make sense for its non-multi-config dependencies

mietzen commented 5 years ago

Sorry I still don't get it.

My case:

"My Product" <- Multi-config build
 |-> Consumes Lib A [Build Type: Debug and Release]
 |-> Consumes Lib B [Build Type: ANY]

Calling: conan create . user/channel which will take the build type Release from my profile

conan file build step:

            cmake_release = CMake(self, build_type="Release")
            cmake_release.configure()
            cmake_release.build()

            cmake_debug = CMake(self, build_type="Debug")
            cmake_debug.configure()
            cmake_debug.build()

The release build will succeed but debug will fail since Lib A is only available as Release pkg.

EDIT: I just tested it again, Lib A is only downloaded once as release pkg. The debug pkg is missing, so conan is trying to link a release pkg in the debug build and fails.

danimtb commented 5 years ago

Sorry, now I understand it better.

Yes, you are right. I was thinking about the first level dependency (without other dependencies) and it works in that case. Then I was thinking about the conumption time (when binaries are already generated) and that also works.

However, I think that in the case of having a multi-config package, the dependencies will have to be multi-config too. The current model does not support depending on multiple packages of the same recipe...

I am going to add this issue to a project with similar cases I have found and tag it to look into multi config packages a little bit more

Siron777 commented 4 years ago

Hi,

I have a similar issue with a multi config - 1 package B depending on a multi config - 1 package A but at the generator level.

I have a multi config - 1 package library A which contain the release and debug version of the lib. I have a library B consuming A with the cmake_find_package_multi generators and which can be packaged also in as multi config - 1 package for a release and debug version.

When I do the create command for that library B, the cmake_find_package_multi generator will only install the cmake file of A with the build type specified in the -s build_type option or the profile instead of considering all build_type of A necessary for the multi config of B. At the build step, I will then have an error because either the release or either the debug version of the lib A will not be found by the compiler.

It looks like for a multi config - 1 package recipe, we should be able to specified in the requires list the build_type necessary.

Simon