Search code examples
macoslibpngotool

On macOS, why doesn't otool -L show the version of libpng the application is running with?


I'm compiling an application which uses the CMake build system for macOS 10.15.4. When I run the built application, I get an error (Application built with libpng-1.5.23 but running with 1.6.37) informing me that I have a mismatch between the version of libpng that the application was compiled against and the one it's using while it runs:

Hostname:sample_data username$ ~/src/github/hoche/splat/build/src/Debug/splat -t ~/src/github/hoche/splat/sample_data/wnju-dt.qth -sdelim _ -L 5 -maxpages 4
.
.
.
Writing Signal Strength map "/Users/username/src/github/hoche/splat/sample_data/wnju-dt.png" (2400x2430 image)... libpng warning: Application built with libpng-1.5.23 but running with 1.6.37
Done!

I've told CMake to generate an Xcode project file for Xcode 11.3. The application in question uses libpng. I tell CMake to use libpng with the following clause in my CMakeLists.txt:

find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)
find_package(Threads REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
add_executable(splat
    .
    .
    .)
target_link_libraries(splat bz2 ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})

I've installed libpng via MacPorts. When I view the linker lines in the generated Xcode, project, they look like:

Xcode linker lines

otool -L reports:

Hostname:sample_data username$ otool -L ~/src/github/hoche/splat/build/src/Debug/splat 
/Users/username/src/github/hoche/splat/build/src/Debug/splat:
    /usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.5)
    /opt/local/lib/libpng16.16.dylib (compatibility version 54.0.0, current version 54.0.0)
    /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
    /opt/local/lib/libjpeg.9.dylib (compatibility version 13.0.0, current version 13.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.7.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)

If I examine the files at the location indicated on the linker line, they appear correct too:

HOstname:sample_data username$ ls -al /opt/local/lib/libpng*
lrwxr-xr-x  1 root  admin      10 Oct 28  2019 /opt/local/lib/libpng.a -> libpng16.a
lrwxr-xr-x  1 root  admin      14 Oct 28  2019 /opt/local/lib/libpng.dylib -> libpng16.dylib
-rwxr-xr-x  1 root  admin  177352 Oct 28  2019 /opt/local/lib/libpng16.16.dylib
-rw-r--r--  1 root  admin  253120 Oct 28  2019 /opt/local/lib/libpng16.a
lrwxr-xr-x  1 root  admin      17 Oct 28  2019 /opt/local/lib/libpng16.dylib -> libpng16.16.dylib

Why is libpng complaining about a version mismatch? Is it really using the wrong version? If so, why doesn't otool -L show the version it runs with?


Solution

  • The error is due to a mismatch between the header files used and the library. The library version as indicated in the Mach-O load commands is not the issue.

    Certain calls to libpng require that you pass PNG_LIBPNG_VER_STRING as a parameter. That effectively bakes the version from the headers into the calling code and libpng compares that to its own version to check for compatibility.

    Make sure the headers that come with the library are the (first) ones found by the compiler.