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

Michael Wild themiwi at gmail.com
Thu Sep 29 02:59:09 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 <mailto: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.
> 
> 
> 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.
> 
> 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.
> 
> 
>>> 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.
> 
> 
> 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?
> 
> Cheers, CY

Just a few of my thoughts on this:

- There are several ways to handle dead symlinks:
  1. Don't check, let the linker complain (status quo)
  2. Check whether the found library is a symlink, and if not valid,
     remove it silently from the list of candidates. Can be very
     surprising and will likely result in quite a few bug reports
     about CMake not finding a certain library that is "clearly" there.
  3. Like 2, but warn about the issue. Possibly very annoying.
I don't know which option to prefer (perhaps somebody finds another one
that is better?). IMHO bogus symlinks to shared libraries constitute a
real problem of the library installation, so CMake shouldn't just paper
over it by silently skipping the dead link, proceeding to the next
candidate which rules out option 2 for me. Also, option 3 can be
troublesome in automated setups where no user actually reads the CMake
output.

- Concerning link-tests:
  1. Only possible with shared libraries
  2. Some shared libraries require special linker flags which CMake
     would require the user to provide. Not so much of an issue, since
     the user needs to provide them anyways.
  3. Some shared libraries on *NIX systems are under-linked, i.e. they
     require additional libraries to be specified on the link line.
     Again, CMake can't know about those (as with static libraries).
  4. Last, but not least, linking can be a very expensive operation.


All of these factors make it very hard to come up with a set of tests
that produces no false negatives (i.e. *never* discards a library that
is actually valid). I don't care about false positives so much, because
the linker will complain loudly about those, but if CMake "refuses" to
find a valid library, that is a *real* problem.


My 2c.

Michael


More information about the CMake mailing list