Android Lollipop native executable NDK 9 PIE executable support - android

Previously I've been using the following make file (or similar) to build a native app with the NDK (version r9d):
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= nativeApp.c
LOCAL_MODULE := nativeApp
LOCAL_STATIC_LIBRARIES := libcutils libc
LOCAL_SHARED_LIBRARIES:= libbinder liblog
include $(BUILD_EXECUTABLE)
However, Lollipop started enforcing that native applications were PIE. I've seen several solutions online and on S.O. and from that I've tried adding the following lines to address this issue:
APP_PLATFORM := android-16
LOCAL_CFLAGS += -fPIE
LOCAL_LDFLAGS += -fPIE -pie
It always builds fine but no matter what flags I use when I try to run it on the device I always get the PIE support error. I already have an environment set up around NDK r9d so I was trying to not have to go and change it but is that the only way to address this?

Related

Android can't include linux in C program with Android.mk

I'm trying to compile a C program for Android 6. This is my Android.mk:
APP_PLATFORM := android-23
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Enable PIE manually. Will get reset on $(CLEAR_VARS). This
# is what enabling PIE translates to behind the scenes.
LOCAL_CFLAGS += -fPIE -DHAVE_FANOTIFY=1 -DHAVE_SYS_FANOTIFY=0
LOCAL_LDFLAGS += -fPIE -pie
# give module name
LOCAL_MODULE := fsmon
# list your C files to compile
LOCAL_SRC_FILES := inotify.c fanotify.c util.c main.c
# this option will build executables instead of building library for android application.
include $(BUILD_EXECUTABLE)
In the fanotify.c following include is written:
#include <linux/fanotify.h>
When I try to use ndk-build, following error appears:
fsmon/jni/fanotify.c:51:10: fatal error: 'linux/fanotify.h' file not found
#include <linux/fanotify.h>
^
The header fanotify.h is present in the ndk path /Android/Sdk/ndk-bundle/sysroot/usr/include/linux
Any suggestions?
EDIT: Same error if I try to include sys/fanotify.h
You can specify additional include paths for your module using LOCAL_C_INCLUDES.
LOCAL_C_INCLUDES := /Android/Sdk/ndk-bundle/sysroot/usr/include/
https://developer.android.com/ndk/guides/android_mk.html#mdv
The NDK historically didn't backport headers to old releases, but we've reworked things in r14 so this is possible: https://android.googlesource.com/platform/ndk/+/ndk-r14-release/docs/UnifiedHeaders.md
By default in r14 you still get the old form of the headers. The new "unified headers" have the headers you're looking for. If you want to try unified headers, set APP_UNIFIED_HEADERS := true in your Application.mk (settings for other build systems can be found in the link above).
In r15 (first beta due out soon), the default has changed to the new headers, and the option for disabling them has changed (see the same doc in r15 for changes in options: https://android.googlesource.com/platform/ndk/+/ndk-r15-release/docs/UnifiedHeaders.md).

Android NDK: Module MediaEncoder depends on undefined modules: cutils gnustl dl

I covert a ADT project to Android Studio. however, i kept getting the error when building this project:
Error:(687) Android NDK: Module MediaEncoder depends on undefined modules: cutils gnustl dl
This is what is in the Android.mk. I am new to NTK, anybody can advise the issue here?
# building application library
#
include $(CLEAR_VARS)
LOCAL_MODULE := libMediaEncoder
LOCAL_CPP_EXTENSION := .cc .cpp
LOCAL_CPPFLAGS := -O2 -Werror -Wall
LOCAL_C_INCLUDES := $(MY_LOCAL_PATH)
LOCAL_SRC_FILES := main_jni.cpp \
h264encoder.cpp \
g72x/g726_32.c \
g72x/g711.c \
g72x/g72x.c
LOCAL_LDLIBS += -llog -lz
LOCAL_SHARED_LIBRARIES := libcutils\
libgnustl\
libdl
I believe that you use a project that was configured to be built in the context of AOSP build, not by NDK. But it could still work with a very old version of NDK.
The current version, r14 which is integrated into Android Studio 2.3, requires some changes to Android.mk.
include $(CLEAR_VARS)
LOCAL_MODULE := libMediaEncoder
LOCAL_CPPFLAGS := -O2 -Werror -Wall
LOCAL_C_INCLUDES := $(MY_LOCAL_PATH)
LOCAL_SRC_FILES := main_jni.cpp \
h264encoder.cpp \
g72x/g726_32.c \
g72x/g711.c \
g72x/g72x.c
LOCAL_LDLIBS += -llog -lz -ldl
LOCAL_SHARED_LIBRARIES := libcutils_prebuilt
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libcutils_prebuilt
LOCAL_SRC_FILES := {full-path-to}/libcutils.so
include $(PREBUILT_SHARED_LIBRARY)
To resolve the dependency on gnustl, run ndk-build APP_STL=gnustl_static, or define APP_STL in your Application.mk file.
Note that your project uses non-public system library libcutils.so. This library was once included in NDK (see https://stackoverflow.com/a/22017733/192373), but for the last 3 years Google has been struggling to discourage linking to it.
You can build libcutils.so yourself as part of AOSP, or you can adb pull it from your device or even from a compatible emulator. You can also find this binary somewhere on the Web (e.g. GitHub).
The final blow comes with the announced changes to system linking for Android 7.0 Nougat. TL;NR: any app that depends on this library will not work on future Android versions.
You need to install an older version of ndk Android NDK, Revision 10e (May 2015) worked for me and then use that ndk-build

Android NDK build to support all available devices

I am using in my project both java files and native c++ code. I would like to make the app available for all devices and hardware (API lvl >= 15). I am also using OpenCV4Android both in java and my native c++ if that matters. I'm not quite sure if my current configuration is sufficient to support all available hardware:
Application.mk
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-9
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include C:/OpenCV4Android/OpenCV-android-sdk/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := myNativeLib
LOCAL_SRC_FILES := myNativeLib.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
I have tested this configuration on a few devices and it seems to work but doesn't APP_ABI := armeabi-v7a narrow down the supported devices to only those with armeabi-v7a, or actually every device will be able to run it? Maybe I should insert APP_ABI := all as mentioned here? https://developer.android.com/ndk/guides/application_mk.html
It is very important to me to make the app responding and working for all devices possible.
To support all platforms you should use APP_ABI := all
. For API 15 use APP_PLATFORM := android-15.
Pay attention that the more platforms you will support the larger your apk file will be, since it will create a binary for each supported platform in your APK.

Android - Native code trigger a SIGILL only on emulator

My app is triggering a SIGILL fault only when i run it on the emulator. The app is using ActionBarSherlock and the minimum SDK target is API level 8. The fault is triggered when native code is executed (the rest of the app, written in Java, seems to work). I have tried a number of different emulator setup without success. There is no specific code that is faulting. If i comment the function that is faulting, the SIGILL is triggered by some other function at some other point. I use the macro LOGI to write things on the console and the native-code functions are called properly. I have absolutely no idea of what is happening. The app is working perfectly on two different phones (an armv6 rev 5 running android 2.3.4 and an armv7 rev 9 running android 4.0.3). The native code is a library that i have written and tested on my Windows desktop system, and it is working without problems.
Help!
Android.mk
OCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#LOCAL_CFLAGS := -DANDROID_NDK -Wno-psabi
LOCAL_C_INCLUDES += png++/
LOCAL_C_INCLUDES += libpng/
LOCAL_C_INCLUDES += zlib/
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := /* a list of .cpp files... */
LOCAL_SRC_FILES += $(wildcard ./*.c)
LOCAL_SRC_FILES += $(wildcard ./zlib/*.c)
LOCAL_SRC_FILES += $(wildcard ./libpng/*.c)
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += -ljnigraphics
LOCAL_CFLAGS += -marm -march=armv6 -mfloat-abi=softfp -mfpu=vfp -fpermissive -fwrapv -O2 -fexceptions
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_static
APP_OPTIM := release
APP_CPPFLAGS += -frtti
I had a similar problem. I gave up trying on emulator; I think it's something related to ARMv6 support on Android emulator. As mine works on the device too, I no longer care about this issue.

"undefined reference to" (function) & "in archive is not an object" Android ndk-build

I'll expose my problem quickly. I am trying to port curl on Android and to use it within my app. I built the curl library with the ARM toolchain, configured and made (a couple times to make sure I didn't do nothing wrong the first time).
I then proceeded to put the newly created libcurl.a and my curljni.c into my jni folder, as long as the following Android.mk :
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libcurl
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/curl
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := curljni
LOCAL_SRC_FILES := curljni.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/curl
LOCAL_STATIC_LIBRARIES := libcurl
include $(BUILD_SHARED_LIBRARY)
I've been trying a lot of things and I'm pretty sure it looks good now, but whenever I try to build with the ndk-build tool I obtain the following :
Note : curljni.c makes calls to functions within the libcurl library and its easy.h and curl.h files. They are then included in top of the file.
I also tried to ask for the whole library to get loaded into my Android app, using LOCAL_WHOLE_STATIC_LIBRARIES instead of LOCAL_STATIC_LIBRARIES, but without much more success :
Previously :
Downloaded curl.7.28.0
Made a standalone toolchain for ARM 4.6
Fixed several files within curl whose linebreaks were DOS like and needed Unix like (bug in configure) - one of which was depcomp, linked to libcurl_la-file.lo
./configure --host=arm-linux-androidaebi --with-zlib --enable-ipv6
make/make install
Added the resulting libcurl.a from curl\lib.libs
Ok,
Your Problem is that your library libcurl.a is not builded with Android ndk gcc ..
You have done :
$ ./configure --host=arm-linux-androidaebi --with-zlib --enable-ipv6
$ make
$ make install
this will generate a library using your PC gcc ..NOt good .
What i do is to configure open source library l for android using line command (or like you have done):
./configure --build=x86_64-unknown-linux-gnu --host=arm-linux-androideabi --target=arm-linux-androideabi
But then you schould not call make and make install ! .
You have to create an android.mk whinch will compile all source file in your libcurl + your jni file ' curljni.c' and put all in one lib : here an example of Android.mk compiling SQLITE3
###################################################
# SQLITE3
###################################################
include $(CLEAR_VARS)
LOCAL_MODULE := Mysqlite3
MY_LOCAL_SQLITE_SRC := $(LOCAL_PATH)/sqlite/
LOCAL_CPPFLAGS := -g
LOCAL_CPPFLAGS += -I $(MY_LOCAL_SQLITE_SRC)
LOCAL_EXPORT_C_INCLUDES:=$(MY_LOCAL_SQLITE_SRC)
FILE_LIST :=$(wildcard $(MY_LOCAL_SQLITE_SRC)*.c*)
LOCAL_SRC_FILES += $(FILE_LIST:$(LOCAL_PATH)/%=%)
# My SQLITE3 JNI FILE
LOCAL_SRC_FILES +=mysqlite_jni.cpp
# include native NDK library liblog and libz
LOCAL_LDLIBS := -llog -lz
include $(BUILD_SHARED_LIBRARY)

Categories

Resources