Hi
The cmake_multi generator in conan only exposes release and debug builds. Cmake however usually has two other modes which are frequent: No build type specified (if cmake_multi is used on a unix environment), because it was e.g. forgotten. Also, there is RelWithDebInfo. If I just call e.g.
target_link_libraries(library CONAN_PKG::MyLib), building will fail on empty build type and RelWithDebInfo
Hi!
cmake_multi is only valid for multi-configuration environments, like Visual Studio.
It doesn't make sense to use it in Unix (Makefiles), which are single configuration and require a project re-generation (from cmake, it is just a cmake thing, not conan related). It is mainly recommended for end-consumers, for package creation I strongly suggest using the single configuration cmake generator.
Regarding the other modes, like RelWithDebInfo, conan hasn't modeled them yet. So far nobody requested them, and from my experience is not that frequent. But I am not against it, if there is some consensus from users, first it would be necessary to add them to settings.yml. Then probably to adapt the CMake helper and revise the cmake and cmake_multi generator logic, to add also XXX_RELWITHDEBINFO flags, targets...
We are developing an application and use conan for dependency management. Also, the application must be buildable under both windows and linux. Building packages is different, I agree.
Are you essentially telling me I should be using both cmake and cmake_multi in conanfile.txt and then use the cmake_multi for msvc builds and the others for linux builds? That would have quite some impact on the way a CMakeLists look as I always have to consider both options. This is why I'd have chosen cmake_multi for both windows and linux as this simplifies the overall setup.
Regarding different modes, it would be helpful to have some kind of helper functions for setting properties because we will have custom build modes as well. I'm not requesting RelWithDebInfo builds on conan, not at all. I'm requesting a way of telling conan to use a certain conan build type for a certain cmake build type. For example, here we have release builds with and without runtime contracts. For dependent libraries, this does not have any impact, thus I just want to use Release in case of a ReleaseWithContract build. for example. If I were to call conan_basic_setup (which would be ideal), a lot of cmake internal properties are touched, such as global include lists, target configurations, runtime selection etc. And duplicating all of this for my build modes is quite a maintenance burden
Actually I think I would recommend a different approach: use always the cmake single configuration in all systems. Have you read this thread: https://github.com/conan-io/conan/issues/330? Please do so, it has lots of interesting discussion.
My point is that changing configuration (single) in any system, is very simple: just go to the command line and do conan install -s build_type=XXXX (or maybe better, with profiles, to adequately set MXd flags for windows runtime).
This flow is simple, is fast, is robust and more tested than the cmake_multi. It will keep CMakeLists scripts simpler too. The cmake_multi the only advantage it has IMO is to allow users of Visual Studio to switch from Debug <=> Release configuration from the IDE. But I also thing that such switches are not so common, I switch branches (in git command line) one order of magnitude more than I switch build-type.
Regarding different modes, sorry I didn't understand at all. I would need to know a bit more about "runtime contracts", and why do you mean about telling conan to use a certain build_type, as that can be done with command line arguments. This might be a long thing to explain, if you want I might be available for chat (hangouts, slack, skype), maybe that is more productive (send me an email to info at conan dot io)
Thanks very much for your feedback!
I did know about #330 but I read it again to be sure and there are a few points in there I disagree with, so may be chat would indeed make sense.
Still, I'd like to point out a few things directly, so sorry if this turns out to be a bit of a longer reply. First, I'd like to challenge the point that going to the command line and executing this command is simple fast and robust. In our company, we have to switch build modes several times a day, so it is very common use case. Forgetting to do so will give you non-working builds. Also note, that by rerunning conan, you change the cmake file, changing the paths which are included in a project which in turn should trigger a full rebuild of the project (I didn't test this though). And this is really not an option for us. This is why I think using the simple cmake generator won't work for us.
Second, your point in #330 that not being able to use the FindXXX scripts with cmake_multi not being a problem is not correct in my opinion. Yes, for simple libraries one can just add the compile flags, the includes and the libs. But look at scripts like FindBoost or FindQt, or even FindCuda. All of them have in common, that apart from setting library variables, they also provide crucial functionality, like selecting a subset of libraries (FindBoost), the ability to invoke moc, uic and friends (FindQt) or compiling files using nvcc (FindCuda). Without those scripts, this functionality is not available and using such libraries becomes very painful and maintenance intensive. In the end, cmake has CMAKE_BUILD_TYPE for most generators and a at-build-time selection of the build type for Visual Studio (and may be others). This is how cmake is meant to be used and it is how pretty much all of the Find* scripts are written. Therefore I think it is absolutely crucial that conan finds a way of supporting this as well.
To that end, I also disagree with the statement in #330 that cmake failed to generalize for different build configurations for find scripts. Because I feel it is conan that is doing the strange thing and not cmake being not general enough.
In the end, since we will have an internal conan server anyway, I consider how hard it would be to actually mimic the "natural" thing, i.e. have a package that contains both release and debug builds. Yes, this would reduce flexibility in just picking something else for testing but it would give a consistent environment. Would conan support something like this?
About the build type -its much simpler than I made it to be, sorry. In the end, it boils down to a simple additional define. This define has no meaning for any dependency so it is a pure per-project thing. It is so common, that our current VS solution has a build mode for this. This way you can have incremental builds, and switch very quickly from one to the other. Now one could argue that under linux, you could provide a cmake-checkbox that sets this define but this again won't interact nicely with VS. So if we define an additional custom build type (lets call it ReleaseWithContracts), I'd just want to use the release builds in conan.
Thanks a lot for your in-depth and fast replies. This is highly appreciated
Thanks also for the detailed discussion, indeed very interesting.
Having packages that bundle both debug and release artifacts is quite simple, something like:
build_type from the settings listbuild() method call the build for both debug and releasepackage() method, take care of packaging everything to the right place, debug/release subfolders, or using _d suffixesThe weak point in the approach is the definition of information to be used by consumers, because you have modeled by conan: defines, libs, include_dirs, cpp_flags, etc, but those are not divided in debug/release types. You might be able to do filtering in the consumer side, like classifying all libs in debug/release according to the suffix. But if using FindXXX.cmake files, probably this is not an issue at all.
Please check if this approach would make sense for your use case.
Thinking more about this, this could actually be a way forward, even for conan. I mean, it is normal to have the same include directories for all build modes. I'm not sure about defines and cpp-flags, but if conan could detect debug and release builds and add them to the appropriate build mode in cmake (using the single cmake generator), one could achieve the best of both worlds...
Does that sound completely unreasonable to you?
No, not unreasonable.
But the "detection" doesn't seem the way to go, IMHO. As a design principle of conan, we try to have things as explicit as possible, so none or very little "magic" is required behind the scenes. What we have learned from experience is that such kind of magic tends to be problematic, even blocking users.
I guess the way to go would be to extend the cpp_info model with debug/release properties, the same way that CMake does. Packages building both debug/release artifacts can fill the appropiate fields. They will be available to generators, so even the cmake single conf generation could use the correct debug/release flags/defines and everything. Seems like the correct technical approach, but I am a bit concerned about the added complexity to the conan codebase, for the use case.
Please @lasote, feedback here.
Yes sure. I'd also prefer to actually specify: Here, this is a conan package, it contains debug and release builds and btw, these are the associated libs. Having autodetection magic behind the scenes is brittle.
I also just read the release announcement of qbs and they also added support for Visual Studio solutions, including the ability to switch the build type without rerunning qbs (https://blog.qt.io/blog/2017/01/31/qbs-1-7-released/ ). So its more than the cmake generator that would profit from this
Ok, will give it a chance, and propose something. Tentatively for 0.20, but not a high priority, might be delayed depending on the complexity.
I'm super in favor of this. As an added benefit, having the debug/release binaries packaged together means than conan packages would be a lot closer to the way libraries normally package themselves - Even for non-windows platforms, debug and release binaries are often distributed together since the header files are identical. IMO this means library developers will have an easier time porting their existing build systems to generate & use conan. I know I will!
Hi @yeswalrus Walter. While I slightly disagree (packages in linux have often separate dbg packages), I totally understand the use case, so the feature is almost ready, you can check the PR in: https://github.com/conan-io/conan/pull/975, and will most likely be on time for next 0.20 release, as planned.
If you can run from sources, you can run my branch and try it, that would help to test it and fine tune the interface. There are basically three things to package both debug and release:
build_type setting, just remove it.build() method as in: https://github.com/conan-io/conan/pull/975/files#diff-436665460bbb7332c38dd9ae7bff5dddR18cpp_info as in https://github.com/conan-io/conan/pull/975/files#diff-436665460bbb7332c38dd9ae7bff5dddR40. In the tests I am using a _d approach, but I think using different folders will work too.It is working with VS, but the tests are broken for linux, so test in Windows if possible.
@yeswalrus it was a dummy thing, already fixed and seems we have a green build on linux too: https://travis-ci.org/conan-io/conan/builds/203018841 if you want to try it.
Merged to develop, it will be released next 0.20
Released in 0.20, docs available: http://docs.conan.io/en/latest/packaging/package_info.html
Most helpful comment
No, not unreasonable.
But the "detection" doesn't seem the way to go, IMHO. As a design principle of conan, we try to have things as explicit as possible, so none or very little "magic" is required behind the scenes. What we have learned from experience is that such kind of magic tends to be problematic, even blocking users.
I guess the way to go would be to extend the
cpp_infomodel with debug/release properties, the same way that CMake does. Packages building both debug/release artifacts can fill the appropiate fields. They will be available to generators, so even thecmakesingle conf generation could use the correct debug/release flags/defines and everything. Seems like the correct technical approach, but I am a bit concerned about the added complexity to the conan codebase, for the use case.Please @lasote, feedback here.