使用cmake失败为Android构建libpng

时间:2018-07-17 03:48:19

标签: android cmake libpng

我正在尝试构建libpng 1.6.34以在我的android项目中使用。 我也尝试使用cmake

这是build_libpng.sh文件

export CMAKE_SYSTEM_NAME=Android
export CMAKE_BUILD_TYPE=Debug
export CMAKE_TOOLCHAIN_FILE=~/android-sdk/ndk-bundle/build/cmake/android.toolchain.cmake
export CMAKE_LIBRARY_OUTPUT_DIRECTORY=obj/armeabi-v7a 

export ANDROID_ABI=armeabi-v7a
export ANDROID_PLATFORM=android-15
export ANDROID_NDK=~/android-sdk/ndk-bundle
export CMAKE_CXX_FLAGS=-frtti -fexceptions

export ZLIB_INCLUDE_DIR=./zlib.1.2.11 
export ZLIB_LIBRARY=./zlib.1.2.11 

~/android-sdk/cmake/3.6.4111459/bin/cmake  -G"Android Gradle - Unix Makefiles"  ./lpng1634/CMakeLists.txt

执行build_libpng.sh并调用后,将其作为日志。

Scanning dependencies of target genfiles
[  0%] Built target genfiles
Scanning dependencies of target png
[  2%] Building C object CMakeFiles/png.dir/png.c.o
[  5%] Building C object CMakeFiles/png.dir/pngerror.c.o
[  8%] Building C object CMakeFiles/png.dir/pngget.c.o
[ 11%] Building C object CMakeFiles/png.dir/pngmem.c.o
[ 13%] Building C object CMakeFiles/png.dir/pngpread.c.o
[ 16%] Building C object CMakeFiles/png.dir/pngread.c.o
[ 19%] Building C object CMakeFiles/png.dir/pngrio.c.o
[ 22%] Building C object CMakeFiles/png.dir/pngrtran.c.o
[ 25%] Building C object CMakeFiles/png.dir/pngrutil.c.o
[ 27%] Building C object CMakeFiles/png.dir/pngset.c.o
[ 30%] Building C object CMakeFiles/png.dir/pngtrans.c.o
[ 33%] Building C object CMakeFiles/png.dir/pngwio.c.o
[ 36%] Building C object CMakeFiles/png.dir/pngwrite.c.o
[ 38%] Building C object CMakeFiles/png.dir/pngwtran.c.o
[ 41%] Building C object CMakeFiles/png.dir/pngwutil.c.o
[ 44%] Linking C shared library obj/armeabi-v7a/libpng16d.so
[]/android-sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot open [...]/third_party/lpng1634/libpng.vers: No such file or directory
[...]/android-sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: fatal error: unable to parse version script file [...]/third_party/lpng1634/libpng.vers
clang: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeFiles/png.dir/build.make:459: recipe for target 'obj/armeabi-v7a/libpng16d.so' failed
make[2]: *** [obj/armeabi-v7a/libpng16d.so] Error 1
CMakeFiles/Makefile2:99: recipe for target 'CMakeFiles/png.dir/all' failed
make[1]: *** [CMakeFiles/png.dir/all] Error 2
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2

我阅读了lpng1634 / CMakeLists.txt,其中有一些我不太了解。

在这一部分

if(NOT AWK OR ANDROID)
  # No awk available to generate sources; use pre-built pnglibconf.h
  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
                 ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
  add_custom_target(genfiles) # Dummy

else()
... code for generating libpng.vers here
endif(NOT AWK OR ANDROID)

但是这部分

if(PNG_SHARED)
  add_library(png SHARED ${libpng_sources})
  set(PNG_LIB_TARGETS png)
  set_target_properties(png PROPERTIES OUTPUT_NAME ${PNG_LIB_NAME})
  add_dependencies(png genfiles)
  if(MSVC)
    # msvc does not append 'lib' - do it here to have consistent name
    set_target_properties(png PROPERTIES PREFIX "lib")
    set_target_properties(png PROPERTIES IMPORT_PREFIX "lib")
  endif()
  target_link_libraries(png ${ZLIB_LIBRARY} ${M_LIBRARY})

  if(UNIX AND AWK)
      if(HAVE_LD_VERSION_SCRIPT)
        set_target_properties(png PROPERTIES LINK_FLAGS
          "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
      elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT)
        set_target_properties(png PROPERTIES LINK_FLAGS
          "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
      endif()
  endif()
endif()

使用libpng.vers是我猜到的问题的原因。

我配置有误吗?你能帮忙吗?

1 个答案:

答案 0 :(得分:0)

TLDR

使用-DHAVE_LD_VERSION_SCRIPT=OFF选项,禁用构建共享库-DPNG_SHARED=OFF或在上游深入cmake代码

cmake -DHAVE_LD_VERSION_SCRIPT=OFF ./lpng1634

版本稍长

...据我所知...

在构建.so文件时,libpng要对其进行版本控制。为此,它会预先生成许多文件,其中包括libpng.vers。如果定义了ANDROID(或AWK不可用),它将跳过生成libpng.vers文件。即使未生成,它仍然会告诉链接器使用它并失败(导致您发布错误)。您可以通过指定-DHAVE_LD_VERSION_SCRIPT=OFF欺骗cmake跳过版本控制。

现在人们可能会问为什么它不仅仅生成这个.vers文件,所以一切正常。看起来生成器使用的是手工编译器调用,这种调用不是超级可靠的,并且在某些体系结构进行交叉编译时会失败。正确的选择可能是深入研究这些脚本并在那里进行修复。