# Feature Request: setting find\_package versions via env/cmake variables

**URL:** <https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661>\
**Category:** Development\
**Created:** [December 14, 2021, 2:49pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661 "2021-12-14T14:49:32Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![milianw](https://discourse.cmake.org/user_avatar/discourse.cmake.org/milianw/32/2035_2.png) [@milianw](https://discourse.cmake.org/u/milianw)\
**Post date:** [December 14, 2021, 2:49pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/1 "2021-12-14T14:49:32Z")

</div>

Hey there,

ArchLinux just rolled out Python 3.10 leading to all sorts of incompatibilities. In one of our project that aggregates multiple other third parties, this leads to lots of havoc. What’s worse, I think I have no alternative to actively editing cmake file by hand to set a version range on all `find_package(Python3)` calls.

Thus the feature request: It would be great, if we could get something similar to `<PackageName>_ROOT`, but for setting the `VERSION` part of the `find_package` call.

Ideally then, I would be able to do something like this:

```auto
cmake -DPython3_FIND_PACKAGE_VERSION="3.7...<3.10" ...

```

Or similar via an environment variable.

Thanks

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [December 14, 2021, 3:13pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/2 "2021-12-14T15:13:25Z")

</div>

Version specification is processed by the `find_package` command (for example, various variables related to version are already defined when the module is called) so bypassing it with some variable seems not a good idea.

But, maybe, a more general approach can be evaluated: to offer the possibility to specify the version needed by some variable (like `<PackageName>_REQUESTED_VERSION`, for example) which will be processed by `find_package`. By this approach, **all** modules will benefit from this new functionality without any change required.

---

<div class="post-metadata">

**Author:** ![milianw](https://discourse.cmake.org/user_avatar/discourse.cmake.org/milianw/32/2035_2.png) [@milianw](https://discourse.cmake.org/u/milianw)\
**Post date:** [December 14, 2021, 3:15pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/3 "2021-12-14T15:15:12Z")

</div>

Yes, that would solve my problem too. I.e. I could then explicitly set `Python3_REQUESTED_VERSION=3.9`

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [December 14, 2021, 4:20pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/4 "2021-12-14T16:20:43Z")

</div>

`find_package` lets you specify a version range:

```cmake
find_package(<PackageName> major.minor...<major.minor REQUIRED)

```

The first match wins over consecutive `find_package` calls. This means that you have to add this call further up your project (somewhere to make sure it is the first `find_package` used). You seem to be interested in a single Python version for your entire CMake project, in which case this function should be in the top level CMake list.

If your Python installation is not in the default path you’d also need to manually set the root dir:

```cmake
cmake -DPython3_ROOT_DIR=$HOME/python/versions/3.9.0 ..

```

---

<div class="post-metadata">

**Author:** ![milianw](https://discourse.cmake.org/user_avatar/discourse.cmake.org/milianw/32/2035_2.png) [@milianw](https://discourse.cmake.org/u/milianw)\
**Post date:** [December 14, 2021, 5:44pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/5 "2021-12-14T17:44:29Z")

</div>

Ah, thanks. That’s good to know as a workaround. I think the problem with Python specifically is that there are so many ways to search for it:

```auto
find_package(Python
find_package(Python3
find_package(PythonLibs
find_package(PythonInterp
find_package(PythonModuleGeneration

```

These are all that get used by the project I’m working on and its dependencies transitively. Obviously it should all just be `Python3`, but reality is more ugly.

One way or another, I’ll have to ensure that all of these point to the same python version…

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [December 14, 2021, 5:59pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/6 "2021-12-14T17:59:57Z")

</div>

It is more than a workaround. For CMake it is the way to go for dependency management.

> [@milianw](#):
>
> ```auto
> find_package(Python
> find_package(Python3
> find_package(PythonLibs
> find_package(PythonInterp
> find_package(PythonModuleGeneration
> 
> ```

I haven’t dealt with this situation before but i cannot think why it should be any different. Maybe the following works for you:

```cmake
project(top)
find_package(Python <version> EXACT)
find_package(Python3 <version> EXACT)
find_package(PythonLibs <version> EXACT)
find_package(PythonInterp <version> EXACT)
find_package(PythonModuleGeneration <version> EXACT)
add_subdirectory(3rdParty)
  add_subdirectory(party1)
    find_package(Python)
  add_subdirectory(party2)
    find_package(Python3)
  add_subdirectory(party3)
    find_package(PythonLibs)
  add_subdirectory(party4)
    find_package(PythonInterp)
  add_subdirectory(party5)
    find_package(PythonModuleGeneration)

```

of course this is only a sketch. Let me know if it is not clear.

---

<div class="post-metadata">

**Author:** ![milianw](https://discourse.cmake.org/user_avatar/discourse.cmake.org/milianw/32/2035_2.png) [@milianw](https://discourse.cmake.org/u/milianw)\
**Post date:** [December 14, 2021, 8:36pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/7 "2021-12-14T20:36:37Z")

</div>

Thank you, I was not aware that this was the recommended way for dependency management. Thinking about it now, it makes a lot of sense.

Cheers

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [December 14, 2021, 10:29pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/8 "2021-12-14T22:29:49Z")

</div>

Modules `FindPyhtonInterp` and `FindPythonLibs` are deprecated must no longer used. And it make definitively no sense to used them mixed with `FindPython*` modules.

Moreover, using `FindPython` with `FindPython2` and `FindPython3` is also an error.  
`FindPython` is used when the goal is to search for python, regardless the version.

And to finish, all these modules are independent in the sense they set different variables.

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [December 14, 2021, 10:37pm UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/9 "2021-12-14T22:37:02Z")

</div>

> [@marc.chevrier](#):
>
> And to finish, all these modules are independent in the sense they set different variables.

And I’ll just note that such behavior was an explicit design decision. (Note that I’m not familiar with `PythonModuleGeneration`, so I have no idea there.) The major problem with `FindPythonInterp` and `FindPythonLibs` is that they did not work together and one could find `pythonX.Y`, but `libpythonW.Z` (this was usually witnessed on macOS with HomeBrew and/or SDKs loaded, but anywhere multiple Pythons were “visible”, there was no coordination). The support for separate Python2 and Python3 was also intentional because one project might want to support both at once and a single find module will just end up conflicting with itself when trying to find 2 and 3 at separate points in the build.

---

<div class="post-metadata">

**Author:** ![milianw](https://discourse.cmake.org/user_avatar/discourse.cmake.org/milianw/32/2035_2.png) [@milianw](https://discourse.cmake.org/u/milianw)\
**Post date:** [December 15, 2021, 8:30am UTC](https://discourse.cmake.org/t/feature-request-setting-find-package-versions-via-env-cmake-variables/4661/10 "2021-12-15T08:30:12Z")

</div>

Oh, don’t get me wrong - I’m totally with you all on that matter. But the sad reality is simply that when one bundles multiple dependencies in a larger application, it may simply happen that all of these, including the deprecated ones, are used…

For this reason I was thinking it would be nice if there could be a central switch to dictate that all dependencies agree on the same version. But that seems to be possible by using the approach outlined by @hex.
