I want to compile my code for specific api level. for example api level 7. and I use ndk-8. is there any option for this ?
now I use ndk-build.cmd command in windows console to compile. and I dont know how can I know which api level is supported.
This doesn't appear to be well documented (even in the NDK docs), but if you have an Application.mk (same directory as your root Android.mk), if you have a line APP_PLATFORM := android-7 (or whatever platform version you desire), it will build to that. That isn't documented in the NDK docs for Application.mk. According to the docs, if you put a TARGET_PLATFORM line in the Android.mk, it will use that, but there appears to be information out that that doesn't work.
excellent reponse, thank you Carl, you saved my life.
I use "APP_PLATFORM := android-7" and it works. when I added this line, compiling gave me an error that a function is not implemented. then, I put its implementation in my code then it works!
I think newer android version has that function but android-7 has not.
the function is wcstombs (it is in stdlib)
and its implementation is
size_t wcstombs(register char *s, register const wchar_t *pwcs, size_t n){
register int i = n;
while (--i >= 0) {
if (!(*s++ = *pwcs++))
break;
}
return n - i - 1;
}
thanks
Related
I'm trying to add the 22.0.7026061 NDK to Qt creator, but this version does not contain the platforms folder. Qt creator uses the following code to check the validity of the NDK and as a result I cannot add the 22nd version. In addition, I did not find any clear explanation why this paltrforms does not exist.
bool AndroidConfig::isValidNdk(const QString &ndkLocation) const
{
auto ndkPath = Utils::FilePath::fromUserInput(ndkLocation);
const Utils::FilePath ndkPlatformsDir = ndkPath.pathAppended("platforms");
return ndkPath.exists() && ndkPath.pathAppended("toolchains").exists()
&& ndkPlatformsDir.exists() && !ndkPlatformsDir.toString().contains(' ')
&& !ndkVersion(ndkPath).isNull();
}
What can I do? I need exactly the 22nd version, the versions below are normally added.
From Changelog-r21:
The legacy toolchain install paths will be removed over the coming
releases. These paths have been obsolete since NDK r19 and take up a
considerable amount of space in the NDK. The paths being removed are:
platforms
sources/cxx-stl
sysroot
toolchains (with the exception of toolchains/llvm)
As for what you can do? I don't think much, you'll have to patch this part of Qt to use newer directories (e.g toolchains/llvm for platforms). You can also report this as a bug to Qt devs.
android.ndk {
moduleName = "hello-jni"
stl = "stlport_static"
CFlags.add("-std=iso9899:2011") // I have also used "-std=c11"
ldLibs.addAll(["android", "log"])
}
I still cannot see memset_s in jni C code. It says undefined reference.
In my c code i have also included string.h, stdlib.h, and stdio.h and also
#define STDC_WANT_LIB_EXT1 1
Still cannot get rid of the error undefined reference error.
If i add the flag Allow_Undefined_symbols it compiles but when ever i call the function memset_s it crashes.
The questions i would like to ask are as follows :
1) In which of the Android NDK tool chains can we get the C11 memset_s api?
2) The other question i have is how can we change the default tool chain for android in the latest android studio with experimental gradle alpha5?
This functionally of "Annex K" in the C11 standard is optional. It is not implemented in many C libraries.
You can test for conformance to Annex K by means of the macro __STDC_LIB_EXT1__.
I was not able to find any tool chain that supports C11 for NDK. So i have used a compliant solution for c99 from the following link:
https://www.securecoding.cert.org/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations
Which you can customize for your own purpose. I am adding this solution for any one in need.
I have created a shared object for Android in Visual Studio 2015.
It works fine so far, but pop_back() for a wstring does not work:
wstring element = "JustATest!";
if (element.back() == L'!')
{
element.pop_back();
}
VS2015 tells me:
"no member named 'pop_back' in 'std::basic_string<wchar_t>'".
Can anybody tell me how to get rid of this error?
I have no idea why this should not work.
Is that because for some reason VS2015 does not use C++11 here?
Thank you for the help!
Edit: Another error:
When I try to use _wtoi, VS tells me: "use of undeclared identifier '_wtoi'.
Very very strange.
You need to turn on STL support. Turn on STL with Configuration Properties -> General -> Use of STL. Good options are LLVM libc++ static library (fewer features, more compatible with CLANG) and GNU STL static library (more features, I had an issue that required me to turn the CLANG optimizer to -Oz to prevent a segfault).
The title says it all. I'm using NDK to build a native library for use with Unity (the game engine, not the Ubuntu shell). I already have much of the code in place and it works on my Xperia Z Ultra which runs Android 4.4.4. However, recently I sent the app to some other people to test on their phones, and it worked on none of their phones. They were using Android 4.0 and 4.1, so I tried running the app on my own Android 4.0.4 device (an old Xperia Mini Pro) and had the same problem. After much narrowing down, I've found out that the root of the problem is including OpenCV in the build, even if it's not referenced at all.
Here's the code I have now. First, the simplest CPP file you've seen:
//Test.cpp:
extern "C"
{
int Test(int a, int b)
{
return a + b;
}
}
Note how it doesn't even include anything from OpenCV. The makefile (or whatever it's called in the context of NDK, I'm mostly a Windows/Visual Studio person) is:
#Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#---------------------------
#note: if I comment these lines out, the library works just fine.
#if I don't, it won't load at all.
#---------------------------
OPENCV_PACKAGE_DIR := D:\Eclipse\OpenCVAndroid\OpenCV-2.4.9-android-sdk
include $(OPENCV_PACKAGE_DIR)/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := Test
LOCAL_SRC_FILES := Test.cpp
include $(BUILD_SHARED_LIBRARY)
Building this project gives me a "libTest.so" file. I put this into my Unity project, at Assets/Plugins/Android/ (I've also tried putting it in Plugins/Android/libs/armeabi-v7a/, no luck). I also have a script inside unity which invokes the library:
//TestNative.cs:
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class TestNative : MonoBehaviour
{
[DllImport("Test")]
public static extern int Test(int a, int b);
void OnGUI()
{
try
{
GUI.Label(new Rect(0, 0, 100, 100), "2 + 3 = " + Test(2, 3));
}
catch (System.Exception e)
{
GUI.Label(new Rect(0, 0, 600, 400), e.GetType().ToString() + " " + e.Message + "\n" + e.StackTrace);
}
}
}
When I run this on my Z Ultra, it works just fine. When I run it on the Mini Pro, it fails with the exception "DllNotFoundException: Test". I've checked logcat for errors, and this is what it says:
01-06 06:46:27.660: D/dalvikvm(11135): Trying to load lib /mnt/asec/com.cet.sna2-2/lib/libTest.so 0x2bb86638
01-06 06:46:27.660: D/dalvikvm(11135): Trying to load lib /mnt/asec/com.cet.sna2-2/lib/libTest.so 0x2bb86638
01-06 06:46:27.660: E/Unity(11135): Unable to find Test
It doesn't say anything else, it just fails. The fact that it works on 4.4.4 makes me think it might have something to do with build configurations or something like that, but I can't figure out what it is. Any ideas? Thanks.
I found out, after much trial and error, that the reason for the error is that Android somehow manages to mess the library dependencies up. The work-around is to manually load the libraries in the specific order of their dependencies, using LoadLibrary. This can be done in Unity using AndroidJavaClass to avoid having to write an entire jar library just for loading the native ones.
You have to build a .so that correspond to the architecture of the device your are using.
You should look at this link :
https://developer.nvidia.com/AndroidWorks
It provides useful tools to develop on Android with Visual Studio
You can easily configure an Android Dynamic Library (.so) that correspond to the architecture you need :)
Android/NDK project, worked with NDK versions all the way up to r8c. Under 8d and 8e, I get a compilation error message on the armeabi-v7a build:
Compile++ thumb : myproject <= MyFile.cpp
C:\cygwin\tmp\ccFXOc2F.s: Assembler messages:
C:\cygwin\tmp\ccFXOc2F.s:1935: Error: can't resolve `.data.rel.ro.local' {.data.rel.ro.local section} - `.LPIC44' {*UND* section}
The armeabi, MIPS, and x86 builds for the same project are successful.
It's reliably popping up on the same file. The file is nothing special - vanilla C++, it compiles and works on numerous other platforms (iOS, Windows, NDK r8c to name some). No STL. It does define a healthy amount of string constants though (AKA initialized read/only data). What could be going on?
Already tried a full rebuild, even deleted the obj folder altogether.
The C++ flags are:
LOCAL_CPPFLAGS := -fshort-wchar -fsigned-char -Wno-psabi
I know NDK comes with several versions of GCC; might a toolchain change help? How exactly?
Surely looks like a compiler bug to me. It's related to indexed access to a large chunk of static const data. When I've slightly reformulated a perfectly innocent statement, the error message went away.
Used to be:
//In global scope
static const LPCWSTR Comments[] = {L"A lot of strings here", L"String 2", L"String 3" /* and many more */ }:
void SomeMethod()
{
DoSomething(Comments[i]); //That was the offending line - commenting it out would get rid the error
}
Replaced with:
void SomeMethod()
{
static LPCWSTR pComments = 0;
if(!pComments)
pComments = Comments;
DoSomething(pComments[i]); //Now it works.
}
Ooky, spooky stuff.