[CMake] [patch] cmake-2.8.1 and png-1.4.2

Michael Hertling mhertling at online.de
Tue Jun 22 04:16:32 EDT 2010


On 06/20/2010 12:34 AM, Thomas Klausner wrote:
> Hi!
> 
> I've updated png in pkgsrc to 1.4.2 and had to fix some programs to
> compile against that version.
> 
> cmake didn't find the png library at all, since it was renamed

There is rather a new version with a different SONAME.

> (again). The attached patch fixes the problem, please include it in
> the next release.

--- Modules/FindPNG.cmake.orig	2010-04-06 14:45:31.000000000 +0000
+++ Modules/FindPNG.cmake
@@ -33,7 +33,7 @@ if(ZLIB_FOUND)
   /usr/local/include/libpng             # OpenBSD
   )

-  set(PNG_NAMES ${PNG_NAMES} png libpng png12 libpng12)
+  set(PNG_NAMES ${PNG_NAMES} png libpng png12 libpng12 png14 libpng14)
   find_library(PNG_LIBRARY NAMES ${PNG_NAMES} )

   if (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR)

I would recommend against doing so. As discussed recently,
<http://www.mail-archive.com/cmake@cmake.org/msg28878.html>,
FIND_LIBRARY() prefers the NAMES to the searched paths, so it decides
in favour of a candidate earlier in the NAMES even if a later one is
earlier in the paths which may lead to hardly solvable problems w.r.t.
choosing specific versions. E.g., imagine you've installed libpng 1.4
in /usr, i.e. libpng.so -> libpng14.so, and libpng12.* in /opt/lib for
compatibility, i.e. without the libpng.so link. You won't be able to
find 1.2 as long as 1.4 is found in /usr - even CMAKE_PREFIX_PATH et
al. don't help - unless you set PNG_NAMES to "png12" before calling
FIND_PACKAGE(PNG), an undocumented and possibly unmeant feature. In
other words: If multiple versions of the same library have different
names you can't direct FIND_LIBRARY() to one that comes later in the
NAMES if an earlier one can be found in the paths.

IMO, specifying multiple library versions that are not totally
equivalent is a misuse of FIND_LIBRARY()'s NAMES option, potentially
resulting in the above-mentioned difficulties. FindTCL.cmake suffers
from this, FindPythonInterp.cmake does with FIND_PROGRAM(), too, and
FindPythonLibs.cmake has similar shortcomings in regard to hardcoded
versions, so it should be avoided to impair another finder module in
this manner. The right approach, I'd say, is to use FIND_PACKAGE()'s
versioning support to set up appropriate calls to FIND_LIBRARY(),
e.g.:

--- [...]/Modules/FindPNG.cmake    2010-04-06 16:45:31.000000000 +0200
+++ ./FindPNG.cmake      2010-06-22 09:27:50.000000000 +0200
@@ -33,7 +33,13 @@
   /usr/local/include/libpng             # OpenBSD
   )

-  set(PNG_NAMES ${PNG_NAMES} png libpng png12 libpng12)
+  if(NOT PNG_FIND_VERSION)
+    set(PNG_NAMES png libpng)
+  else()
+    set(PNG_NAMES
+        png${PNG_FIND_VERSION_MAJOR}${PNG_FIND_VERSION_MINOR}
+        libpng${PNG_FIND_VERSION_MAJOR}${PNG_FIND_VERSION_MINOR})
+  endif()
   find_library(PNG_LIBRARY NAMES ${PNG_NAMES} )

   if (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR)

Of course, this could be much more elaborated, e.g. in regard to the
EXACT option or the version's patch level, but it allows to request
libpng's overall version or to further say just FIND_PACKAGE(PNG)
which looks for the versionless libpng.so, and variables like
CMAKE_PREFIX_PATH can be used to find a specific libpng as
expected.

Regards,

Michael


More information about the CMake mailing list