Is CMAKE_PREFIX_PATH recursively searched?

Hi!

I have a build where a system package config file is picked up even though it should not be. Having read the docs on what the config file search logic is, it could only possible find it if the search of <prefix> is recurisve, however this word does not appear in the docs anywhere.

With 3.17, you should be able to pass --debug-find to have CMake output why it is finding the package in question.

CMAKE_PREFIX_PATH is not searched recursively, but specific paths are used relative to each entry to find other paths. For example, lib is looked in for find_library calls. If it is finding a foo-config.cmake package under it, it is in a path that is search specifically by CMake under the prefixes it is given.

1 Like

Thanks @ben.boeckel, that was a lifesaver. I installed the 3.17-rc3 for this sole purpose and debugged the issue. It’s picking up the package config file, because of a bin path, which is then shaved off and made a system-wide base of config file lookup. This rule 5. of Search Procedure is intricate, to say the least.

I was about to ask for the same kind of question.
We have a set of customarily build dependencies which are installed in a common prefix, say:
/my/local/install but each of them have their own subdir, say: /my/local/install/pkg/x.y.z so that pkg-config.cmake is located in /my/local/install/pkg/x.y.z/cmake.
I want my main build to find all those dependencies (with find_xxx) but in order to make that work
I have to append https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html with every /my/local/install/pkg/x.y.z/cmake I have (and I have a bunch of them) is there any reason CMake does not recurse into a specified CMAKE_MODULE_PATH ?

CMake would have to know where to stop. Recursively searching /usr is not something I want CMake to ever do (permission errors for various bits, finding documentation/examples instead of Real Code, etc.).

One thing that might be useful here is glob support in CMAKE_PREFIX_PATH (CMAKE_MODULE_PATH is more sensitive and probably not as viable IMO)?

Yes right. I suppose cmake can only look into *.cmake files. My need concerns find package and cmake config files which ought to be called that way.

Agreed. Globbing would be nice, and may be doing it in a programmatic way would
avoid repetitive globbing.
I.e. we could do that with:
cmake_prefix_path_add(PREFIX /my/local/install GLOB '*.cmake')
or
cmake prefix_path_add(PREFIX /my/local/install GLOB_RECURSE '*.cmake')

those call would populate CMAKE_PREFIX_PATH accordingly.
Which makes me think (out at loud) I can already do that with a user defined macro, I’ll give it a shot.

By the way why do you think CMAKE_MODULE_PATH is more sensitive?

I think you misunderstood. I don’t want CMake even looking under /usr/share/docs/examples (or whatever) for anything. It shouldn’t even get to the “does this filename match?” part of its logic.

Maybe I’m misunderstanding. Why is list(APPEND CMAKE_PREFIX_PATH "/static/*/*") not sufficient?

I think it is way more common to be able to say "I have a forest of prefixes that all match /static/*/*. I can’t say that it feels that common for files I want CMake to search in with include.

It is, no doubt.

My point was that we may want to enforce the fact that the globbing expression is resolved only once.
And not each time CMake uses CMAKE_PREFIX_PATH content.

I think this is the same idea as yours:

So if I may summarize:

  1. we may want to have a way to specify globbing expression in CMAKE_PREFIX_PATH
    which collect all paths used by find_xxx command
  2. we don’t want that for CMAKE_MODULE_PATH

I would add that globbing expression in CMAKE_PREFIX_PATH should ideally be processed only once.

If a developer wants globbing, that can already be done with one additional line, right?

Little more than one line I guess but yes it is already doable with something like:

file(GLOB_RECURSE CUSTOM_PATHS
     LIST_DIRECTORIES true
     "/my/custom/path/**/*")

then you’ll have to filter out files since (AFAIK) one cannot list “only directories”.
but yes a macro/function would do the job.