Designing CMaize’s PackageManager Component
This page describes the design of the classes comprising CMaize’s PackageManager component.
What is the PackageManager Component?
Developers use CMaize to write the build system for their project. As part of that build system they state the dependencies which the project needs. The PackageManager component is responsible for actually making those dependencies available to the user, be it by finding already built versions, or by building them.
Why do we Need a PackageManager Component?
The need for package manager integrations was one of the high-level
considerations behind CMaize (see package manager support). The
PackageManager component is how CMaize addresses this consideration. It should
be noted that traditional CMake can be seen as having an underlying package
manager manager with find_package
serving as the function for
locating existing packages and the FetchContent
and/or ExternalProject
modules actually building and installing the packages.
PackageManager Considerations
- finding packages
The design discussion in Overview of CMaize’s User API Design decided that the package manager would be responsible for finding packages that meet the specifications needed by the project. From the Designing CMaize’s CMaizeProject Component discussion it was decided that the specifications will be represented by
PackageSpecification
objects.
- building packages
The design discussion in Overview of CMaize’s User API Design decided that the package manager would be responsible for building packages that the project depends on.
- installing packages
Brought up in Designing CMaize’s C++ Target Classes, the package manager is responsible for installing the built packages.
- CMake package manager
Historically, C++ build system maintainers have relied on CMake’s package managing capabilities. To be backwards compatible, CMaize must support CMake’s package manager. See CMake’s Package Manager for more details on how traditional CMake is used as a package manager.
- extendable
Ultimately we want to leverage existing package managers outside the CMake ecosystem. The PackageManager component should be able to wrap other package managers aside from the CMake manager.
PackageManager Design
Fig. 7 provides an overview of the PackageManager
component. Considerations finding packages,
building packages, and installing packages are addressed by
the abstract base class’s API. More specifically, each derived class is
charged with implementing mechanisms for finding (find_installed
),
building (get_package
), and installing (install_package
) packages. The
mechanisms for using CMake’s built in package manager are implemented by the
CMakePackageManager
class (consideration CMake package manager).
Finally, we note that the extendable consideration is addressed by
deriving new classes from the PackageManager
base class.
Summary
- finding packages
Finding installed packages is done via the
find_installed
method. Each derived class must implement it appropriately.- building packages
Obtaining and/or building a package is done by calling the
get_package
method. Again, the derived class is responsible for implementing it in a manner which is appropriate for the backend.- installing packages
Installing the package is abstracted away by the
install_package
method. Classes derived fromPackageManager
must implement the method appropriately.- CMake package manager
The first package manager implemented in CMaize is the CMake package manager, which is represented by the
CMakePackageManager
class. TheCMakePackageManager
class leverages CMake’sfind_package
function and theFetchContent
module.- extendable
Extending the package manager component to additional package managers is straightforward and done by deriving new classes from
PackageManager
.