2025-08-29 00:18:02 +02:00
# CPM
CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden.
Global Options:
- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing
* If this is `OFF` , required system dependencies will be searched via `find_package` , although certain externals use CPM regardless.
- `CPMUTIL_FORCE_SYSTEM` (default `OFF` ): Require all CPM dependencies to use system packages. NOT RECOMMENDED!
* Many packages, e.g. mcl, sirit, xbyak, discord-rpc, are not generally available as a system package.
* You may optionally override these (see CPMUtil section)
- `CPMUTIL_FORCE_BUNDLED` (default `ON` on MSVC and Android, `OFF` elsewhere): Require all CPM dependencies to use bundled packages.
## CPMUtil
CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful utility functions to make dependency management a piece of cake.
### AddPackage
`AddPackage` is the core of the CPMUtil wrapper, and is generally the lowest level you will need to go when dealing with dependencies.
**Identification/Fetching **
- `NAME` (required): The package name (must be the same as the `find_package` name if applicable)
- `VERSION` : The minimum version of this package that can be used on the system
2025-09-08 19:21:38 +02:00
- `GIT_VERSION` : The "version" found within git
2025-08-29 00:18:02 +02:00
- `URL` : The URL to fetch.
- `REPO` : The GitHub repo to use (`owner/repo` ).
* Only GitHub is supported for now, though other platforms will see support at some point
- `TAG` : The tag to fetch, if applicable.
- `ARTIFACT` : The name of the artifact, if applicable.
- `SHA` : Commit sha to fetch, if applicable.
- `BRANCH` : Branch to fetch, if applicable.
The following configurations are supported, in descending order of precedence:
- `URL` : Bare URL download, useful for custom artifacts
* If this is set, `GIT_URL` or `REPO` should be set to allow the dependency viewer to link to the project's Git repository.
* If this is NOT set, `REPO` must be defined.
- `REPO + TAG + ARTIFACT` : GitHub release artifact
* The final download URL will be `https://github.com/${REPO}/releases/download/${TAG}/${ARTIFACT}`
* Useful for prebuilt libraries and prefetched archives
- `REPO + TAG` : GitHub tag archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/tags/${TAG}.tar.gz`
* Useful for pinning to a specific tag, better for build identification
- `REPO + SHA` : GitHub commit archive
* The final download URL will be `https://github.com/${REPO}/archive/${SHA}.zip`
* Useful for pinning to a specific commit
- `REPO + BRANCH` : GitHub branch archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/${BRANCH}.zip`
* Generally not recommended unless the branch is frozen
- `REPO` : GitHub master archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/master.zip`
* Generally not recommended unless the project is dead
**Hashing **
Hashing is used for verifying downloads. It's highly recommended to use these.
- `HASH_ALGO` (default `SHA512` ): Hash algorithm to use
Hashing strategies, descending order of precedence:
- `HASH` : Bare hash verification, useful for static downloads e.g. commit archives
- `HASH_SUFFIX` : Download the hash as `${DOWNLOAD_URL}.${HASH_SUFFIX}`
* The downloaded hash * must * match the hash algorithm and contain nothing but the hash; no filenames or extra content.
- `HASH_URL` : Download the hash from a separate URL
**Additional Options **
- `KEY` : Custom cache key to use (stored as `.cache/cpm/${packagename_lower}/${key}` )
* Default is based on, in descending order of precedence:
- First 4 characters of the sha
2025-09-08 19:21:38 +02:00
- `GIT_VERSION`
2025-08-29 00:18:02 +02:00
- Tag
2025-09-08 19:21:38 +02:00
- `VERSION`
2025-08-29 00:18:02 +02:00
- Otherwise, CPM defaults will be used. This is not recommended as it doesn't produce reproducible caches
- `DOWNLOAD_ONLY` : Whether or not to configure the downloaded package via CMake
* Useful to turn `OFF` if the project doesn't use CMake
- `SOURCE_SUBDIR` : Subdirectory of the project containing a CMakeLists.txt file
- `FIND_PACKAGE_ARGUMENTS` : Arguments to pass to the `find_package` call
- `BUNDLED_PACKAGE` : Set to `ON` to force the usage of a bundled package
- `OPTIONS` : Options to pass to the configuration of the package
- `PATCHES` : Patches to apply to the package, stored in `.patch/${packagename_lower}/0001-patch-name.patch` and so on
- Other arguments can be passed to CPM as well
**Extra Variables **
For each added package, users may additionally force usage of the system/bundled package.
- `${package}_FORCE_SYSTEM` : Require the package to be installed on the system
- `${package}_FORCE_BUNDLED` : Force the package to be fetched and use the bundled version
**Bundled/System Switching **
Descending order of precedence:
- If `${package}_FORCE_SYSTEM` is true, requires the package to be on the system
- If `${package}_FORCE_BUNDLED` is true, forcefully uses the bundled package
- If `CPMUTIL_FORCE_SYSTEM` is true, requires the package to be on the system
- If `CPMUTIL_FORCE_BUNDLED` is true, forcefully uses the bundled package
- If the `BUNDLED_PACKAGE` argument is true, forcefully uses the bundled package
- Otherwise, CPM will search for the package first, and if not found, will use the bundled package
**Identification **
All dependencies must be identifiable in some way for usage in the dependency viewer. Lists are provided in descending order of precedence.
URLs:
- `GIT_URL`
2025-10-04 09:27:13 +02:00
- `REPO` as a Git repository
* You may optionally specify `GIT_HOST` to use a custom host, e.g. `GIT_HOST git.crueter.xyz` . Note that the git host MUST be GitHub-like in its artifact/archive downloads, e.g. Forgejo
* If `GIT_HOST` is unspecified, defaults to `github.com`
2025-08-29 00:18:02 +02:00
- `URL`
Versions (bundled):
- `SHA`
- `GIT_VERSION`
- `VERSION`
- `TAG`
- "unknown"
If the package is a system package, AddPackage will attempt to determine the package version and append ` (system)` to the identifier. Otherwise, it will be marked as `unknown (system)`
### AddCIPackage
Adds a package that follows crueter's CI repository spec.
- `VERSION` (required): The version to get (the tag will be `v${VERSION}` )
- `NAME` (required): Name used within the artifacts
- `REPO` (required): CI repository, e.g. `crueter-ci/OpenSSL`
- `PACKAGE` (required): `find_package` package name
- `EXTENSION` : Artifact extension (default `tar.zst` )
- `MIN_VERSION` : Minimum version for `find_package` . Only used if platform does not support this package as a bundled artifact
- `DISABLED_PLATFORMS` : List of platforms that lack artifacts for this package. One of:
* `windows-amd64`
* `windows-arm64`
* `android`
2025-10-04 09:27:13 +02:00
* `solaris-amd64`
* `freebsd-amd64`
* `linux-amd64`
2025-08-29 00:18:02 +02:00
* `linux-aarch64`
2025-10-04 09:27:13 +02:00
* `macos-universal`
2025-08-29 00:18:02 +02:00
### AddJsonPackage
This is the recommended method of usage for CPMUtil. In each directory that utilizes `CPMUtil` , there must be a `cpmfile.json` that defines dependencies in a similar manner to the individual calls.
The cpmfile is an object of objects, with each sub-object being named according to the package's identifier, e.g. `openssl` , which can then be fetched with `AddJsonPackage(<identifier>)` . Options are designed to map closely to the argument names, and are always strings unless otherwise specified.
- `package` -> `NAME` (`PACKAGE` for CI), defaults to the object key
- `repo` -> `REPO`
- `version` -> `VERSION`
- `ci` (bool)
If `ci` is `false` :
- `hash` -> `HASH`
2025-10-04 09:27:13 +02:00
- `hash_suffix` -> `HASH_SUFFIX`
2025-08-29 00:18:02 +02:00
- `sha` -> `SHA`
2025-10-04 09:27:13 +02:00
- `key` -> `KEY`
2025-08-29 00:18:02 +02:00
- `tag` -> `TAG`
2025-10-04 09:27:13 +02:00
* If the tag contains `%VERSION%` , that part will be replaced by the `git_version` , OR `version` if `git_version` is not specified
- `url` -> `URL`
2025-08-29 00:18:02 +02:00
- `artifact` -> `ARTIFACT`
2025-10-04 09:27:13 +02:00
* If the artifact contains `%VERSION%` , that part will be replaced by the `git_version` , OR `version` if `git_version` is not specified
* If the artifact contains `%TAG%` , that part will be replaced by the `tag` (with its replacement already done)
2025-08-29 00:18:02 +02:00
- `git_version` -> `GIT_VERSION`
2025-10-04 09:27:13 +02:00
- `git_host` -> `GIT_HOST`
2025-08-29 00:18:02 +02:00
- `source_subdir` -> `SOURCE_SUBDIR`
- `bundled` -> `BUNDLED_PACKAGE`
- `find_args` -> `FIND_PACKAGE_ARGUMENTS`
- `patches` -> `PATCHES` (array)
- `options` -> `OPTIONS` (array)
Other arguments aren't currently supported. If you wish to add them, see the `AddJsonPackage` function in `CMakeModules/CPMUtil.cmake` .
If `ci` is `true` :
- `name` -> `NAME` , defaults to the object key
- `extension` -> `EXTENSION` , defaults to `tar.zst`
- `min_version` -> `MIN_VERSION`
- `extension` -> `EXTENSION`
### Examples
2025-09-18 02:37:02 +02:00
In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discord-rpc (sha + options + patches)
2025-08-29 00:18:02 +02:00
``` json
{
"openssl" : {
"ci" : true ,
"package" : "OpenSSL" ,
"name" : "openssl" ,
"repo" : "crueter-ci/OpenSSL" ,
"version" : "3.5.2" ,
"min_version" : "1.1.1"
} ,
"boost" : {
"package" : "Boost" ,
"repo" : "boostorg/boost" ,
2025-10-04 09:27:13 +02:00
"tag" : "boost-%VERSION%" ,
"artifact" : "%TAG%-cmake.7z" ,
2025-08-29 00:18:02 +02:00
"hash" : "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01" ,
"git_version" : "1.88.0" ,
"version" : "1.57"
} ,
"opus" : {
"package" : "Opus" ,
"repo" : "xiph/opus" ,
"sha" : "5ded705cf4" ,
"hash" : "0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203" ,
"version" : "1.3" ,
"find_args" : "MODULE" ,
"options" : [
"OPUS_BUILD_TESTING OFF" ,
"OPUS_BUILD_PROGRAMS OFF" ,
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF" ,
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
]
} ,
"discord-rpc" : {
"repo" : "discord/discord-rpc" ,
"sha" : "963aa9f3e5" ,
"hash" : "386e1344e9a666d730f2d335ee3aef1fd05b1039febefd51aa751b705009cc764411397f3ca08dffd46205c72f75b235c870c737b2091a4ed0c3b061f5919bde" ,
"options" : [
"BUILD_EXAMPLES OFF"
] ,
"patches" : [
"0001-cmake-version.patch" ,
"0002-no-clang-format.patch" ,
"0003-fix-cpp17.patch"
]
} ,
}
```
### Inclusion
To include CPMUtil:
``` cmake
include ( CPMUtil )
```
## Prefetching
- To prefetch a CPM dependency (requires cpmfile):
* `tools/cpm-fetch.sh <packages>`
- To prefetch all CPM dependencies:
* `tools/cpm-fetch-all.sh`
2025-09-08 19:21:38 +02:00
Currently, `cpm-fetch.sh` defines the following directories for cpmfiles (max depth of 2, so subdirs are caught as well):
2025-08-29 00:18:02 +02:00
2025-09-15 17:21:18 +02:00
`externals src/qt_common src/dynarmic .`
2025-08-29 00:18:02 +02:00
Whenever you add a new cpmfile, update the script accordingly