使用cmake失败为android构建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

在执行buildlibng.sh并调用make之后,这就是日志。

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,我想这就是我问题的原因。

我配置错误了吗?你能帮忙吗?

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文件,所以一切都正常。看起来生成器使用的是手工编制的编译器调用,这种调用不是超稳定的,在某些体系结构的交叉编译时会失败。正确的选择可能是深入研究这些脚本并修复它们。

最新更新