97 lines
3.8 KiB
Markdown
97 lines
3.8 KiB
Markdown
|
# CMake Package Detector
|
||
|
|
||
|
This proof-of-concept detects which packages are used in a CMake project without having to modify the project at all (in most cases.) This could be used to generate dependency data for KDE libraries and also 3rd party dependencies.
|
||
|
|
||
|
## How it works
|
||
|
|
||
|
As you may have seen before, lots of CMake projects (including KDE software) uses a module called `FeatureSummary`. It prints out what packages are used in a project and also a whole host of other configurable information.
|
||
|
|
||
|
Here's the trimmed output from the feature summary in Tokodon:
|
||
|
|
||
|
```shell
|
||
|
-- The following REQUIRED packages have been found:
|
||
|
|
||
|
* ECM (required version >= 5.240.0)
|
||
|
* Gettext
|
||
|
* Qt6Keychain
|
||
|
Secure storage of account secrets
|
||
|
* KF6QQC2DesktopStyle
|
||
|
Preferred Qt Quick Controls style
|
||
|
* KF6KIO (required version >= 5.240.0)
|
||
|
Sharing content and downloading files
|
||
|
* KF6Purpose (required version >= 5.240.0)
|
||
|
Sharing content from other KDE applications
|
||
|
* KF6 (required version >= 5.240.0)
|
||
|
Required application components
|
||
|
* KF6DBusAddons (required version >= 5.240.0)
|
||
|
Single application support
|
||
|
* KF6WindowSystem (required version >= 5.240.0)
|
||
|
Misc windowing operations
|
||
|
* Qt6
|
||
|
Required application components
|
||
|
|
||
|
-- The following OPTIONAL packages have not been found:
|
||
|
|
||
|
* Qt6QmlCompilerPlusPrivate
|
||
|
* KUnifiedPush, <https://invent.kde.org/libraries/kunifiedpush>
|
||
|
Push notification support
|
||
|
|
||
|
-- The following REQUIRED packages have not been found:
|
||
|
|
||
|
* KF6KirigamiAddons (required version >= 0.11.40)
|
||
|
Required application components and runtime dependency
|
||
|
* MpvQt
|
||
|
```
|
||
|
|
||
|
CMake Package Detector overrides the default `FeatureSummary` module with a custom version that includes a basic file output, which is then pre-processed a bit before outputting to `stdout`.
|
||
|
|
||
|
The benefits of this over other solutions (some are described [in this issue](https://invent.kde.org/sdk/kdesrc-build/-/issues/9)) is enormous:
|
||
|
|
||
|
### Manual list keeping
|
||
|
|
||
|
CMake Package Detector can automatically update dependencies, as the CMakeLists for the project is now the single source of truth. It also handles if-else chains since it uses CMake under the hood, which eliminates classes of hand-written errors.
|
||
|
|
||
|
### Using distribution packages (for build dependencies)
|
||
|
|
||
|
This encounters the same set of issues, whenever a new dependency is introduced then it will usually not be reflected in the distribution package for months at a time. Also, distributors tend to have to deal with dependency issues via trial and error, so the issue still exists but is handled by someone else and delayed.
|
||
|
|
||
|
(Also, not every module exists in a distribution.)
|
||
|
|
||
|
### .kde-ci.yml
|
||
|
|
||
|
This file is still handwritten, and it usually concerns dependencies between KDE software and select 3rd party stuff.
|
||
|
|
||
|
### Some kind of CMake log parser/manual generation
|
||
|
|
||
|
Since we use CMake itself to calculate dependency data, it's 1-to-1 as it is on developer machines which is big. And it happens on the configuration step, so it's extremely quick. Since it doesn't depend on errors (such as my log parser) then it's more pro-active than re-active.
|
||
|
|
||
|
## Usage
|
||
|
|
||
|
Run `main.py` and give it a project path, like so:
|
||
|
|
||
|
```commandline
|
||
|
$ python main.py ~/kde/tokodon
|
||
|
```
|
||
|
|
||
|
And it should spit out a list of CMake packages needed, and this could be fed into something like `dnf` with it's `CMake()` query.
|
||
|
|
||
|
```commandline
|
||
|
CMake Packages:
|
||
|
ECM
|
||
|
Qt6QmlIntegration
|
||
|
Qt6QmlModels
|
||
|
Qt6OpenGL
|
||
|
Qt6QuickTemplates2
|
||
|
Qt6QuickControls2
|
||
|
Qt6Svg
|
||
|
Qt6WebSockets
|
||
|
Qt6Test
|
||
|
...
|
||
|
```
|
||
|
|
||
|
## Caveats
|
||
|
|
||
|
There is a few requirements for this to work correctly:
|
||
|
|
||
|
1. The project must **not** use the `REQUIRED` argument on `find_package`. This stops the CMake configuration step and the package list will be incomplete. Instead, use `set_package_properties` and set `TYPE REQUIRED` there instead.
|
||
|
2. The project must use `FeatureSummary` (it should be doing this anyway, in my opinion.) It also must use the `feature_summary` function.
|