然后,我们使用studio创建一个新的带有c++ support的新工程,activity 留空我们也不要运行或是生成apk,只是为了编译。
创建完成后,Java代码会报错,因为没有创建layout相关代码全部删了,哪里错就删哪里。然后,把libpng的h和c文件拷贝到cpp文件夹里面,拷贝libpng根目录里面所有的h和c具体见后面的cmakelist.txt。
cpp 文件夹原来包含native-lib.cpp文件不要动,把里面代码都删了,不需要。然后,编写cmakelist.txt文件。
# Sets the minimum version of CMake required to build the native # library. You should either keep the default value or only pass a # value of 3.4.0 or lower. cmake_minimum_required(VERSION 3.4.1) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -std=c99") # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds it for you. # Gradle automatically packages shared libraries with your APK. include_directories( src/main/cpp/ ) add_library( png STATIC src/main/cpp/pngget.c src/main/cpp/pngread.c src/main/cpp/pngrutil.c src/main/cpp/pngtrans.c src/main/cpp/pngwtran.c src/main/cpp/png.c src/main/cpp/pngmem.c src/main/cpp/pngrio.c src/main/cpp/pngset.c src/main/cpp/pngwio.c src/main/cpp/pngwutil.c src/main/cpp/pngerror.c src/main/cpp/pngpread.c src/main/cpp/pngrtran.c src/main/cpp/pngwrite.c ) set_target_properties( png PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${ANDROID_ABI}" ) target_link_libraries( png z ) add_library( native-lib SHARED src/main/cpp/native-lib.cpp ) target_link_libraries( native-lib png ) 文件路径是相对于 cmakelist.txt的。 png编译需要static 只要一个a文件。 native-lib是空的编译为so文件,设置为shared,没有一个so文件不工作。 png连接的时候需要z,因为使用了libzip。 还缺少一个pnglibconf.h文件。找到这个scripts/pnglibconf.h.prebuilt文件,重命名为pnglibconf.h放到cpp文件夹即可。这是报错后,报错代码位置注释写的。 set_target_properties的目的是,把编译的libpng.a文件放到指定目录,这里和cmakelist.txt同一目录。
然后,看gradle文件。
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.test.libpng" minSdkVersion 18 targetSdkVersion 23 versionCode 1 versionName "1.0" externalNativeBuild { ndk { abiFilters 'armeabi-v7a', 'arm64-v8a', 'armeabi', 'x86' } externalNativeBuild { cmake { arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=system' cFlags '-std=c99', '-DPNG_ARM_NEON_OPT=0' } } } } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } externalNativeBuild { cmake { path "CMakeLists.txt" } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) testCompile 'junit:junit:4.12' } 这里注意要加这句话,cFlags '-std=c99', '-DPNG_ARM_NEON_OPT=0',关闭neon的优化,不然编译报错。最后,我们需要把编译修改为release,编译出来就是直接使用的,不用debug模式。
执行编译成功后,会得到我们配置的不同平台的库文件,在cmakelist.txt目录下。如果需要编译libpng.so文件,修改cmake配置,就不需要native-lib SHARED来链接了。直接把png设置为SHARED的就可以了。libpng.so文件会生成在project/app/build/intermediates/cmake/release/obj/armeabi-v7a/libpng.so。
# Sets the minimum version of CMake required to build the native # library. You should either keep the default value or only pass a # value of 3.4.0 or lower. cmake_minimum_required(VERSION 3.4.1) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -std=c99") # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds it for you. # Gradle automatically packages shared libraries with your APK. include_directories( src/main/cpp/ ) add_library( png SHARED src/main/cpp/pngget.c src/main/cpp/pngread.c src/main/cpp/pngrutil.c src/main/cpp/pngtrans.c src/main/cpp/pngwtran.c src/main/cpp/png.c src/main/cpp/pngmem.c src/main/cpp/pngrio.c src/main/cpp/pngset.c src/main/cpp/pngwio.c src/main/cpp/pngwutil.c src/main/cpp/pngerror.c src/main/cpp/pngpread.c src/main/cpp/pngrtran.c src/main/cpp/pngwrite.c ) target_link_libraries( png z )