[CMake] [cmake-developers] Using CMake as a package manager vs using a dedicated package management tool (like Conan)

Timothy Wrona tjwrona1992 at gmail.com
Tue Feb 19 10:37:17 EST 2019


Correction:

*I haven't tried this yet, but I am hoping it will work well* - Pull Put my
sub-projects (my own custom libraries) into their own independent git repos
and pull them into my main project using "FetchContent". Then when I run
"FetchContent" it will checkout the sub-projects and I will have all of the
source code available. I am hoping if I do this any changes I make to the
sub-projects can easily be committed and pushed back to their own
independent repositories.

On Tue, Feb 19, 2019 at 10:33 AM Timothy Wrona <tjwrona1992 at gmail.com>
wrote:

> Hi Craig,
>
> Thank you for the detailed description!
>
> To answer some of your questions:
>
>    - This project will not be incorporated into a Linux distribution,
>    however I would like to keep it cross platform and it should work on
>    Windows, Mac, and Linux.
>    - All of the pieces of the project that I am writing myself are using
>    CMake, but I do have some dependencies on external libs such as
>    "googletest" and "boost". Conan does seem to make using these external
>    dependencies very simple - especially since I am using MinGW to do my
>    compilation and "googletest" doesn't seem to compile out of the box on
>    MinGW without passing specific flags to the compiler. With Conan I get a
>    pre-compiled binary so it just works out of the box.
>    - At the current time, this project does not have many dependencies,
>    although it will likely grow quite large. I don't believe the external 3rd
>    party dependencies will need to update frequently, but all of the libraries
>    I am writing for the project will likely change quite a bit throughout
>    working on the project. I would also like to be able to compile these
>    libraries independently for reuse in other projects.
>    - I intend to support as many platforms/compilers as possible, I am
>    currently using Qt as my dev environment which allows me to
>    install/configure multiple compilers and try builds with each one - this
>    way I can at least do a build with both MinGW and msvc very quickly.
>    - I would like to support tools like sanitizers and code refactoring
>    tools at least within my own libraries (not necessarily with any of the 3rd
>    party libs)
>    - I would like past releases to be repeatable/rebuildable as much as
>    possible, although when the compiler is upgraded it is understandable that
>    past versions may have issues. I don't have much understanding of CI
>    systems at this point and it is something I have been trying to become more
>    familiar with. I'd like to avoid having multiple versions of the same
>    dependency, although I don't think having two versions of "googletest" for
>    two separate sub-projects that don't depend on each other would cause any
>    issues.
>       - I imagine Conan would make past releases more repeatable since
>       you can fetch binary packages instead of needing to rebuild from source and
>       package versions are always explicit.
>
> I am currently the only developer working on the project, but I would
> still like to find the most efficient method of managing packages for my
> particular situation since it will likely save me a lot of pain down the
> road if I get it right up-front. This project is in the situation where I
> have a set of different sub-projects (libraries) that all need to be able
> to be compiled independently for re-use, but I have a main project that
> will use them all. All of these projects have their own dependencies (some
> of them 3rd party, some of them written by me). The 3rd party libs will
> likely rarely change, but the ones written by me may change quite
> frequently.
>
> This is an approach I was thinking about taking:
>
>    - *So far I have tried this and it is working well* - Manage 3rd party
>    libs with Conan, since I don't need to see the source and it's quite
>    convenient to not need to recompile them this seems to work pretty well.
>    Using "FetchContent" on 3rd party libs and then attempting to compile them
>    yourself can sometimes be tricky (for example "googletest" requires special
>    compiler flags to be compiled with MinGW.) It also ensures that if two
>    projects ask for the same version of a dependency I get only one copy even
>    if the projects are built entirely independent of each other.
>    - *I haven't tried this yet, but I am hoping it will work well* - Pull
>    my sub-projects (my own custom libraries) into their own independent git
>    repos and pull them into my main project using "FetchContent". Then when I
>    run "FetchContent" it will checkout the sub-projects and I will have all of
>    the source code available. I am hoping if I do this any changes I make to
>    the sub-projects can easily be committed and pushed back to their own
>    independent repositories.
>    - The alternative to this would be to put my own sub-projects into
>       their own Conan packages and use Conan to get them from the main project.
>       But I am thinking since they will change frequently, "FetchContent" may be
>       a better fit for this scenario.
>       - Maybe when the sub-project libraries reach a mature and stable
>       release they should be packaged into Conan and fetched in the main project
>       from Conan at that point?
>
> Let me know what you think! :)
>
>
> On Tue, Feb 19, 2019 at 5:56 AM Craig Scott <craig.scott at crascit.com>
> wrote:
>
>>
>>
>> On Tue, Feb 19, 2019 at 12:46 PM Timothy Wrona <tjwrona1992 at gmail.com>
>> wrote:
>>
>>> I have been working on a new C++ project and I am trying to decide
>>> whether I should use CMake as my package management system or if I should
>>> use a dedicated package management tool such as Conan.
>>>
>>> For more information on Conan see: https://conan.io/
>>>
>>> I am trying to understand the main difference between using Conan to
>>> manage dependencies vs using CMakes "FetchContent" module. Are there any
>>> compelling reasons to prefer something like Conan?
>>>
>>
>> Excellent question, one that I think deserves a more detailed answer than
>> I can provide here, but I'll try to hit the main points as I see them.
>>
>> Personally, I think there is no "right answer" or "one size fits all"
>> when it comes to package management for a CMake project. What works well
>> for one situation, person or project may not be as convenient or suitable
>> for another. There are competing needs and views, some of which are
>> personal preferences, others are hard requirements from things like OS
>> distribution policies for packaging. Even just the maturity of a project
>> can have a big influence on how developers may prefer to handle its
>> dependencies and handle it as a dependency of other projects.
>>
>> The key thing for me is that the developer should ideally have choices
>> when it comes to this area. If a project hard-codes that its dependencies
>> must come from a particular provider (whether that be Conan, Hunter, vcpkg
>> or some other system), this might not be compatible with what the
>> developer's situation allows. You would need to weigh up whether it makes
>> sense to lock the developer into a particular package manager if they want
>> to use your project or not. An inappropriate choice here can mean lower
>> adoption of the project as some may reject it for consideration based on
>> this point alone.
>>
>> If instead a project relies only on find_package() to find its
>> dependencies, then it is up to the developer to ensure they are all
>> available. This could be done using whatever package manager the developer
>> finds convenient, or they could build the dependency projects from source
>> individually or they might set up a superbuild parent project that builds
>> the dependencies in the required order and makes dependees available to
>> dependers. This gives good flexibility at the cost of more responsibility
>> on the developer than perhaps some would want (again, it will be highly
>> situation-dependent).
>>
>> A drawback with find_package() is that it assumes you actually have a
>> packageable project. For a variety of reasons, this may not be the case.
>> Consider a large, complex project in its early stages and where multiple
>> teams are working on different subprojects which all get combined into some
>> larger whole. Each of the subprojects may need to be able to build on their
>> own with their own smaller subset of dependencies, but they also need to be
>> able to be incorporated into a larger build (think of different teams
>> working on core toolkits, rendering engines, different algorithm
>> strategies, multiple GUI applications, backend components, etc). No-one may
>> know yet how it should get packaged up and everyone might be focused on
>> just getting a minimal viable prototype up and running as a technical
>> demonstrator. For a case like that, neither find_package() nor a package
>> manager really fits the workflow. In this situation though, FetchContent is
>> a perfect fit, since it doesn't require any packaging to already be in
>> place, it needs no external tools other than CMake and it gives each
>> project precise control over its dependencies down to the individual commit
>> to bring in for each one.
>>
>> With the above in mind, perhaps the following few questions may be
>> helpful in clarifying what your constraints are and maybe steering you more
>> toward one way or the other:
>>
>>    - Will the project be incorporated into a Linux distribution at some
>>    point (not just be installed on Linux, but be part of the actual Linux
>>    distribution as provided by its own native package manager)? If so, I would
>>    expect this would pretty much eliminate using any package manager and
>>    instead require that you use find_package() to find all dependencies.
>>    - Are any of the dependencies of the project using a build system
>>    other than CMake? If so, they tend to take a bit more work to incorporate
>>    into a build via ExternalProject or FetchContent. If you can assume the
>>    developer provides those somehow, bringing them in by find_package() shifts
>>    responsibility for building them from the project to the developer (or
>>    whatever package manager they choose to use). This might be anywhere from
>>    entirely appropriate to entirely problematic depending on who your intended
>>    audience is.
>>    - How many dependencies does the project have and what is the
>>    maturity of each one? Will the project need to update any of those
>>    dependencies often (are they also being actively developed, do you need to
>>    follow recent work in them)? What will be the impact on developers working
>>    on the project when these dependencies need to be updated (how easy is it
>>    for them to update, what assumptions are you making about their development
>>    environment and tools)?
>>    - What breadth of platforms, compilers and CMake generators do you
>>    want to support? The bigger this set, the more it may drive you towards
>>    building dependencies from source rather than relying on having pre-built
>>    packages available to you.
>>    - Do you want developers to be able to use tools like sanitizers,
>>    perform code refactoring across projects or have source code visibility
>>    into dependencies within their IDE tools? FetchContent supports all of
>>    these requirements quite naturally, but doing so for the other methods it
>>    may be more difficult.
>>    - How will you manage repeatability of building past releases? Will
>>    you be able to build a year old release again if you update a build slave?
>>    In particular, what assumptions are you making about a CI system's build
>>    slaves and what dependencies they have installed (can you have multiple
>>    versions of any given dependency available at once, whether that be at a
>>    known path or via whatever package manager(s) you choose to use)?
>>
>>
>> On a side note, this is an area I'm increasingly thinking about these
>> days (I'm the author of the FetchContent module). I'm interested in hearing
>> peoples' views on dependency management and building an understanding of
>> what works for people and what doesn't. If you want to send feedback my
>> way, do feel free to get in touch.
>>
>> --
>> Craig Scott
>> Melbourne, Australia
>> https://crascit.com
>>
>> Get the hand-book for every CMake user: Professional CMake: A Practical
>> Guide <https://crascit.com/professional-cmake/>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190219/51aa95c2/attachment-0001.html>


More information about the CMake mailing list