conan-io / conan

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

[question] Switching Between Debug and Release Install in Same Folder #3298

Open matthewdhunt opened 6 years ago

matthewdhunt commented 6 years ago

I am having trouble creating and installing a debug vs. release version of a package. In brief, whichever package I export last (conan export-pkg) is what is used when running conan install, regardless of whether debug or release is specified.

In detail --

I have created two packages for a 3rd party library set. The library sets are very large, so I have created a separate package for debug and release. The command line I have used to do this is:

conan export-pkg . <..Package Name..>/<..Version..>@matt.hunt/testing -s arch=x86 -s compiler="Visual Studio" -s compiler.version=15 -s build_type=Release (package name and version omitted for brevity).

When building for Debug, I simply change build_type to =Debug, and I update the files/folders in the package. (The library folder for this 3rd party package is split between Debug and Release, so the self.cpp_info.libdirs is different for Debug vs Release).

This seems to correctly create two packages with two different hashes. The contents of the packages under "...matt.hunt/Testing/Package" look correct. The manifests and conanfile.py entries in each folder are correct.

But, locally, if I try to install the Debug vs Release package, conan somehow only uses the conanfile.py from whatever was last exported (in "...matt.hunt/Testing/export"). The command line I am using to install is:

conan install . -s arch=x86 -s os=Windows -s compiler="Visual Studio" -s compiler.version=15 -s build_type=Debug

If I change build_type=Debug to build_type=Release, leaving the rest unchanged, it uses the conanfile.py found in the exports folder, and due to the different folder layout between debug and release, this fails. The resulting .props file has no library exports. If I manually swap the conanfile.py in the export folder, the error is resolved, although obviously that isn't supposed to be necessary.

Do I misunderstand how to create and install packages, or is there a bug?

Conan info: Metadata-Version: 1.1 Name: conan Version: 1.6.0 Summary: Conan C/C++ package manager Home-page: https://conan.io Author: JFrog LTD Author-email: luism@jfrog.com License: MIT Location: c:\python27\lib\site-packages Requires: PyJWT, requests, colorama, PyYAML, patch, fasteners, six, node-semver, distro, pylint, future, pygments, astroid, deprecation, bottle, pluginbase Classifiers: Development Status :: 5 - Production/Stable Intended Audience :: Developers Topic :: Software Development :: Build Tools License :: OSI Approved :: MIT License Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.6 Entry-points: [console_scripts] conan = conans.conan:run conan_build_info = conans.build_info.command:run conan_server = conans.conan_server:run

PC info: Windows 10 Python 2.7 (due to other tools required for development)

danimtb commented 6 years ago

If I understood your issue right, you are trying to export-pkg a library for release and debug settings.

As you described it and reading this part:

When building for Debug, I simply change build_type to =Debug, and I update the files/folders in the package. (The library folder for this 3rd party package is split between Debug and Release, so the self.cpp_info.libdirs is different for Debug vs Release).

You are modifying the recipe between Debug and Release and this is why you get the issue as the recipe is also exported in the conan export-pkg command.

To solve this, consider the conanfile as a general recipe to build any configuration needed without having to modify it every time. In your case, if self.cpp_info.libdirs need to be different, make them conditional to the build type:

def package_info():
    if self.settings.build_type == "Debug":
         self.cpp_info.libdirs = "libs/debug"  # this is just an example path
    else:
        self.cpp_info.libdirs = "libs/release"

You may also found this section of the documentation interesting for your purpose: https://docs.conan.io/en/latest/creating_packages/package_approaches.html

matthewdhunt commented 6 years ago

Thank you for the reply. I can change the recipe to have a N configs -> 1 recipe approach, and that does work. But, it isn't clear to me why this is necessary. If build_type is a setting, and changing the build type from debug to release produces a different package with different hash, isn't that valid 1 config -> 1 recipe approach? Why does conan use the last package created with export-pkg? On other PCs that had never created a new package and are just clients, no export-pkg would have been run, and presumably it would work properly?

danimtb commented 6 years ago

Conan model is thought to be one recipe for all configs unless you change the name of the lib with something like libname_debug/libname_release but actually I dont see the point on this as the user will have to indicate it manually and you would lose the key functionality of Conan: Download an use the correct package for your settings (Conan does this based on the Package ID).

I dont see much pain on using one recipe to target all the configs. That's what all Conan users would expect from a recipe unless indicated otherwise.

export-pkg is creating a package a moving files from user space to Conan cache, so it needs to capture the latest version of the recipe and export it with the files to have the right version of it.

A client user who wants to reuse the package will set their settings and Conan will retrieve the right configuration (debug/release) for him without the need of doing an export-pkg.