Statically linking a library in Android Studio 3.x and CMake - android

First of all, this is my error.
Build command failed.
Error while executing process /Users/{user}/Library/Android/sdk/cmake/3.6.4111459/bin/cmake with arguments {--build /Users/{user}/Desktop/android/app/.externalNativeBuild/cmake/debug/arm64-v8a --target native-lib}
ninja: error: 'src/main/jniLibs/zlib/arm64-v8a/lib/libz.a', needed by '../../../../build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so', missing and no known rule to make it
I have a statically linked prebuilt zlib.a library for every ARCHs (armeabi, armeabi-v7a, arm64-v8a, x86, x86_64) and placed the library like this.
app/src/main/jniLibs/zlib/${ANDROID_ABI}/include/zlib.h
app/src/main/jniLibs/zlib/${ANDROID_ABI}/lib/libz.a
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
add_library(libz STATIC IMPORTED)
set_target_properties(libz PROPERTIES IMPORTED_LOCATION src/main/jniLibs/zlib/${ANDROID_ABI}/lib/libz.a)
include_directories(src/main/jniLibs/zlib/${ANDROID_ABI}/include)
find_library(log-lib log)
target_link_libraries(native-lib libz ${log-lib})
in a Java file,
static {
System.loadLibrary("libz");
System.loadLibrary("native-lib");
}
I don't have no idea about this issue. It seems okay. I don't touch build.gradle, should I? What am I missing? What is problem?

Property IMPORTED_LOCATION should be an absolute path.
Use ${CMAKE_CURRENT_SOURCE_DIR} for refer to the directory with currently processed CMakeLists.txt:
set_target_properties(libz PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/zlib/${ANDROID_ABI}/lib/libz.a)

Related

Compile with CMAKE and invalid sh_info in symbol table

