I'm trying to build a jni project which generates a shared library using the Android-ndk.
I'm going to code a some part in assembly language as needed, so I configured the project as the following.
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := my_test
LOCAL_SRC_FILES := Test.cpp MyAsm.s
LOCAL_CFLAGS :=
include $(BUILD_SHARED_LIBRARY)
Application.mk:
APP_ABI := armeabi-v7a
APP_STL := stlport_static
Test.cpp:
...
MyAsmFunc();
...
MyAsm.s:
.text
.align 2
.global MyAsmFunc
MyAsmFunc:
...
tbb [PC,R1]
...
cbnz R1,loc_51ACE
...
When I was compiling the project, I've got the following error msg.
MyAsm.s:224: Error: selected processor does not support ARM mode `tbb [PC,R1]'
MyAsm.s:882: Error: selected processor does not support ARM mode `cbnz R1,loc_51ACE'
My question is how to build the project successful. Help me, please.
Thanks in advance.
According to this page,
These 16-bit Thumb instructions are available in ARMv6T2 and above.
There are no ARM or 32-bit Thumb versions of these instructions.
You're compiling for ARMv7-A, so the first part is fine. However, it's trying to interpret the instructions as ARM rather than THUMB/THUMB2. Add .thumb / .thumb_func directives to your assembly source file to set THUMB mode. See also the GNU as docs.
Related
I'm trying to build and link freeimage to an android project. I'm close but I'm tripping up on some linker errors from that library.
I'm using this repo: https://github.com/jamcar23/FreeImage-Android/blob/master/jni/freeimage/Android.mk
Freeimage uses the internal NDK library 'cpufeatures' to use xeon chipset features. In the project's 'android.mk', there's a reference to the cpufeatures library:
LOCAL_STATIC_LIBRARIES := cpufeatures
and my library, which statically links to this one, also includes cpufeatures in its LOCAL_STATIC_LIBRARIES statement in that project's android.mk:
LOCAL_STATIC_LIBRARIES := tinyxml freetype2 bullet freeimage cpufeatures
also in my android.mk, I link freeimage like this:
#####FREEIMAGE_LIBRARY_DECLARATION##########
include $(CLEAR_VARS)
LOCAL_PATH = $(TPLIBROOT)/FreeImage-Android
LOCAL_MODULE := freeimage
LOCAL_EXPORT_C_INCLUDES := include
LOCAL_SRC_FILES := obj/local/$(TARGET_ARCH_ABI)/libFreeImage.a
include $(PREBUILT_STATIC_LIBRARY)
###############################################
which, taking note of a previous question I had about the NDK, should take care of specific architectures (I've build freeimage using all available architectures)
freeimage .a and .so libraries appear to build fine but on linking to my library when building the .so, I get this error:
[armeabi-v7a] SharedLibrary : libAnthracite.so
jni/freeimage/Source/LibWebP/./src/dsp/dsp.cpu.c:108: error: undefined reference to 'android_getCpuFamily'
jni/freeimage/Source/LibWebP/./src/dsp/dsp.cpu.c:109: error: undefined reference to 'android_getCpuFeatures'
jni/freeimage/Source/LibWebP/./src/dsp/dsp.dec.c:745: error: undefined reference to 'VP8DspInitNEON'
which is odd as both libraries do link cpufeatures, so it really ought to be there.
I'm declaring
APP_PLATFORM := android-14
APP_STL := gnustl_static
in the application.mk files for both projects.
Also, I've tried placing 'LOCAL_STATIC_LIBRARIES' in different positions in the files and linking libraries in different orders, although that's just guesswork.
Does anybody know what might be causing these linker errors?
Please follow the official guide to add cpu-features. TL;NR: add $(call import-module,android/cpufeatures) to your Android.mk.
I finally got it to work by ensuring that all of my 'application.mk' files for all four of the third party libraries I was using shared a common base file that looks like this:
APP_PLATFORM := android-15
APP_STL := c++_static
APP_ABI := all
APP_OPTIM := release
APP_SHORT_COMMANDS := true
Which makes keeping them in line easier, ensuring they're all built against the same libraries.
Also, I changed the STL implementation from 'gnustl_static' to 'c++_static'
I'm trying to build my native library with CMake in latest Android Studio. I prepared gradle scripts for this, no any problems, but I found a small problem - I can not compile my library for x86 arch.
Some time before...
My library uses OpenSSL AES/DES encryption/decryption. I compiled OpenSSL 1.0.2k as is (static library), linked it to my shared library and all was fine except x86 arch - there was an error shared library text segment is not shareable while dlopen on then device. Then I recompiled OpenSSL with -fPIC flag, linked it again and error went away. I was building with NDK 13b.
Now...
I am trying to migrate from NDK to CMake because it is has more features for me and Android Studio can normally autocomplete and lint C/C++ code only with CMake. I wrote CMakeList.txt and it works, but problem with shared library text segment is not shareable appeared again, but on linkage step of CMake build process. Error:
D:/User/AppData/Local/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: warning: shared library text segment is not shareable
D:/User/AppData/Local/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: treating warnings as errors
I disabled treating this warning as error and shared library text segment is not shareable appeared while dlopen on the device again.
What is the problem? Why NDK builds without any problems and CMake does not?
P.S. I tried different CMAKE flags (such as CMAKE_POSITION_INDEPENDENT_CODE) and nothing works. This problem occurrs only for x86 arch.
CMakeLists.txt (Build failed for x86, all others - no problems):
cmake_minimum_required(VERSION 3.4.1)
include_directories(include/)
find_library(log-lib log)
add_library(libcrypto STATIC IMPORTED)
add_library(libssl STATIC IMPORTED)
add_library(testlib SHARED test.c)
set_target_properties(libcrypto
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/static/${ANDROID_ABI}/libcrypto.a)
set_target_properties(libssl
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/static/${ANDROID_ABI}/libssl.a)
target_link_libraries(testlib libcrypto libssl ${log-lib})
set (CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fPIC")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -fPIC")
Android.mk (NDK14b, All archs - no problems):
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := $(LOCAL_PATH)/static/$(TARGET_ARCH_ABI)/libcrypto.a
LOCAL_MODULE := crypto
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := $(LOCAL_PATH)/static/$(TARGET_ARCH_ABI)/libssl.a
LOCAL_MODULE := ssl
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LCOAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := test.c
LOCAL_MODULE := testlib
LOCAL_STATIC_LIBRARIES := crypto ssl
include $(BUILD_SHARED_LIBRARY)
Thanks in advance for any help!
The solution was that I need to compile OpenSSL with no-asm flag. After that OpenSSL linked and worked normally on x86 arch.
set(CMAKE_SHARED_LINKER_FLAGS "-Wall -v -Wl, --no-warn-shared-textrel")
this exact toolcain is treating warnings as errors, so just add this to suppress the warning. --no-warn-shared-textrel is the key
just in x86, add --no-warn-shared-textrel, you should add this to CMakeList.txt:
if (${ANDROID_ABI} STREQUAL "x86")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-warn-shared-textrel")
endif ()
good luck.
I'm trying to build a static library using a standalone toolchain for a project that has its own build process, which I then wrap with a C++ library and expose to Android (compiled with ndk-build). However, on the ndk-build step I receive the following error:
➜ jni /Users/chrisfosterelli/Library/Android/sdk/ndk-bundle/ndk-build
[arm64-v8a] Compile++ : wrapper <= wrapper.cpp
In file included from /Users/chrisfosterelli/workspace/android/jni/wrapper.cpp:9:
In file included from ../prebuild/include/valhalla/meili/universal_cost.h:7:
In file included from ../prebuild/include/valhalla/sif/dynamiccost.h:4:
In file included from ../prebuild/include/valhalla/baldr/directededge.h:5:
../prebuild/include/valhalla/baldr/graphconstants.h:432:11: warning: 21 enumeration values not handled in switch: 'kRoad', 'kRamp', 'kTurnChannel'... [-Wswitch]
switch (use) {
^
1 warning generated.
[arm64-v8a] SharedLibrary : libwrapper.so
/Users/chrisfosterelli/Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld: /Users/chrisfosterelli/workspace/android/jni/../prebuild/libvalhalla_meili.a(libvalhalla_meili_la-map_matcher_factory.o): Relocations in generic ELF (EM: 62)
[...above message repeated many times...]
/Users/chrisfosterelli/workspace/android/jni/../prebuild/libvalhalla_meili.a: error adding symbols: File in wrong format
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [/Users/chrisfosterelli/workspace/android/obj/local/arm64-v8a/libwrapper.so] Error 1
➜ jni ls /Users/chrisfosterelli/Library/Android/sdk/ndk-bundle/
This error indicates, as far as I can tell, that I'm trying to mix and match binaries compiled for different architectures. However, from what I can tell the library is the correct architecture:
root#eacbdb1c0e46:/meili/meili2/newtest# ar x libvalhalla_meili.a
root#eacbdb1c0e46:/meili/meili2/newtest# file libvalhalla_meili_la-map_matcher_factory.o
libvalhalla_meili_la-map_matcher_factory.o: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), not stripped
root#eacbdb1c0e46:/meili/meili2/newtest#
FWIW, these are my current Application.mk,
APP_STL := c++_static
APP_CPPFLAGS := -frtti -std=gnu++11 -D_GLIBCXX_USE_C99
APP_CPPFLAGS += -fexceptions
NDK_TOOLCHAIN_VERSION := clang
APP_LDFLAGS := -latomic
APP_PLATFORM := android-21
APP_ABI := arm64-v8a
and Android.mk,
LOCAL_PATH := $(call my-dir)
# static library info
include $(CLEAR_VARS)
LOCAL_MODULE := libvalhalla_meili
LOCAL_SRC_FILES := ../prebuild/libvalhalla_meili.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include
include $(PREBUILT_STATIC_LIBRARY)
# wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += ../prebuild/include
LOCAL_MODULE := wrapper
LOCAL_SRC_FILES := wrapper.cpp
LOCAL_STATIC_LIBRARIES := libvalhalla_meili
include $(BUILD_SHARED_LIBRARY)
Any ideas how to resolve this? I've tried a number of things but all of them lead to more (more obscure) errors, so I'm hoping someone here can point me in the correct direction!
I discovered the problem, but I wish I had a more insightful answer. Apparently the build process had created two library files. The one that I inspected was, of course, ARM64. However the one that I actually copied to the Android device was x86.
So, the error message was correct and so was the library file, but there was more than one file involved. If you're running into the same problem and pretty sure your library is ARM64, double check that's actually the same file that is being compiled into the ndk build!
I've found some serious difficulties in getting a working .so library to develop an Android app with Android NDK and intel TBB.
Basically I've downoaded version 4.4 Update 4 bundle for Android and followed the steps there (kind of, since the docs are not correct...).
Problem is that I can only get x86 and x86_64 .so libraries when compiling, since there are no armeabi-XXX or mips folders with the necessary .so in there.
Using the suggested command ./ndk-build.cmd tbb target=android arch=arm does not produce anything, in fact it tells me
/workspace/tbb44_20160413oss/lib/android/mips/libtbb.so library not found. Copy mips version of library to /home/filippo/workspace/tbb44_20160413oss/lib/android/mips folder to enable its build.
and the same for the other missing directories.
Threfore using only ./ndk-build.cmd tbb target=android gives me a cuople of dirs: x86 and x86_64 which I can use in Android Studio, and work with the emulator.
The result is taht I can properly test my apps on an emulator but cannot make it work into my personal device.
What am I missing here?
Application.mk
APP_ABI := x86 x86_64 // if I choose all, of course it won't find the .so for the other architectures
APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti
APP_STL := gnustl_shared
Android.mk
LOCAL_PATH := $(call my-dir)
#
# TBB
#
include $(CLEAR_VARS)
LOCAL_MODULE := libtbb
LOCAL_SRC_FILES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/libtbb.so
include $(PREBUILT_SHARED_LIBRARY)
#
# Main module
#
include $(CLEAR_VARS)
LOCAL_MODULE := myndkapp
LOCAL_SHARED_LIBRARY := libtbb
include $(BUILD_SHARED_LIBRARY)
Thanks.
As you can see in 'jni/Application.mk' you can use targets 'ia32', 'intel64', 'arm' and 'arm64'.
Also it looks like you trying to build on Windows platform, so you should add a tbb_os=windows to your make command like this:
C:\TEMP\tbb44_20160413oss\src>ndk-build.cmd tbb tbbmalloc target=android arch=arm tbb_os=windows
OS: Windows 7
SDK: adt-bundle-windows-x86-20130717
NDK: android-ndk-r8e
Eclipse ADT: Build: v22.0.4-741630
I'm trying to render a bitmap using OpenGL ES in JNI. I have these headers declared at the top of the file:
#include <android/bitmap.h>
#include <GLES2/gl2.h>
so I don't understand why tokens such as GL_TEXTURE_2D are reported as "could not be resolved" and the project doesn't build. The frustrating part is that functions and variables defined in bitmap.h such as AndroidBitmap_getInfo() and ANDROID_BITMAP_FORMAT_RGB_565 don't cause a problem; they resolve properly.
The C/C++>General>Paths and Symbols properties for the project has this path:
C:\Android\android-ndk-r8e-windows-x86\android-ndk-r8e\platforms\android-9\arch-arm\usr\include
I see the tree structure in the header node of the Eclipse project and I've confirmed that android & GLES2 folders exist at that path location and each contain the appropriate .h file (bitmap.h and gl2.h respectively). How can it be that bitmap.h resolves but gl2.h doesn't? I'm declaring the includes exactly the same way!
Application.mk:
APP_PLATFORM := android-10
APP_ABI := armeabi-v7a
Any troubleshooting tips?
Thanks
Have you ever tried the sample code bitmap-plasma & hello-gl2 in NDK package? you can check relevant Android.mk. make sure you have linked correct libraries
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgl2jni
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := gl_code.cpp
LOCAL_LDLIBS := -llog -lGLESv2 -lm -ljnigraphics
include $(BUILD_SHARED_LIBRARY)