I'm trying to use tcdrain function call defined in termios.h by compiling my c code with the android ndk.
I'm having issues because when I build the newest android ndk, tcdrain is not defined in termios.h, however if I go inside the android source code it is defined in termios.h for bionic.
For example: https://github.com/android/platform_bionic/blob/master/libc/include/termios.h#L44
But when I build the ndk, it seems to have a different termios.h file in sysroot/usr/include/termios.h?
Why would the newest ndk not have the same include files as the newest bionic/libc files?
The source code you linked states that those functions are defined only if the following holds
#if __ANDROID_API__ >= 21
so, as nayuta said you will have tcdrain only with build environment configured with --platform=android21.
If you can not use plafform android21, you may still define yourself the functions you need.
In case of tcdrain a possible replacement would be
#define tcdrain(fd) ioctl(fd, TCSBRK, 1)
Did you configure your build environment with --platform=android21 or later?
Before android 5.0, api level 20 and older, function declarations is replaced with android/legacy_termios_inlines. h.
If you configure for android 5.0 or later, you can use tcdrain.
Related
I have an App that uses a library with native libs and now in Android 11 is crashing due to fdsan.
I have contacted the library providers, but they are not going to deliver a new version of the library with this issue solved, so I need to be able to somehow disable fdsan.
I think the solution would be to call when I am on Android 11 or higher:
if(android_get_device_api_level()>=30)
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
But I am unable to compile because of error:
use of undeclared identifier 'android_fdsan_set_error_level'
Because this was only added in Android 10 (API 29)
So my question is how can I call this function in my project?
I am creating a specific cpp file for this and a specific library for this, so I would need to some how for this library say that it is only for Android 10 or higher.
Is there some definition in the cpp file or in the Android.mk file that I can use to be able to compile this specific library that I will invoke from Java in Android 11 or higher only when my App starts?
According to the documentation here you should do it like this:
if (android_fdsan_set_error_level) {
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
}
You will have to set your target SDK to 10 or above for this to work.
Alternatively, if you are compiling this in to a separate native binary, you can use conditional compilation.
Include this file.
Then do something like this:
#if __ANDROID_API__ >= __ANDROID_API_P__
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
#endif
Just make sure this binary is never loaded on older devices, else the linker will give an error.
Depending on how your whole project is built, you may need to ship a separate APK for this in a bundle.
Finally, if all else fails, you may try using dlopen and dlsym to load the function dynamically at runtime, but you will need to find out which module exactly it is included in.
I tried to compile a .so library using Visual Studio 2019 along with OpenCV Android in order to use this library in Unity.
There are some answers on how to configure Visual Studio to use OpenCV Android (here or here) but none of these work for me. Below you can see my configurations.
Visual Studio 2019 (running on Windows 10)
android-ndk-r21e // also tried with android-ndk-r15c android-ndk-r16b and android-ndk-r17c
OpenCV Android 4.5.2 // also tried with OpenCV Android 4.0.0, 4.0.1 and 4.1.0
My settings in Visual Studio 2019 look as follows:
Configuration Properties
- General
Platform Toolset Clang 5.0 (also tried Clang 3.8 or GCC 4.9)
Configuration Type Dynamic Library (.so)
Target API Level Nougat 7.0 (android-24) (also tried different versions)
Use STL LLVM libc++ static library (c++_static) (also tried "GNU STL static library (gnustl_static)")
C/C++
- General
Additional Include Directories "Path to OpenCV_4_5_2_Android\sdk\native\jni\include"
Code Generation Enable C++ Exceptions "Yes(-fexceptions)"
Language C++17(-std=c++1z)
Precompiled Headers Not using Precompiled Headers
Linker
- General
Additional Library Directories Path to OpenCV_4_5_2_Android\sdk\native\libs\armeabi-v7a
- Input
Additional Dependencies Path to OpenCV_4_5_2_Android\sdk\native\libs\armeabi-v7a\libopencv_java4.so
My Source.cpp I try to compile is just a single function for testing purposes
#include <opencv2/core.hpp>
extern "C" float test(float a, float b)
{float c = a * b; return c;}
Which gives me the following errors:
E0035 #error directive: This constructor has not been ported to this platform
E0020 identifier "__fp16" is undefined
use of undeclared identifier 'ANDROID_LOG_INFO'
The ANDROID_LOG_INFO error can be fixed when I add #include "android/log.h" at the top of the file that throws this error. But the other two errors still remain.
I had the exact same issue as you (though I used c++ 11) with the exact same setup, and struggled for days. I believe the errors you're seeing (like me) are from arm_neon.h. Very oddly, I was able to just build (not run) the .so successfully, even with those errors (I say "errors" because if you look at arm_neon.h, others pop up), so try it. Maybe it's some kind of IntelliJ/Intellisense mistake more than anything else where it's catching false negatives from some other toolchain setup.
At the same time, I'm not 100% sure I was always able to build with that issue, so try these steps as well if you can't:
use OpenCV 4.0.1 with Android NDK 16rb. The NDK matters when it comes to OpenCV builds, and this is the only supposed match that I know of.
follow this tutorial from scratch: https://amin-ahmadi.com/2019/06/03/how-to-use-opencv-in-unity-for-android/
if the downloaded OpenCV android SDK is still giving trouble, build OpenCV from the source using his other tutorial here: https://amin-ahmadi.com/2019/02/03/how-to-build-opencv-4-x-for-native-android-development/
and then repeat step 2.
MAJOR EDIT:
OpenCV 4.5.2 needs to be treated differently because it no longer uses toolchains with gnu c++.
-When you build OpenCV from CMake, build with Android NDK 21e, and do not use the toolchain in OpenCV 4.5.2. Use the one inside the Android NDK's build folder (android-ndk-r21e\build\cmake).
-When you build your .so from Visual Studio 2019, do not use the GNU STL, use the LLVM. GNU c++ is no longer part of Android NDKs, and you need to cut it out of the process entirely.
-In the Linker Input, put the names of your library files (or file, if it's just the world one) in the Library Dependencies field, not the Additional Dependencies field.
-Everything else is the same as in those common tutorials.
I'm porting C++ code to Android that references _swab.
While there are related header files in Android NDK r15c (swab.h, swab.h), none provides a signature for swab() or _swab().
What is a good workaround?
Looks like Android does have it, but not until android-28: https://android.googlesource.com/platform/bionic/+/1eb5976d7505f299754040e19792a0de94abccbc/libc/include/unistd.h#318
Here's a change to add an inline for backporting to old releases: https://android-review.googlesource.com/c/platform/bionic/+/984334. Not merged into any NDK yet. Until it is, you can paste that function into your code to get moving. Once that ships and you've upgraded to an NDK that contains it you can delete it again.
Android ndk r15c compiled node.js error: 'to_string' is not a member
of 'std'
I use the (doc) method to build using ndk, this problem has occurred, after google After searching and issues, I got the message android-ndk uses gnustl cpp lib by default which doesn't include some functions (std::to_string) in particular., then I put the common.gypi file inside The gnu++1y was changed to c++11 and it still didn't work.
In file included from ../deps/v8/src/torque/ast-generator.h:9:0,
from ../deps/v8/src/torque/ast-generator.cc:8:
../deps/v8/src/torque/ast.h: In member function 'std::string'
then I put the common.gypi file inside The gnu++1y was changed to c++11 and it still didn't work.
That flag controls your C++ standard version, not your STL.
If you update to r17/r18 you'll get libc++ by default. Otherwise:
https://github.com/nodejs/node/blob/master/android-configure#L43
You need to add --stl=libc++ to that command. I'd strongly recommend updating to r16 at least though, since libc++ wasn't really ready for production use until then.
I'm working on an Android app that has heavy use of the NDK. On the Java side of things, we target SDK 19 with a min SDK of 16. Is there a way to do something similar on the NDK side?
Right now our Application.mk file has APP_PLATFORM := android-16. Is there a way to target platform 19 but still have compatibility back to 16 on the NDK side?
It's doable, but it is not too easy.
For the java code, as you know, you can set any higher target SDK version and use such features, as long as you make sure that those codepaths only are executed on the newer devices - simple.
For the native code, you can in principle set a higher APP_PLATFORM than your baseline, and try to do the same, but there's a few details you need to keep track of:
You can't unconditionally link to functions from the newer platform, you need to load them dynamically. That is, instead of calling functions directly and adding the libraries to LOCAL_LDLIBS, you need to load the functions via dlopen and dlsym instead, to make sure that the binary is loadable on the older versions. (Or alternatively, you can build separate shared libraries, where one shared library can be loaded on all platform, while another one only can be loaded on newer platforms.)
Some bionic libc functions have changed (mainly in android-21, but some minor ones also changed before that) - functions that did exist before but have changed symbol name. One of the more common functions that has changed is rand - prior to android-21, rand was an inline function that actually called lrand48(), so your binary ended up depending on lrand48 which existed in the older android versions' libc.so, while they didn't have any rand there. In android-21, a lot of such functions have been added, and the inline functions removed, so if you build with APP_PLATFORM := android-21, your binary will end up depending on the function rand which didn't exist before. See https://stackoverflow.com/a/27093163/3115956 and https://stackoverflow.com/a/27338365/3115956 for more details about this.
Keep in mind that you don't need to set APP_PLATFORM to the same as the target SDK on the java side, you only (may) need to set it if you want to selectively use newer features on newer firmware versions.
Due to the second issue you might not want to set a higher APP_PLATFORM at all. If you use dlopen (so you don't actually need the .so files to link against), you can manage pretty easily by copying those new headers from the newer platform version into your own project, and building with the older APP_PLATFORM.
Take a look at https://developer.android.com/ndk/guides/stable_apis.html
For example, if you don't use OpenGL ES 3.0 and OpenGL ES 3.1 APIs and don't link libGLESv3, then your app has compatibility to API level 14.