Allow find_package to prefer CONFIG mode
To take advantage of the powerful generator expressions and INTERFACE properties. allow the user to globally specify that find_package should try CONFIG mode before MODULE mode. Perhaps a global variable like CMAKE_FIND_PACKAGE_PREFER_CONFIG.
Here's an example problem this would solve:
-
I have a software package using a set of third-party libraries ( eg zlib, png, ..) in an odd combination of shared and static. Most of these libraries have CMakeLists that expect every library they link with to be shared or static, not a combination.
-
To fix this, I carefully crafted custom CMakeLists for some common libraries (e.g. zlib, png, lzma). The new CMakeLists use generator expressions and INTERFACE properties so that all the right Include directories, definitions and libraries are added to any project using the libraries, regardless of whether they are being compiled as static or shared. PKGConfig.cmake files are exported for both the build and install trees.
-
A dependent lib/exe would not need to know if it's linking to a shared or static library, because the imported library defined in the PKGConfig.cmake file provides it with all the information it needs.
PROBLEM 1:
- Software repos do not, by default, use the CONFIG option when calling find_package for libraries such as zlib and png. This means, for example, calling find_package(PNG) will find a matching library and create its own imported library and ignore the exported PKGConfig file with all the INTERFACE definitions.
- I will need to modify the CMakeLists of all third-party libraries so that they first try find_package with the CONFIG option. And if that fails, try again with the MODULE option.
PROBLEM 2:
-
The command "find_dependency" does not have a CONFIG option and always uses MODULE mode.
-
Example: LibPNG links to zlib. If libpng is built as a static library, the exported PNGConfig.cmake must include a call to find_dependency(ZLIB) so that the library/executable linking to libpng can also link to zlib. But find_dependency does not have a CONFIG mode. It will find a zlib library, create its own imported library and ignore the exported ZLIBConfig.cmake.
WORKAROUND So that other packages will use the exported PKGConfig.cmake, I duplicate most of CMake's various FindPkg.cmake files and insert these lines at the top:
if( CMAKE_FIND_PACKAGE_PREFER_CONFIG )
# TODO: need to pass the other find_package parameters here
find_package( ${FIND_PACKAGE_NAME} CONFIG )
endif()
if( ${FIND_PACKAGE_NAME}_FOUND )
return()
endif()
< .. duplicate the find<pkg>.cmake file .. >
This is a workaround only. I imagine a far better solution would be in the find_package C code.