In several find modules of dune, the commands find_library, find_path, and find_program are called twice:
with option NO_DEFAULT_PATH that enabled all NO_* options, i.e., only search in HINTS and PATHS that are specified in the find_xxx commands.
without the option NO_DEFAULT_PATH
This is a non-standard behaviour and essential means that the paths fixed in the commands are always preferred. Is there any reason for this, that I do not see? Or is it historical, because the behaviour in cmake changed?
Designs
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
This was an active choice and followed good practices we learned from others. Even today, the documentation for find_libray states:
The default search order is designed to be most-specific to least-specific for common use cases. Projects may override the order by simply calling the command multiple times and using the NO_* options:
find_library ( NAMES name PATHS paths... NO_DEFAULT_PATH)
find_library ( NAMES name)
Once one of the calls succeeds the result variable will be set and stored in the cache so that no call will search again.
If you have good arguments to change that, we can discuss these. The idea behind the current way is, to prefer the paths given by the user (first run) over the default ones (second run).
For me it is irritating if you allow multiple variable names for the same search hints, e.g. GMP_PREFIX and GMP_ROOT for GMP, or METIS_DIR and METIS_ROOT for METIS? Why two variables representing the same? Why not just specify one variable where to search for GMP or METIS?
Let's say Package_ROOT. This variable is searched for nevertheless as first step. No need to specify manually that you want to search in Package_ROOT first. This is the default behaviour.
The change in the behaviour is (in my opinion) only necessary, if you want to specify non-standard variables that specify search paths and want to prefer those variables over all others. Like, maybe, EBROOTMETIS in easybuild software-management systems.
The find_library documentation states, as you have quoted, "The default search order is [...] for common use cases". So, in almost all cases, just one call to find_xxx should be fine. Only if you have very specific needs to change this behaviour, two well designed calls to find_xxx should be implemented.
In FindSuiteSparse, for example, I have reduced the two calls to just one. I can specify the system installed library, the bild directory of a manual installation, the install-directory of a manual installation, the cmake-variant of suitesparse with build and install dir. I have seen no problems with just setting SuiteSparse_ROOT. No need to do something else.
The search order of find_package(), find_library(), and find_path() in CMake >=3.12 is the following:
Directories specified by <Package>_ROOT, if any.
Search paths specified in the CMake cache.
Search paths specified in the CMake environment variables.
Directories given as HINTS.
Standard system directories.
Directories given as PATHS.
So the new default behavior should be what @gruenich was previously aiming for with the NO_DEFAULT_PATH option.
Several find modules of DUNE also support hinting a location via <Package>_DIR, but this variable is actually reserved for a Config mode search. From the docs on find_package():
Config mode search attempts to locate a configuration file provided by the package to be found. A cache entry called <PackageName>_DIR is created to hold the directory containing the file. [...] If <PackageName>_DIR has been set to a directory not containing a configuration file CMake will ignore it and search from scratch.
If you want to maintain the possibility of hinting the location of a package via <Package>_DIR for backwards compatibility , it should hence be safe to add this variable to the HINTS of the respective find_library() and find_path() calls in the find module.
Thanks for digging up those fact, @simon.praetorius and @lukas.riedel! Both of you are right. Back then there was no default how to name the variables. We chose _DIR over _ROOT, and we needed two calls. As CMake 3.12 defined _ROOT as the way to go, we should adapt and get rid of the second find_* calls.