Search code examples
cmakecmake-languagecmakelists-options

cmake use wildcard for find_library NAMES option


In cmake to find a library we use find_library(MyLibrary_LIBRARY NAMES mylibrary mylibrary10 mylibrary11 HINTS /path/to/library). This command tells cmake to find a file named mylibrary.so or mylibrary10.so or mylibrary11.so (or files with .lib suffix in windows) per path of HINTS. If any of the above files were found, the path to the file would be written to the MyLibrary_LIBRARY variable. However, as one of the libraries I am using is frequently being updated - so that the library would soon be renamed to mylibrary20.so or mylibrary21.so - I need to update the cmake script frequently to reflect the changes. I wonder if there is a way that I can use wildcard here, so that cmake would automatically find mylibraryXX.so here, where XX means two digits.

According to documentation (https://cmake.org/cmake/help/latest/command/find_library.html), it seems this is not supported. If that's the case, will there be any other workarounds? (Creating a link from mylibraryXX.so to mylibrary.so doesn't quite work for me, as I don't have control of the library.)


Solution

  • There is no support for wildcard in the find_library and other find_* commands.

    If name of the library is not fixed, then it is normal to enumerate all possible names in NAMES option.

    For example, script FindBoost.cmake collects all known versions of Boost in a variable:

    set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
        "1.74.0" "1.74"
        "1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69"
        "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
        # ...
        "1.34" "1.33.1" "1.33.0" "1.33")
    

    and create list of possible library names by iterating over this variable.

    Note, that while the list of known versions is hardcoded, FindBoost.cmake allows (by means of Boost_ADDITIONAL_VERSIONS variable) a user to specify additional versions, which could be not known for the script at the time it is written.

    For create a list of possible library names with two-digits version suffix, you may use foreach(RANGE) loop:

    set(mylibrary_names)
    foreach(ver RANGE 11 99)
      list(APPEND mylibrary_names mylibrary${ver})
    endforeach()
    
    find_library(MyLibrary_LIBRARY NAMES ${mylibrary_names})
    

    Note, that changing library name usually implies some incompatibility, so blindly iterating over all virtually possible versions of the library may cause you program to not work as expected.