sorry bad english
cloned and compiled this project in Android Studio:
https://github.com/Pangu-Immortal/KeepAlivePerfect/
During compile, got the following error (using ndk 24.0.8215888):
KeepAlivePerfect/library/src/main/cpp/binder_libs/armeabi-v7a/libbinder.so: invalid sh_info in symbol table
tested both in linux and windows. Same error.
plz help
Finally could compile with changing SHARED to STATIC in CMakeLists.txt. And some more config.
Here are the changes:
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
add_compile_options(-fno-rtti -O3 -v)
message(###${CMAKE_CURRENT_SOURCE_DIR})
link_directories(binder_libs/${CMAKE_ANDROID_ARCH_ABI})
aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library( # Sets the name of the library.
keep_alive
# Sets the library as a shared library.
STATIC # Changed from SHARED to STATIC
# 提供源文件的相对路径。
${SRC_LIST} main.cpp art.cpp)
# More Config
set_target_properties(keep_alive PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/binder_libs/${ANDROID_ABI}/libutils.so)
set_target_properties(keep_alive PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/binder_libs/${ANDROID_ABI}/libc.so)
set_target_properties(keep_alive PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/binder_libs/${ANDROID_ABI}/libcutils.so)
set_target_properties(keep_alive PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/binder_libs/${ANDROID_ABI}/libutils.so)
# The END
find_library(log-lib log)
target_link_libraries(
keep_alive
${log-lib}
)
More information in an issue in main project:
https://github.com/Pangu-Immortal/KeepAlivePerfect/issues/8#issuecomment-1107427875

Issue linking against POCO::Net::SocketAddress

I'm working on an Android native project where I'm using NDK + CMake to build a native solution based on POCO C++. I'm getting a super weird link error when I comment this line in my cpp file:
//std::ostream& o = session.sendRequest(request);
this is the link error:
../NetSSL_OpenSSL/src/SecureSocketImpl.cpp:381: error: undefined reference to 'Poco::Net::SocketAddress::~SocketAddress()'
But is even more weird that the file with the object where sendRequest is placed it is not being included in any other file. So, I have one isolated file (header and implementation) that is not being included in any other file (but it is build with CMake, I cannot remove it because of the issue) and if I comment one line of the implementation, it generates a link issue.
This is how I'm linking Poco:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_COMPILER_VERSION "5.0") # Unknown miss-detection of the compiler by CMake
find_library( # Defines the name of the path variable that stores the
# location of the NDK library.
log-lib
# Specifies the name of the NDK library that
# CMake needs to locate.
log )
add_library(PocoFoundation STATIC IMPORTED)
set_target_properties(PocoFoundation PROPERTIES IMPORTED_LOCATION
/Users/user/dev/poco-2/install/lib/libPocoFoundation.a)
add_library(PocoNet STATIC IMPORTED)
set_target_properties(PocoNet PROPERTIES IMPORTED_LOCATION
/Users/user/dev/poco-2/install/lib/libPocoNet.a)
add_library(PocoJSON STATIC IMPORTED)
set_target_properties(PocoJSON PROPERTIES IMPORTED_LOCATION
/Users/user/dev/poco-2/install/lib/libPocoJSON.a)
add_library(PocoNetSSL STATIC IMPORTED)
set_target_properties(PocoNetSSL PROPERTIES IMPORTED_LOCATION
/Users/user/dev/poco-2/install/lib/libPocoNetSSL.a)
add_library(PocoCrypto STATIC IMPORTED)
set_target_properties(PocoCrypto PROPERTIES IMPORTED_LOCATION
/Users/user/dev/poco-2/install/lib/libPocoCrypto.a)
add_library(PocoUtil STATIC IMPORTED)
set_target_properties(PocoUtil PROPERTIES IMPORTED_LOCATION
/Users/user/dev/poco-2/install/lib/libPocoUtil.a)
add_library(PocoXML STATIC IMPORTED)
set_target_properties(PocoXML PROPERTIES IMPORTED_LOCATION
/Users/user/dev/poco-2/install/lib/libPocoXML.a)
// ... SOURCES ...
target_include_directories(mylib PRIVATE /Users/user/dev/poco-2/install/include)
target_link_libraries(mylib
PocoNet
PocoNetSSL
PocoUtil
PocoJSON
PocoCrypto
PocoXML
PocoFoundation
Ssl
Crypto
${log-lib})
Also, I'm using Android Studio 3.6.2 with NDK version r19c. I have tried cleaning the build, rebuilding and cleaning .cxx, .gradle and build folder.
Any idea?
You need to recreate the inter-library dependencies such that CMake can construct the correct linker command line with dependencies after the libraries that depend on them.
Running through the libraries you listed, that should be at least the following (reconstructed from the Poco CMakeLists.txt).
target_link_libraries(PocoNet PocoFoundation)
target_link_libraries(PocoNetSSL PocoCrypto PocoUtil PocoNet)
target_link_libraries(PocoCrypto PocoFoundation Ssl Crypto)
target_link_libraries(PocoUtil PocoFoundation)
target_link_libraries(PocoJSON PocoFoundation)
target_link_libraries(PocoXML PocoFoundation)

CMake set target properties called with incorrect number of arguments

I'm trying to use OpenCV library in my project, but I get this error at runtime :
Build command failed. Error while executing process
D:\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments
{-HC:\Users\Mouad AITALI\AndroidStudioProjects\BGREMOVER\app
-BC:\Users\Mouad AITALI\AndroidStudioProjects\BGREMOVER\app.cxx\cmake\debug\arm64-v8a
-DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-16 -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=C:\Users\Mouad AITALI\AndroidStudioProjects\BGREMOVER\app\build\intermediates\cmake\debug\obj\arm64-v8a
-DCMAKE_BUILD_TYPE=Debug -DANDROID_NDK=D:\Sdk\ndk\19.2.5345600 -DCMAKE_CXX_FLAGS=-std=c++11 -DCMAKE_TOOLCHAIN_FILE=D:\Sdk\ndk\19.2.5345600\build\cmake\android.toolchain.cmake
-DCMAKE_MAKE_PROGRAM=D:\Sdk\cmake\3.6.4111459\bin\ninja.exe -GAndroid Gradle - Ninja}
-- Configuring incomplete, errors occurred! See also "C:/Users/Mouad AITALI/AndroidStudioProjects/BGREMOVER/app/.cxx/cmake/debug/arm64-v8a/CMakeFiles/CMakeOutput.log".
CMake Error at CMakeLists.txt:13 (set_target_properties):
set_target_properties called with incorrect number of arguments.
CMakeLists.txt
#declare folder path
set(pathToProject C:\\Users\\Mouad;AITALI\\AndroidStudioProjects\\BGREMOVER)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
include_directories(${pathToOpenCv}/sdk/native/jni/include)
#library location
add_library(lib_opencv SHARED IMPORTED)
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)
#define libraries
add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
add_library(grabcut SHARED src/main/cpp/jni-grabcut-lib.cpp src/main/cpp/grabcutter_p.cpp src/main/cpp/grabcutter_p.h)
find_library(log-lib log)
#target libraries
target_link_libraries(native-lib ${log-lib} lib_opencv)
target_link_libraries(grabcut ${log-lib} lib_opencv)
As commented, CMake uses the semicolon ; to define lists. So if the path contains semicolons, you must enclose the definition, and places where you use the variable pathToProject with double quotes:
set(pathToProject "C:\\Users\\Mouad;AITALI\\AndroidStudioProjects\\BGREMOVER")
...
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION "${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so")
The IMPORTED_LOCATION property only takes one value. So when you provide a list for that property, the set_target_properties() command cannot parse the arguments correctly, which yields the error.

Add headers and native library to Android project

