[CMake] Does find_library check that a found library does in fact link?

Michael Hertling mhertling at online.de
Mon Oct 3 19:52:47 EDT 2011


On 09/29/2011 07:15 AM, Clifford Yapp wrote:
> On Wed, Sep 28, 2011 at 8:52 PM, Michael Hertling <mhertling at online.de>wrote:
> 
> What do you do on systems which have no idea of symbolic links, e.g.
>> previous Windows versions? Adding more platform-specific code to the
>> sources of the FIND_LIBRARY() function?
> 
> 
> If the problem isn't solved (or readily solvable) on some platforms, we can
> just fall back to doing what we do now in those cases... we don't have to
> solve the problem on all possible platforms to improve the results on
> platforms that can be supported.  The point wouldn't be to *guarantee* the
> result of find_library is a valid working library (it doesn't do that now),
> just improve the results by doing what can be done to avoid returning
> results that can be tagged as non-working (since a build trying to use such
> results is guaranteed to fail anyway.)  Does cmake know (or can it tell)
> when it is cross compiling?  If so, it could decide how much to test and not
> test in those cases.

There's the CMAKE_CROSSCOMPILING variable which indicates if CMake is
configuring a project for cross-compilation, but that's not my actual
point here. Even for a non-cross-compiling project, FIND_LIBRARY()'s
candidate might be a valid library in one of several native binary or
even textual formats, or it can be in a foreign binary format and is
to be used in a combined native- and cross-compiling project. What's
about the opposite case, i.e. FIND_LIBRARY() returns a working native
library, but you intended to find a library in a foreign format? How
should FIND_LIBRARY() ever check if a library is valid, and what does
"valid" mean in this context? Nobody says that a library must be used
with the compilers specified in the CMAKE_<LANG>_COMPILER variables;
it might also be processed in a custom command/target by a different
tool. How would you implement the checks you envision if you can not
rely on CMAKE_<LANG>_COMPILER as linker front-end? How do you know
when you must check a library with the C++ compiler, and not the C
compiler? In short: For which criteria and by use of which means do
you decide whether a library is valid? IMO, FIND_LIBRARY() would
hardly be able to check for any criterion in a reliable manner,
so it's best to not have such checks in this function at all.

>> Furthermore, the kernels of
>> *nix systems hardly distinguish between binary files and text files;
>> usually, they know just "files" with the limited exception of being
>> able to recognize the native executable formats and the #! shebang.
>> The detection of the diverse file types is typically implemented
>> in utility programs, notably the file(1) utility.
>>
> 
> A linker test when possible (non-cross-compilation scenarios) with a
> fallback testing option using file introspection would handle a lot of
> situations, if I'm understanding correctly how this works.  To the best of
> my knowledge and that of one of our other devs (he knows a lot more than me)
> there aren't any platforms where actual library files (as opposed to linker
> scripts) consist solely of character values <128.  Checking a found file for
> at least one character over 128 would avoid at least a few failure cases -
> empty files, plain text files, and dead links.  Such a check would be
> reliable, consist, and would be useful in eliminating files we might find
> that are not actually library files.

"Why doesn't my linker script pass this test?"
"Because it contains comments in German."
"Häää?" ("48c3a4c3a4c3a43f" in UTF-8)

> Such a test  of course wouldn't pass linker scripts like ubuntu's libc.so,
> but such a script *would* pass the actual linker test and would never get to
> file introspection. Actually if the script failed the linker test, then
> there is a real problem that should be a failure case.  This would also be
> helpful in spotting early on the hypothetical case of a linker being tested
> that doesn't understand the .so linker script.

OTOH, an arbitrary binary file would not pass the linker test, but
the fallback introspection test, wouldn't it? A valid library as well
as an invalid one might consist of a binary as well as a textual file,
so this test cannot even rudimentarily be considered as reliable, IMO.

>>>> But how do you test whether a library is "linkable"?
>>
> 
> If not cross-compiling, wouldn't it be possible to have find_library try the
> link as part of its test?  Even in the case where linking isn't viable,
> falling back on the check on file contents would still be helpful.

Again, trying to link with *which* linker?

>> What do you do if the library found by FIND_LIBRARY() has a non-native
>> binary format, e.g. for cross-compiling purposes? How do you select the
>> right set of tools to check the library in question without the user's
>> ado? IMO, FIND_LIBRARY()'s job is to find library files, and a general
>> check whether these files are valid/usable/linkable and not dangling
>> symlinks or whatever is beyond the scope of this function; ensuring
>> that is rather the realm of system administration.
>>
> 
> I guess the question revolves around the expectation of find_library being
> different from find_file - as a user, my expectation would be that
> find_library is doing something to distinguish libraries from files (when
> that's technically workable, of course - clearly solving that problem in
> general is hard.)  If something tricky like cross-compiling is going on then
> the simpler testing behavior is in order, but couldn't CMake scrub the
> results looking for library validity as much as possible?

If I understand correctly, all your points are based on the assumption
that libraries delivered by FIND_LIBRARY() will be used to link other
binaries against, especially with the tools in CMAKE_<LANG>_COMPILER,
but this is just the usual case, not the only one. One might use other
tools for other purposes on the library files, and there might also be
very exceptional setups with a dangling symlink being exactly what the
user wants FIND_LIBRARY() to return. In such cases, one would not like
to have FIND_LIBRARY() issue warnings or even bail out. Rather, FIND_
LIBRARY() must not make any decisions on the validity of a library to
be returned, since it can hardly make such decisions reliably, IMO.

In order to not be misunderstood: Checking a library for its validity
w.r.t. certain purposes - linking or whatever - is useful, of course,
but it shouldn't be burdened on FIND_LIBRARY(). This function simply
lacks the necessary information to perform such checks and should be
considered as a specialized derivative of FIND_FILE(), i.e. it looks
in library-specific locations, knows library prefixes/suffixes etc.
For advanced checking, one might very well implement supplementary
functions that examines a library with regard to any criteria, e.g.
CHECK_LIBRARY_LINKS() similar to CHECK_LIBRARY_EXISTS(). BTW, does
the latter in combination with FIND_LIBRARY() not nearly do what
you intend?

Regards,

Michael


More information about the CMake mailing list