Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake use foreach and find_library to return full path of libraries

Tags:

cmake

I used a list to store names of libraries, and I would like to use foreach and find_library to find full path of each library. But find_library just returned the path of the first library. I checked this post, but problem still exist. My CMake version is 3.4.3.

SET(VTKLIBS_DIR)

FOREACH(LIB ${VTKLIBS})
        SET(FOUND_LIB)
        FIND_LIBRARY(FOUND_LIB ${LIB})
        LIST(APPEND VTKLIBS_DIR ${FOUND_LIB})
        MESSAGE("Lib: ${LIB}")
        MESSAGE("Found Lib: ${FOUND_LIB}")
        UNSET(FOUND_LIB)
ENDFOREACH(LIB)
like image 497
just_rookie Avatar asked Apr 21 '16 01:04

just_rookie


1 Answers

Command find_library sets cached variable, but simple form of command unset remove only simple variable's definition.

As noted by the link you provide, you need to store special value FOUND_LIB-NOTFOUND to the variable FOUND_LIB for force find_library to search another library while variable already contains path to the previous library:

FOREACH(LIB ${VTKLIBS})
        SET(FOUND_LIB "FOUND_LIB-NOTFOUND")
        FIND_LIBRARY(FOUND_LIB ${LIB})
        LIST(APPEND VTKLIBS_DIR ${FOUND_LIB})
        MESSAGE("Lib: ${LIB}")
        MESSAGE("Found Lib: ${FOUND_LIB}")
ENDFOREACH(LIB)

Actually, this is some kind of trick, as cached variable FOUND_LIB isn't changed by simple set command. But when find_library implementation attempts to read cached value of the variable, it actually read value of simple variable with the same name.

Because find_library treats only *-NOTFOUND cached values as "library not found", your trick with assigning empty value to the variable doesn't work.

The better approach, as noted by @arrowd, would be using different names for variable, used in different find_library() call:

FOREACH(LIB ${VTKLIBS})
        FIND_LIBRARY(FOUND_LIB_${LIB} ${LIB})
        LIST(APPEND VTKLIBS_DIR ${FOUND_LIB_${LIB}})
        MESSAGE("Lib: ${LIB}")
        MESSAGE("Found Lib: ${FOUND_LIB_${LIB}}")
ENDFOREACH(LIB)

Such a way results for every find_library call will be stored separately, and the same library will not be searched again at the next time cmake being invoked. Also, such approach allows user to modify (in cache) paths to concrete libraries without affecting other ones.

like image 110
Tsyvarev Avatar answered Oct 11 '22 07:10

Tsyvarev