microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
23.23k stars 6.4k forks source link

How to specify version for a feature's depencency? #28432

Closed reitowo closed 1 year ago

reitowo commented 1 year ago

I am upgrading ffmpeg to 5.1.2 and considering its API change, I want to restrict all ports which depends on ffmpeg to an older version: 4.4.3, for example aubio:

``` { "name": "aubio", "version-semver": "0.4.9", "port-version": 9, "description": "Aubio is a tool designed for the extraction of annotations from audio signals. Its features include segmenting a sound file before each of its attacks, performing pitch detection, tapping the beat and producing midi streams from live audio.", "homepage": "https://github.com/aubio/aubio", "license": "GPL-3.0-or-later", // Tried, no effect "overrides": [ { "name": "ffmpeg", "version-string": "4.4.3#1" } ], "dependencies": [ { "name": "vcpkg-cmake", "host": true }, { "name": "vcpkg-cmake-config", "host": true } ], "default-features": [ "tools" ], "features": { "tools": { "description": "Build tools and add extra dependencies", "dependencies": [ "bzip2", { "name": "ffmpeg", "default-features": false, "features": [ "avcodec", "avformat", "swresample" ] }, "libflac", "liblzma", "libogg", { "name": "libsndfile", "default-features": false }, "libvorbis" ] } } } ```

I tried to use overrides but it makes no effect, I also tried to add version= in the feature.dependencies, but it only accepts version>=.

$.features.tools.dependencies[1] (a dependency): unexpected field 'version', did you mean 'version>='?

So how to restrict port feature dependency to an old version, or like version<= to avoid blocking ports from update with API breaking changes? I think implementing a version<= constraint is better than renaming ffmpeg to ffmpeg5 and forbids ports from API breaking changes. Adding version= and version<= for port feature's dependency will also solve #23312 and #28387 because they will be blocked by ports depends on ffmpeg.

In my opinion, ports that depends on other ports should constraint the version explicitly. Take an example: If my project use ffmpeg 5.x, and one dependency I use depends on 4.x, it comes into a typical C++ dependency hell. Either I switch my project to 4.x, or I have to urge the library author to move up to 5.x. Although it sounds frustrating, but it will makes both my project and the library port pretty clean and straight forward. Moreover, making multiple ports like opencv2, opencv3, opencv4 doesn't makes it easier under same situation: My project depends on ffmpeg5, and a library port depends on ffmpeg, it is also a depencency hell and we still don't want to use multiple versions of same library. In one word, being lazy solves nothing for us, although it might save us plenty of time implementing version constraints. I have to admit that both approach solves the problem, but the later one is more friendly to port maintainer, as we have no additional works to do if ports depends on us. We don't have to do liblib2, liblib3 everytime have API breaking changes. From the other hand, the ports also don't need to worry if one dependency made some breaking changes and breaks the port either, all dependency should be freezed using baseline revision. At the same time, we can still overrides versions if we do have some special circumstances.

If such PR is welcomed by the vcpkg commitee, I'm willing to contribute. Anyway, only supports constraint version>= makes no sense to a modern package manager.

Neumann-A commented 1 year ago

Adding version= and version<= for port feature's dependency

Simply said: Not going to happen. Not supplying this has been a concise design choice since you would make parts of vcpkg unbuildable. As such the only solution is to fix downstream or find an alternative acceptable solution.

reitowo commented 1 year ago

Since this is already a decision, I think I will stick to create another port if there's breaking change.