I want to compile libs that are bundled in my project. And I run into 2 issues.
First of one that Cmake does not seems to detect/include that directory.
Second one is after bundled directory is detected/included instead of android toolchain a system's one is used to compile libs.
As workaround to 1st issue I added if(ANDROID) to add that directory so it can be included.
if(EXISTS "${CMAKE_SOURCE_DIR}/libs/CMakeLists.txt")
message(STATUS "Using bundled libraries located at ${CMAKE_SOURCE_DIR}/libs")
if(ANDROID)
add_subdirectory(libs)
else()
include(libs/CMakeLists.txt)
endif()
else()
So for me expected result should follow like this include libs/CMakeLists.txt and build libs using toolchain provided by NDK
If you are trying to use non-ndk prebuilt library for your native component, then add those library details into CMake as mentioned below.
add_library( imported-lib
SHARED
IMPORTED )
set_target_properties( # Specifies the target library.
imported-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
imported-lib/src/${ANDROID_ABI}/libimported-lib.so )
https://developer.android.com/studio/projects/configure-cmake#add-other-library
For building native library using cmake system.
define CMakeLists.txt in your module(local source code to be used for generating lib).
add_library(xyz STATIC
folder-name/xyz.cpp)
target_include_directories(xyz PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/..)
define CMakeLists.txt in your android app module cpp folder.
cmake_minimum_required(VERSION 3.4.1)
/* using existing ndk lib , if you want you can remove this */
build native_app_glue as a static lib.
add_library(native_app_glue STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
Import the CMakeLists.txt for the glm library
add_subdirectory(glm)
/* require if u r adding header files location */
target_include_directories(game PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/data
${ANDROID_NDK}/sources/android/native_app_glue)
add lib dependencies
target_link_libraries(
native_app_glue
xyz
)
define app module build.gradle
android {
compileSdkVersion 28
defaultConfig {
applicationId 'com.google.sample.tunnel'
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName '1.0'
}
externalNativeBuild {
cmake {
version '3.10.2'
path 'src/main/cpp/CMakeLists.txt' // location of second(app module) CMakeLists.txt
}
}
}
Also check CMake build commands to verify what all parameters are used during build.
Check this file
app.externalNativeBuild\cmake\debug\x86\cmake_build_command.txt
So this is how it builds libcurl it does configure it 1st then compile using wrong toolchain. I did found something here https://developer.android.com/ndk/guides/other_build_systems but it does export for 1 toolchain per build. Mine is using 2 abi's
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
As you can see it's using ExternalProject_Add instead.
#-----------------------------------------------------------------
# Build bundled cURL library
#-----------------------------------------------------------------
if(BUNDLED_CURL AND (BUILD_CLIENT OR BUILD_SERVER))
ExternalProject_Add(
bundled_curl
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/curl
CONFIGURE_COMMAND ./configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/libs/curl
--enable-shared=no --enable-static=yes
--enable-http --enable-ftp --disable-file
--disable-ldap --disable-ldaps --disable-rtsp
--enable-proxy --disable-dict --disable-telnet
--disable-tftp --disable-pop3 --disable-imap
--disable-smb --disable-smtp --disable-gopher
--without-ssl --without-libssh2 --without-nghttp2
--without-gssapi --with-zlib
--disable-ares --enable-threaded-resolver
--enable-ipv6 --enable-unix-sockets
--without-libidn2 --disable-manual
--disable-sspi --enable-libgcc
--without-libmetalink --without-libpsl
--without-librtmp ${CROSS_COMPILE32_FLAGS}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libs/curl
BUILD_COMMAND make
INSTALL_COMMAND make install
BUILD_IN_SOURCE 1
)
set(CURL_BUNDLED_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/libs/curl/lib/libcurl.a")
set(CURL_BUNDLED_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/libs/curl/include")
endif()
Related
I'm trying to start a native app project with Android Studio and CMake on Windows 10, but I'm stuck at including libpng.
For starters it's the first time I've seen a CMakeLists.txt file. It took me a day to figure out target_link_libraries(native-activity ... png) could not be target_link_libraries(png native-activity ...) since all the error messages were about files not being created and commands failing due to missing requirements from the toolchain (why were the essential errors at the end of the list? not cool!).
After finally managing to include libpng in the project I now get a build error:
Error:Execution failed for task ':app:externalNativeBuildDebug'.
...
error: unknown target CPU 'armv5te'
CMake Error at scripts/genout.cmake:78 (message):
Failed to generate
C:/APP_PATH/app/libpng-1.6.28/build/scripts/symbols.out.tf1
ninja: build stopped: subcommand failed.
I've recursively grep'ed my project, .android, .AndroidStudio2.2 directories, as well as filenames, and found absolutely nothing with armv5te except for the genout.cmake. My abiFilters line is abiFilters 'x86'.
How do I build libpng to link to my native app? Also, in Android Studio it shows the project now includes the libpng source files (with no less than 9 projects dedicated to it!). Is there any way to remove it?
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
# build native_app_glue as a static lib
add_library(app-glue STATIC ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
set(png_src_dir ../../../../libpng-1.6.28)
set(PNG_STATIC ON)
add_subdirectory(${png_src_dir} ${png_src_dir}/build)
# now build app's shared lib
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14")
add_library(native-activity SHARED
main.cpp logger.cpp logger.h game.cpp game.h
shaders.cpp shaders.h assets.cpp assets.h)
target_include_directories(native-activity PRIVATE ${ANDROID_NDK}/sources/android/native_app_glue
C:/devlibs/include
${png_src_dir})
# add lib dependencies
target_link_libraries(native-activity app-glue android log EGL GLESv2 png)
I've managed libpng to work with android NDK app (CMake build system instead of Android.mk) as static library. I used libpng-android repackaging. Here are things I've done:
git clone https://github.com/julienr/libpng-android.git into ${YOUR_LIBS_FOLDER} (I used ${ANDROID_NDK_ROOT_DIRECTORY}/sources/android).
Add ${ANDROID_NDK_ROOT_DIRECTORY} (home/username/Android/sdk/ndk-bundle for me) to global $PATH variable which is needed for build script).
Build lib with ndk-build (there is ./build.sh for that in directory with lib). Library will be built for different ABI targets ( arm64-v8a, armeabi, x86_64 etc).
At this point you have library headers at ${YOUR_LIBS_FOLDER}/libpng-android/jni and libpng.a at ${YOUR_LIBS_FOLDER}/libpng-android/obj/local/${ANDROID_ABI}/, where ${ANDROID_ABI} is target platform.
Finally you could include lib at CMakeLists.txt. libpng requires zlib compression library so you need to link against it aswell (zlib is provided by android studio so just add -lz flag).
Here is related piece from my CMakeLists.txt:
add_library(libpng STATIC IMPORTED)
set_target_properties(libpng PROPERTIES IMPORTED_LOCATION
${YOUR_LIBS_FOLDER}/libpng-android/obj/local/${ANDROID_ABI}/libpng.a)
add_library(appManager SHARED src/main/cpp/appManager.cpp)
target_include_directories(appManager PRIVATE ${YOUR_LIBS_FOLDER}/libpng-android/jni/)
target_link_libraries(appManager
android
libpng
z)
Few things to note there:
${ANDROID_ABI} is a variable set by Android Studio build system.
Once again: you need to link against zlib, that is why we have libpng z instead of libpng in target_link_libraries.
With Android Studio 3.6, including libpng into your project is rather easy.
Download the latest sources from sourceforge and unpack the zip file.
In Android Studio, make sure you have NDK and CMake installed (in SDK Manager)
Create a new Android Library module, call it pngAndroid (I would recommend
to set the Package Name to org.libpng.libpng, same as MacOS). Keep it Java, and choose the min SDK that fits your app.
For this module, choose File/Link C++ Project with Gradle. Find CMakleLists.txt of libpng that you downloaded as step 1.
In the pngAndroid's build.gradle, add
android.defaultConfig.externalNativeBuild.cmake.targets "png_static"
In Project Structure dialog, specify module dependency between your Module and pngAndroid.
When you build the pngAndroid Module, you will see files libpng16d.a in build/intermediates/cmake/debug/obj directory under pngAndroid.
In your Module, you also have CMakleLists.txt. In this script, you have a target, e.g.
add_library(native-library SHARED …
You should add libpng as dependency of native-library:
target_link_libraries(native-library libpng)
Elsewhere in this CMakleLists.txt you should define the imported libpng:
add_library(libpng STATIC IMPORTED)
set_target_properties(libpng PROPERTIES IMPORTED_LOCATION
../pngAndroid/build/intermediates/cmake/debug/obj/${ANDROID_ABI}/libpng16d.a)
set_target_properties(libpng PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
../../lpng1637)
set_target_properties(libpng PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES
z)
Note that here I used relative paths a) to the pngAndroid Module that you added to your Android Studio project, and b) to the libpng sources that you downloaded. In your setup, the relative paths may be different.
For completeness, here is a cleaned-up build.gradle script for pngAndroid to build shared library libpng16d.so:
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
arguments "-DSKIP_INSTALL_ALL=YES"
targets "png"
}
}
}
externalNativeBuild {
cmake {
path file('../../lpng1637/CMakeLists.txt')
}
}
}
When you build the module, you get in build/outputs an aar file that contains the jni directory with armeabi-v7a/libpng16d.so and all other ABI variants.
Last, it's worth mentioning that Google is working on an easier native package manager. Unfortunately, it's still not released.
I am trying to integrate the Hyperledger indy SDK. However, when running my code I get the error
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: dlopen failed: library "libgnustl_shared.so" not found
at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
at java.lang.System.loadLibrary(System.java:1657)
I am trying to follow the documentation provided in the project repo. I tried using the sample project on this blog .
I was able to build the *.so libraries under a linux virtual machine, the copied the built files in my android studio project on windows.
I added the files inside my project's jniLibs forlder for each architecture.
Added the code to load the library inside my mainActivity
static{
System.loadLibrary("indy");
}
Tried creating a CMake file
cmake_minimum_required(VERSION 3.4.1)
add_library(indy SHARED IMPORTED)
include_directories(src/main/jniLibs/${ANDROID_ABI}/include)
My gradle file includes:
android{
defaultconfig{
...
ndk{
moduleName "indy"
abiFilters 'armeabi-v7a'
}
}
...
sourceSets {
main {
jniLibs.srcDir 'src/main/jniLibs'
}
}
externalNativeBuild {
cmake {
path file('../CMakeLists.txt')
}
}
}
Still, keep on getting the same error when I launch the app.
I am aware that the bash script that builds the libraries on linux uses the android-ndk-r16b-linux-x86_64 tools so I tried downgrading my ndk in android studio to use the same version but had no luck.
The output of the build script is
include/
indy_anoncreds.h
indy_core.h
...
lib/
libindy.a
libindy.so
libindy_shared.so
How can I use this libraries in my android studio project?
The issue is mainly related to the nature of libraries. Libraries are dynamic in Android and needs to be linked at runtime.
libindy.so depends on stl, openssl, libsodium and libzmq.
You will find libgnustl_shared.so in NDK.
All the other needed prebuilt libraries are also available here.
What you need to do is make sure these libraries are present in the jniLibs folder and load these in order libraries before libindy.
System.loadLibrary("libgnustl_shared");
.
.
System.loadLibrary("indy");
Alternate approach:
There is a subproject in Indy where we are using libindy as dependency and we try to create a one fat dynamic library which has all the dependencies.
Link
If you follow the steps like vcx you dont have to have all the defendant l libraries in jniLibs as they will be already part of final .so file
The command which make one fat dynamic library with all the symbols and dependencies is this (from the link pasted above)
${LIBVCX}/target/${CROSS_COMPILE}/release/libvcx.a \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/libz.so \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/libm.a \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/liblog.so \
${LIBINDY_DIR}/libindy.a \
${TOOLCHAIN_DIR}/${CROSS_COMPILE_DIR}/${NDK_LIB_DIR}/libgnustl_shared.so \
${OPENSSL_DIR}/lib/libssl.a \
${OPENSSL_DIR}/lib/libcrypto.a \
${SODIUM_LIB_DIR}/libsodium.a \
${LIBZMQ_LIB_DIR}/libzmq.a \
${TOOLCHAIN_DIR}/${CROSS_COMPILE_DIR}/${NDK_LIB_DIR}/libgnustl_shared.so -Wl,--no-whole-archive -z muldefs
I want to implement AEs and RSA in my project.i downloaded pre built openssl and included in my project. After including openssl in my project i am getting error as above mentioned.i searched on SO some answers mentioned to include set_target_properties in CMake(U can check my cmake below) but still no use.
My CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# 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 them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
add_library(openssl SHARED IMPORTED)
set_target_properties (openssl PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/lib/libcrypto.so )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
include_directories(jni/include/)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/lib/libcrypto.a
${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/lib/libssl.a
# Links the target library to the log library
# included in the NDK.
${log-lib} )
and My build.graddle is here
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.manvish.prebuiltcrypto"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
abiFilters "x86_64", "armeabi-v7a"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
help me to resolve this issue?
The complete error log is here
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:externalNativeBuildDebug'.
> Build command failed.
Error while executing process /home/manvish/Android/Sdk/cmake/3.6.4111459/bin/cmake with arguments {--build /home/manvish/Gajanand/PrebuiltCrypto/app/.externalNativeBuild/cmake/debug/armeabi-v7a --target native-lib}
ninja: error: '../../../../jniLibs/armeabi-v7a/lib/libcrypto.a', needed by '../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so', missing and no known rule to make it
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
* Get more help at https://help.gradle.org
BUILD FAILED in 2s
I can guess that you get the cited error because you don't have jniLibs/x86_64/lib/libcrypto.a. Try to use
abiFilters "x86", "armeabi-v7a"
This error happend to me when upgrade targetSDKversion from 21 to 27. The last change of this horrible stage of my life as a Android programmer was this error:
What went wrong:
Execution failed for task ':myProject:externalNativeBuildDebug'.
Build command failed.
Error while executing process C:\Users\myUser\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build D:\workspaces\android\myProject.externalNativeBuild\cmake\debug\armeabi-v7a --target myProject}
ninja: error: '../../../../src/main/libs/armeabi-v7a/libcrypto.so', needed by '../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libmyProject.so', missing and no known rule to make it
My app uses a own .so which uses funcions of libcrypto.so inside him, for that reason appers myproject.so
Change the old path for the new one, for that, you need to go to External Build Files/CMakeLists.txt in Android Studio (if dont appers in your Android Studio interface, go to your FileSystem and search it inside your project, and compile after realize this change).
If doens't exists, add set_target_properties:
set_target_properties( # Specifies the target library.
crypto-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libcrypto.so )
To:
set_target_properties( # Specifies the target library.
crypto-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libcrypto.so )
Now, build the project and run the app.
Thing related:
Dont need to add crypto statically (is libcrypto, but his name is crypto).
System.loadLibrary("crypto");
Related info:
Description of Android.mk
Port to BoringSSl (no need to me to work the app)
I hope this help!
In Android NDK old version, we include GLES like this:
LOCAL_LDLIBS += -lGLESv1_CM
But in newest version, Android uses CMakeLists instead of Android.mk with the same purpose. So how to add GLES/GLES2/GLES3 dependency to CMakeList file? Thank you!
The difference between the gradle scripting ndk module and cmakelist external tool is the way to define your script. In this case,
you need to create your CMake script (CMakeLists.txt, and change your gradle file to activate the external tool):
CMakelists:
cmake_minimum_required(VERSION 3.4.1)
# now build app's shared lib
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
add_library(gljni SHARED
your_code.cpp)
# add lib dependencies
target_link_libraries(gljni
android
log
EGL
GLESv2) #here you can put your opengl linking library.
The command target_link_libraries specifies the libraries that they are going to be linked.
In the gradle file you need to specify the external native build, adding cmake options such as compiler, android native version etc.
externalNativeBuild {
cmake {
// Available argumetns are inside ${SDK}/cmake/.../android.toolchain.cmake file
arguments '-DANDROID_PLATFORM=android-9',
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
}
}
Hope this helps.
Cheers
Unai.
I use Android Studio 2.2's cmake to build native code, in the native code I invoked the ffmpeg api, so the ffmpeg library should be packaged. My CMakelists.txt is as below:
cmake_minimum_required(VERSION 3.4.1)
include_directories(libs/arm/include)
link_directories(libs/arm/lib/)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# Associated headers in the same location as their source
# file are automatically included.
src/main/cpp/native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
add_library(avcodec-57 SHARED IMPORTED)
set_target_properties(avcodec-57 PROPERTIES IMPORTED_LOCATION C:/Users/tony/Desktop/MyApplication/app/libs/arm/lib/libavcodec-57.so)
target_link_libraries(native-lib avcodec-57)
target_link_libraries(native-lib avformat-57)
target_link_libraries(native-lib avutil-55)
target_link_libraries(native-lib avfilter-6)
In such case, I can make project successfully, but when I install the apk to emulator and run, it failed and show that "libavcodec-57.so" isn't found.
Then I use tool (analyze apk) to check the apk, found that the ffmpeg library isn't packaged.
I found a way that works for me, not sure it helps you but it might. I'm using Android Studio 2.2, and ran into your problem too.
I created a jar-file, with the prebuilt libraries in it:
lib
--|armeabi
--|--|libMyLIb.so
etc.
by simply creating a folder lib with that contents somewhere, and the executing the command
zip -r myjar.zip lib && mv myjar.zip myjar.jar
Next, I put the jar file in here:
app/libs/myjar.jar
And added these lines to the CMakeLists.txt that builds a native .so-library inside Android Studio. That is, I started with an empty project off the template for calls to native code (the default libnative-lib.so):
# already there:
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
# my addition:
add_custom_command(TARGET native-lib POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs"
$<TARGET_FILE_DIR:native-lib>)
And magically, now if I build the apk, the contents of my jar end up in the final apk. Don't ask me why this works, really, I have no clue, it was accidental.
What this means for me, is that I compile the empty libnative-lib.so, for the only purpose of tricking Android Studio into including my jar.
Perhaps someone finds a cleaner solution, and can point out where my solution is a ridiculous loop that resulted out of misunderstanding gradle and cmake...
I had the exact same problem.
Cmake does not automatically pack third library into the apk , you have to do it yourself.
Here is an exemple with libavcodec and libavutil from ffmpeg.
1- Copy your pre-built lib into app/libs/[abi]/
Exemple : app/libs/armeabi-v7a/libavcodec.so
2- Copy include into app/libs/include
Then in your cmakelist.txt add the libraries you need
find_library( log-lib log )
set(ffmpeg_DIR ../../../../libs) #set path to libs folder
add_library( libavutil SHARED IMPORTED )
set_target_properties( libavutil PROPERTIES IMPORTED_LOCATION ${ffmpeg_DIR}/${ANDROID_ABI}/libavutil.so )
add_library( libavcodec SHARED IMPORTED )
set_target_properties( libavcodec PROPERTIES IMPORTED_LOCATION ${ffmpeg_DIR}/${ANDROID_ABI}/libavcodec.so )
include_directories(libs/include) #add include dir. don't know why ../ not needed
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
target_link_libraries( native-lib libavcodec libavutil ${log-lib} )
Finally in your build.gradle set jniLibsfolder :
sourceSets.main {
jniLibs.srcDirs = ['libs']
}
Setting jniLibs.srcDir was the key for me to be able to bundle the libs into the apk.
Note that i used libs folder but you can probably use any folder you want to store your pre-built libs.
Found a working sample on github (not mine) : https://github.com/imchenjianneng/StudyTestCase
I suffered the same problem.
Gradle doesn't packaging .so files into apk while I filled CMakeLists.txt correctly, but finally I resolved it.
Add the JniLibs path into sourceSets in local build.gradle as this sample code:
https://github.com/googlesamples/android-ndk/blob/master/hello-libs/app/build.gradle
which is #Gerry mentioned in the comment.
I did:
copy .so libraries into src/main/JniLibs/${ANDROID_ABI}.
ex) mobile/src/main/JniLibs/armeabi-v7a/libavcodec.so
edit CMakeLists.txt
CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
# project path (absolute), change it to yours.
set(projectDir C:/Users/Administrator/AndroidStudioProjects/TestApp1)
# headers
include_directories(${projectDir}/mobile/src/main/JniLibs/${ANDROID_ABI}/include)
# sample ndk lib
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
# FFMPEG libraries
add_library( lib_avcodec SHARED IMPORTED )
set_target_properties( lib_avcodec PROPERTIES IMPORTED_LOCATION ${projectDir}/mobile/src/main/JniLibs/${ANDROID_ABI}/libavcodec.so)
# ...
# (omitted) same codes with lib_avdevice, lib_avfilter, lib_avformat, lib_avutil, lib_swresample, and lib_swscale each.
# ...
target_link_libraries( # Specifies the target library.
native-lib
lib_avcodec
lib_avdevice
lib_avfilter
lib_avformat
lib_avutil
lib_swresample
lib_swscale
)
in build.gradle (app)
build.gradle
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "your-application-Id"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
}
}
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'armeabi', 'armeabi-v7a'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
# ADD THIS BLOCK.
sourceSets {
main {
// let gradle pack the shared library into apk
jniLibs.srcDirs = ['src/main/JniLibs']
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
productFlavors {
}
}
hope it helps you.
p.s. I used FFMPEG libraries that built myself.