Current state:
When adding a new package to hunter, many times we need to fork that package to make modifications to it. These commonly are:
- The package does not use CMake
- The package use CMake, but forces certain build settings (ie. sets the CXX version to 11), when we want to leave these up to the toolchain
- The package has dependencies that need to be installed through hunter (ie.
hunter_add_package
in addition to the usual find_package
)
- The package doesn't have a CMake install step, which hunter uses to make the package available to consumers
- The package does not have a config file
Needing to make forks to add a package creates an extra overhead that would be nice to avoid. However, we probably can't get away with needing to make changes to packages to use them, because we rely on "CMake best practices" that upstream maintainers either haven't added or aren't interested in adding.
A more lightweight version:
Here is an example of a PR to a fork, to hunterize a package hunter-packages/Bento4#1, at version 1.5.1-628-e6ee435-p0
. Instead of making a fork, and pushing a commit to it, we could generate a patch, with git diff HEAD~1 HEAD > 1.5.1-628-e6ee435-p0.patch
. We could then take that patch, and when making the PR against hunter too add the package, like ruslo#1797, we would include the patch file. So we would have cmake/projects/bento4/1.5.1-628-e6ee435-p0.patch
. Then, our hunter config would look like this, using the upstream release tar:
hunter_add_version(
PACKAGE_NAME
bento4
VERSION
"1.5.1-628-e6ee435-p0"
URL
"https://github.com/hunter-packages/Bento4/archive/v1.5.1-628-e6ee435-p0.tar.gz"
SHA1
f296f38004cd6523eed12ce15cbbfaa8ce6fa050
LOCAL_PATCH
ON
)
After downloading the source, and before building it, we would have an extra step:
> download https://github.com/hunter-packages/Bento4/archive/v1.5.1-628-e6ee435-p0.tar.gz
> extract v1.5.1-628-e6ee435-p0.tar.gz
> cd v1.5.1-628-e6ee435-p0
> git apply ${HUNTER_ROOT}/cmake/projects/bento4/1.5.1-628-e6ee435-p0.patch, if it exists
To support packages with multiple versions in hunter, we could keep multiple patch files in the project folder in hunter.
Benefits:
- No more forks
- Hunterizing a package, and adding it to hunter happen in one PR - the plain-text patch can be reviewed when adding it
Disadvantages:
- We are then restricted to using released archive from upstream repos. Some repos don't release frequently, and the fork model has allowed us to use unreleased code in hunter
- The size of the hunter repo increases. The example patch I referenced was very simple, and still is 3.6KB. Having more complex patches, and patches per version for all packages in hunter would easily add 10s of megabytes to the repo
- Reviewing patches becomes visually harder, compared to a PR against the fork. For example, we need to read
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2f08b2f..c7170c3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# cmake -DCMAKE_BUILD_TYPE=Release ..
-cmake_minimum_required(VERSION 2.8)
-project(bento4)
+cmake_minimum_required(VERSION 3.0.2)
+project(bento4 LANGUAGES CXX VERSION "0.0.0")
Instead of
Likely we can support both the fork and patch models, and only use the patch models on small changes. However, small patches cover the overwhelming majority of package forks in hunter.
Summary:
- Tracking versioned patches in hunter for each package that requires "hunterization" to use means we can remove the need to fork packages, and can quickly make small modifications to a project's source in a single PR