I got some C code I have to integrate into my Android project. It depends on a library (.so), and I also have the .h files.
I copied the libs and include directories into the project's cpp package to make them easier to find.
To make it easier I tried starting with the HelloJNI project Android Studio offers and followed the instructions here.
This is the CMakeLists.txt:
#given from HelloJNI
cmake_minimum_required(VERSION 3.4.1)
add_library(hello-jni SHARED
hello-jni.c)
# Include libraries needed for hello-jni lib
target_link_libraries(hello-jni
android
log)
#my own additions now:
add_library( # Specifies the name of the library.
libgdndk
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
IMPORTED)
set_target_properties( # Specifies the target library.
libgdndk
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${CMAKE_BINARY_DIR}/libs/${ANDROID_ABI}/libgdndk.so )
include_directories(${CMAKE_BINARY_DIR}/inc/)
target_link_libraries( hello-jni libgdndk app-glue ${libgdndk} )
This results in an error:
ninja: error: 'libs/armeabi-v7a/libgdndk.so', needed by 'C:/workspace/android/HelloJNI/app/build/intermediates/cmake/arm7/debug/obj/armeabi-v7a/libhello-jni.so', missing and no known rule to make it
You seem to be linking your imported library to the hello-jni target twice. Also, using ${} in the target_link_libraries() command for the libgdndk library is not necessary. You have already defined a CMake target libgdndk for the library, so you can just do this:
target_link_libraries( hello-jni libgdndk app-glue )
I finally got some help from the publisher of the lib, the (working) result looks quite similar to the code i tried, so maybe it was just the location of the library that was at fault.
add_library( gdndk SHARED IMPORTED )
include_directories( $ENV{userprofile}/AppData/Local/Android/sdk/extras/blackberry/dynamics_sdk/sdk/libs/handheld/gd/inc)
set_target_properties(gdndk PROPERTIES IMPORTED_LOCATION $ENV{userprofile}/AppData/Local/Android/sdk/extras/blackberry/dynamics_sdk/sdk/libs/handheld/gd/libs/${ANDROID_ABI}/libgdndk.so )
target_link_libraries( hello-jni gdndk )

Unable to link libCurl.a static library in CMake on Android

I am new to CMake and spent almost 2 weeks searching all over the internet trying to figure out why I am unable to link libcurl static libraries with my cpp sources in Cmake within my android project.
I found this repo: https://github.com/gcesarmza/curl-android-ios that I used to generate my static libraries for libcurl. It has dependencies with openssl and libz ( I dont know what else it's built with)
Here's my cmake:
cmake_minimum_required(VERSION 3.4.1)
include_directories(
${EXTERNAL}/libCurl/include/
#${EXTERNAL}/openssl/include/
)
add_library(
libcurl
STATIC IMPORTED SHARED
)
set_target_properties(
libcurl
PROPERTIES IMPORTED_LOCATION
${EXTERNAL}/libcurl/lib/android/libcurl.a
)
add_library(
libz
STATIC IMPORTED
)
set_target_properties(
libz
PROPERTIES IMPORTED_LOCATION
${EXTERNAL}/zlib/lib/armeabi-v7a/libz.a
)
set(WHARE_LIBRARY Whare_Native)
add_library(
${WHARE_LIBRARY}
SHARED
${CPP_SOURCE}/MyWebRequest.cpp
)
target_link_libraries(
${WHARE_LIBRARY}
libcurl
libz
)
I have a simple cpp implementation that makes curl calls such as curl_easy_init(). I am getting the following linker error when I build the project with this CMake file:
[9/9] Linking CXX shared library
../../../../build/intermediates/cmake/debug/obj/arm64-
v8a/libWhare_Native.so
FAILED: : && /Users/jay.nagar/Library/Android/sdk/ndk-
bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --
target=aarch64-none-linux-android --gcc-
.........
.........
.........
.........
WhareWebRequest.cpp:40: undefined reference to `curl_easy_init'
clang++: error: linker command failed with exit code 1 (use -v to see
invocation)
ninja: build stopped: subcommand failed.
I have spent days on Stackoverflow , GitHub and other sources and also tried many solutions that have been suggested, such as:
How to use libcurl as a static library with cmake?
and
Linking static libraries with c++/cmake
I also looked up CMake official documentation to understand the different properties. I experimented with CFLAGS, CURL_LIBRARY, find_library and what not. Like I said, I am a total newbie when it comes to Cmake configurations. Can anyone make sense of the type of error I am getting? I think its related to issues linking with the static libs but I am not sure. Can someone help debug this problem that I am deep into for days!
Thanks and help much appreciated!
https://imgur.com/a/gLN9ctq
libcutils.so is a private system library and is no longer allowed to be linked by app since API level 24.
See this link
How to solve UnsatisfiedLinkError?
---- Edit ----
You need to specify the correct static lib path for each Android ABI using CMake variable ${ANDROID_ABI}.
Change below code
set_target_properties(
libcurl
PROPERTIES IMPORTED_LOCATION
${EXTERNAL}/libcurl/lib/android/libcurl.a
)
to
set_target_properties(
libcurl
PROPERTIES IMPORTED_LOCATION
${EXTERNAL}/libcurl/lib/android/${ANDROID_ABI}/libcurl.a
)
And ensure that you have all the needed architectures (ABI) of your libcurl.a, e.g. armeabi-v7a, arm64-v8a, x86, x86_64
The issue was with incorrectly generated libs for the libcurl static libraries. I found some prebuilt .a files here that worked for me: https://github.com/gcesarmza/curl-android-ios/tree/master/prebuilt-with-ssl/android
and
https://github.com/djp952/prebuilt-libz
It was just pure luck that I found something out of several prebuilt libs that just happened to work. I would be happier if I could generate those myself but in any case, at least I am not blocked :)

Categories

Resources