Implementing baresip NDK library causes lack of *.so file - android

I want to implement baresip lib into my Android project using NDK.
I've found up-to-date "bare bones" demo-project in HERE. As in readme I've created some native libs from another repo and placed in "distribution" folder. Project is compiling, installing, working fine. Comparing to Android native sip implementation this lib is just awesome, use it, forget about permission.USE_SIP, its rubish.
Now I want to import baresip into my project, but without Java/Kotlin files, planning to build own. So my steps:
Added externalNativeBuild entries to build.gradle
Copied cpp and distribution folders to proper places in my structure
Invalidate cache and restart
And got exception:
Build command failed.
Error while executing process C:\Android\sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build C:\Android\projects\MyApplication\app.cxx\cmake\debug\armeabi-v7a --target baresip}
[1/2] Building C object CMakeFiles/baresip.dir/baresip.c.o
[2/2] Linking C shared library C:\Android\projects\MyApplication\app\build\intermediates\cmake\debug\obj\armeabi-v7a\libbaresip.so
FAILED: cmd.exe /C "..."
next some duplicated lines like:
src/video.c:331: error: undefined reference to 'atof'
src/main/main.c:944: error: undefined reference to 'signal'
src/main/main.c:775: error: undefined reference to '__FD_ISSET_chk'
src/main/main.c:690: error: undefined reference to '__FD_SET_chk'
C:/Android/projects/MyApplication/app/src/main/cpp/../../../../distribution/openssl/lib/armeabi-v7a/libcrypto.a(armcap.o):armcap.c:function OPENSSL_cpuid_setup: error: undefined reference to 'sigfillset'
and ends with
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
note app/src/main/cpp/../../../../distribution/ files path, as declared in CMakeLists:
set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../distribution)
For me it looks like not-visible files for compiler, but when I add/remove some/any ../ error changes to clearly suggesting wrong path. besides same path and hierarchy is in sample project
I've tried to strip out baresip.c file, but its crashing with just logging OnLoad call...
#include <string.h>
#include <pthread.h>
#include <jni.h>
#include <android/log.h>
#include <stdlib.h>
#include <re.h>
#include <baresip.h>
#define LOGD(...) \
if (log_level_get() < LEVEL_INFO) ((void)__android_log_print(ANDROID_LOG_DEBUG, "Baresip Lib", __VA_ARGS__))
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
LOGD("at JNI_OnLoad\n");
return JNI_VERSION_1_6;
}
crash still occurs, but when I comment out if (log_level_get() < LEVEL_INFO) call my project is building and install just fine... log_level_get() comes from baresip.h, which is #included, libbaresip.a files (per abi) present, so why is libbaresip.so missing, why it isn't generating? what lines are present in sample project which makes it to build and work?
(yep, I'm pretty weak in native, lost some support from colleagues due to coronavirus...)

turns out it was a bit hidden, but nothing tough... target/compile SDK version should be at least 21 for this lib, I had 19, thats why ndk wasn't compiling properly...

Related

Linking to a shared object library (.so) when cross-compiling

I am trying to link my c-program to a shared object library (libfoo.so) using the ARM cross-compiler arm-linux-gnueabi-gcc. I am compiling on a Ubuntu system, and I want to run the program on an Android device. The compiling works, but when I try to run the program on my android device I get an error.
I've created a simple test program containing the following files:
foo.c:
#include <stdio.h>
void foo(void){ puts("Hello, I am a shared library"); }
foo.h:
#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif
main.c:
#include <stdio.h>
#include "foo.h"
int main(void)
{
puts("This is a shared library test...");
foo();
return 0;
}
I have then created the shared object library using:
arm-linux-gnueabi-gcc -c -fPIC foo.c
arm-linux-gnueabi-gcc -shared -o libfoo.so foo.o
I then compile my program using:
arm-linux-gnueabi-gcc -L/home/foo -o test main.c -lfoo
After uploading the test-program to the Android device using adb, I am not able to run it. Instead I get the error: /system/bin/sh: ./test: No such file or directory
I am in the right directory and the test-file is present, so I assume that it is the shared library that cannot be found. I've tried uploading libfoo.so to the android device as well (to the same path as specified when compiling), but it still doesn't work to run the program.
I've gotten it to work with a static library (foo.o) using arm-linux-gnueabi-gcc -static -o test main.c foo.o, but not with a shared library.
How do I properly link a shared library when cross-compiling, to make sure that the program can then run on an Android device?
The linker isn't able to dynamically link to the library.
Define LD_LIBRARY_PATH environment variable to include the library:
export LD_LIBRARY_PATH=/home/foo

OpenCV for Android: undefined reference to std::ios_base::Init::Init() while linking

I have seen the similar questions undefined reference to std::ios_base::Init::Init() and undefined reference to `std::ios_base::Init::Init()' but I'm not sure whether I have the same situation.
I'm configuring opencv for android 3.4.7 on Android Studio 3.5. I imported libs of opencv by editing CMakeList.txt and build.gradle:
set(opencv_version OpenCV3-android-sdk)
set(OpenCV_STATIC ON)
set(OpenCV_DIR /home/lynx/Android/Proj/${opencv_version}/sdk/native/jni)
find_package(OpenCV REQUIRED)
if (OpenCV_FOUND)
message(WARNING "opencv libs: ${OpenCV_LIBS}")
else (OpenCV_FOUND)
message(WARNING "opencv not found!")
endif(OpenCV_FOUND)
target_link_libraries(
${OpenCV_LIBS})
sourceSets {
main {
jniLibs.srcDirs = ['/home/lynx/Android/Proj/OpenCV3-android-sdk/sdk/native/libs']
}
}
and my native-lib.cpp is
#include <jni.h>
#include <string>
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_stitch_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from OpenCV " + (std::string)CV_VERSION;
return env->NewStringUTF(hello.c_str());
}
When building the project it shows many undefined reference errors from the file of opencv. It seems not the problem of linking cpp files with c linker: it called clang++ to do the task and when not using opencv, the project can be build successful.
So is it because that I didn't correctly configured opencv?
This is usually a case of using a library built against a different STL than you're using. I can't tell with the information you've given, but there are a lot of other questions on SO where people build their app with libc++ but build opencv with libstdc++. These are not compatible. See NDK - problems after GNUSTL has been removed from the NDK (revision r18).

undefined reference to `AImageReader_new'

CAMERA NDK
I add .h(#include <media/NdkImageReader.h>) to .cpp.
when compile project, the function from .h (#include <media/NdkImageReader.h>)undefined reference.
#include <media/NdkImageReader.h>
#include <media/NdkImage.h>
error:
CMakeFiles/native-camera2-lib.dir/native-camera2-lib.cpp.o: In function Java_com_example_ts_camerandk_NativeCamera_openCamera':
D:\AndroidStudioProjects\camerandk\app\src\main\jni\native-camera2-lib.cpp:(.text+0x348): undefined reference to AImageReader_new'
D:\AndroidStudioProjects\camerandk\app\src\main\jni\native-camera2-lib.cpp:(.text+0x378): undefined reference to AImageReader_setImageListener
CMakeFiles/native-camera2-lib.dir/native-camera2-lib.cpp.o: In function Java_com_example_ts_camerandk_NativeCamera_startPreview':
D:\AndroidStudioProjects\camerandk\app\src\main\jni\native-camera2-lib.cpp:(.text+0x6e4): undefined reference to AImageReader_getWindow
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
enter code here
Check your cmake target libraries line in CMakeLists.txt file. You are forgetting to include mediandk
target_link_libraries(... camera2ndk mediandk ...)
Media NDK is a different library, and is not a part of Camera or Camera2.

Include JNI header on Android Lib with Bazel

I'm trying to use JNI with Bazel (0.12.0):
WORKSPACE file:
android_ndk_repository(
name = "androidndk",
)
libs/hello_lib_c/BUILD:
cc_library(
name = "hello_lib_c",
srcs = ["src/hello.c"],
visibility = ["//visibility:public"],
)
libs/hello_lib_c/src/hello.c:
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_eu_tamere_bazel_HelloJNI_hello(JNIEnv *env, jclass clazz) {
return (*env)->NewStringUTF(env, "Hello from JNI ");
}
libs/hello_lib_java/BUILD:
android_library(
name = "hello_lib_java",
srcs = glob(["src/eu/tamere/bazel/**"]),
deps = ["//libs/hello_lib_c"],
visibility = ["//visibility:public"],
)
When building the Java lib, the jni.h header file is not found. Any idea on how to declare the dependency?
$ bazel build //libs/hello_lib_java
INFO: Analysed target //libs/hello_lib_java:hello_lib_java (22 packages loaded).
INFO: Found 1 target...
ERROR: /path/to/project/libs/hello_lib_c/BUILD:1:1: C++ compilation of rule '//libs/hello_lib_c:hello_lib_c' failed (Exit 1)
libs/hello_lib_c/src/hello.c:1:10: fatal error: jni.h: No such file or directory
#include <jni.h>
^~~~~~~
compilation terminated.
Target //libs/hello_lib_java:hello_lib_java failed to build
Use --verbose_failures to see the command lines of failed build steps.
I've tried to add hdrs = ["#androidndk//:jni_header"], to the cc_library definition but it does now work either. I've also tried to explicitly set the path for the Android NDK in the WORKSPACEbut it does not change.
The android example on the official repo does not specify where to find the jni lib.
It seems that using JNI inside an android_library (i.e., .aar) is not possible at the moment without some tricks. Only android_binary (i.e., .apk) will link the jni lib.
From https://github.com/bazelbuild/bazel/issues/348 :
android_library .aar output does not currently support bundling native libraries. This is a known deficiency that I believe #dkelmer has plans to work on.
aj-michael has a repo with a workaround:
https://github.com/aj-michael/aar_with_jni

Compiling 1 library with 2 sub-libraries with Android Studio's CMake and NDK

Working on an Android NDK project. The project is using CMake to build the C++ libraries.
The library has the following structue -
Main Library
main.cpp
CMakeLists.txt
hello (sub library)/
CMakeLists.txt
include/
hello.h
src/
hello.c
world (sub library)/
CMakeLists.txt
include/
world.h
src/
world.c
The contents are the following:
main.cpp
#include <jni.h>
#include <string>
#include <hello.h>
#include <world.h>
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_test_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string str = hello() + world();
return env->NewStringUTF(str.c_str());
}
CMakeLists.txt for main.cpp
cmake_minimum_required(VERSION 3.4.1)
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_subdirectory(src/main/cpp/hello)
include_directories(src/main/cpp/hello)
add_subdirectory(src/main/cpp/world)
include_directories(src/main/cpp/world)
target_link_libraries( # Specifies the target library.
native-lib
hello
world)
world.h
#include <string>
std::string world();
world.c
#include "world.h"
std::string world() {
return std::string("world");
}
CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (world)
add_definitions(/DVERSION="0.4.0")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")
include_directories(include/)
set(SOURCES
src/world.c
include/world.h
)
add_library(world STATIC IMPORTED
${SOURCES}
)
target_include_directories(world PUBLIC ./)
The content is the same for the "hello" library as the only difference is the output returned from hello's function.
Now, my experience with CMake is close to non-existent and I can't get this to work. I'm constantly getting errors upon building it. Latest error is the following -
CMake Error at src/main/cpp/hello/CMakeLists.txt:19
(target_include_directories): Cannot specify include directories for
imported target "hello". CMake Error at
src/main/cpp/world/CMakeLists.txt:19 (target_include_directories):
Cannot specify include directories for imported target "world".
I just can't find a way to compile all of it into a simple library that will be used in the app. Sometimes I get " not found", sometimes it can't find the header files and etc.
I'd appericiate if someone will be able to post a simple structure and CMake of the correct way of doing so as I'm lost.
In the actual project I try to use libmicrohttpd, but again, can't make it work. I've tried using CentOS's libraries but Android Studio seems to use the system's libraries which causes things to get messed up. This is the reason for which I download the library and try to compile it via Android Studio.
So, again, if anyone will be able to find a way to compile all of the 3 libraries together into a single library (main) which connected the other 2 (hello, world), I'd greatly appericiate it.
Much appericiated.

Categories

Resources