NDK Android - Can't build ARMv5 and V7 at the same time - android

I'm facing a weird problem.
I'm building a shared library for my Android application.
I can't build both armv5 and armv7 at the same time.
If I do so, I get a lot of errors on my source files at the second run (when the ndk build the armV7 lib) like:
FinderPatternInfo.o: previous definition here
multiple definition of ...
My Application.mk
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8
APP_STL := stlport_static
APP_CPPFLAGS += -fexceptions
It works perfectly if I only set APP_ABI := armeabi or APP_ABI := armeabi-v7a..
Any idea ?
Thank you for your help,
EDIT: Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyModule
MY_LOCAL_INCLUDED_FILES += $(wildcard $(LOCAL_PATH)/*.h)
MY_LOCAL_INCLUDED_FILES += $(wildcard $(LOCAL_PATH)/*.hpp)
MY_LOCAL_INCLUDED_FILES += $(wildcard $(LOCAL_PATH)/bigint/*.h)
... (many includes)
LOCAL_C_INCLUDES := $(subst jni/, , $(MY_LOCAL_INCLUDED_FILES))
MY_LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/*.c)
MY_LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/*.cpp)
MY_LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/bigint/*.c)
.... (many cpp files)
LOCAL_SRC_FILES := $(subst jni/, , $(MY_LOCAL_SRC_FILES))
LOCAL_CFLAGS := -DNO_ICONV
include $(BUILD_SHARED_LIBRARY)

The Android make system parses your Android.mk once for each target, so your MY_LOCAL_SRC_FILES gets a full set of all of your .c and .cpp files twice when there are two targets, but only one of each when there's a single target.
If your first MY_LOCAL_SRC_FILES assignment used := instead of +=, I think it would fix the problem.

Related

How to generate arm64-v8a 64bit shared object from c++ code?

I've been using a c++ library on my android app for some time now but it has been using 32-bit. I'm trying to compile now the c++ library to a 64bit .so file but every time I do ndk-build I do see the armeabi-v7a get generated successfully, but when the arm64-v8a tries to compile, it fails and gives me the following error message:
libfftw3.a: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
I'm going to place below my Application.mk and Android.mk respectively to show what I've done to try to do this properly.
Application.mk
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION=4.9
APP_CPPFLAGS += -frtti
APP_PLATFORM := android-23
APP_CPPFLAGS += -std=c++11
APP_ABI := armeabi-v7a arm64-v8a
APP_MODULES := SCCpp
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
CXXFLAGS += -arch x86_64 -arch i386
LOCAL_MODULE := fftw3
LOCAL_SRC_FILES := ../lib/libfftw3.a
LOCAL_EXPORT_C_INCLUDES = $(LOCAL_PATH)/..
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
GLOBAL_C_INCLUDES := \
$(LOCAL_PATH)/../src
LOCAL_SRC_FILES += ../src/d/re.cpp
LOCAL_SRC_FILES += ../src/d/me.cpp
LOCAL_SRC_FILES += ../src/d/ev.cpp
LOCAL_SRC_FILES += ../src/d/fe.cpp
LOCAL_SRC_FILES += ../src/fft/fourier.cpp
LOCAL_SRC_FILES += ../src/nu/ac.cpp
LOCAL_SRC_FILES += ../src/nu/st.cpp
LOCAL_SRC_FILES += ../src/utils/converter.cpp
LOCAL_SRC_FILES += ../src/sci.cpp
LOCAL_MODULE := SCCpp
LOCAL_MODULE_FILENAME := libSCCpp
LOCAL_STATIC_LIBRARIES := fftw3
LOCAL_CPP_FEATURES += exceptions
LOCAL_CFLAGS += -fopenmp
LOCAL_CFLAGS += -Ofast
LOCAL_LDFLAGS += -fopenmp -t
LOCAL_CPPFLAGS := -std=c++11
LOCAL_LDLIBS += -latomic -llog
LOCAL_C_INCLUDES := $(GLOBAL_C_INCLUDES) $(LOCAL_PATH)/../../../3rdParty/fftw-3.3.4-dll32/
LOCAL_EXPORT_CPPFLAGS := -fexceptions -frtti
include $(BUILD_SHARED_LIBRARY)
I'm really unfamiliar with this whole process so I'm at a dead end especially since the logs don't really tell me anything at all. I thought that by just adding in the arm64-v8a would automatically generate the 64bit shared object. Is there a missing step?
If there's any missing information that I should provide, please ask in the comments so I can give more details, but as of now in my current position, this is all that I have touched in the code base for the c++ library so I'm not quite sure where all the pieces are at the moment.
You use a prebuilt library at
../lib/libfftw3.a
You must build fftw3 for arm64, too. Usually we have
LOCAL_SRC_FILES := ../lib/$(TARGET_ARCH_ABI)/libfftw3.a
so that ndk-build can choose the right variant of the 3rd party lib.
The instructions to build fftw3 for arm64 are available on GitHub.

Android NDK building shared library - Aborting - stop. local_module_filename must not contain a file extension

Here is my Android.mk
LOCAL_PATH := $(call my-dir)
LOCAL_STATIC_LIBRARIES = -lboost_system ...
include $(CLEAR_VARS)
LOCAL_MODULE := AVL
LOCAL_MODULE_FILENAME:= libAVL
LOCAL_SRC_FILES := AVL.cpp
LOCAL_CFLAGS += -I$(LOCAL_PATH)/boost/include/boost-1_55
LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -frtti
include $(BUILD_SHARED_LIBRARY)
include $(BUILD_STATIC_LIBRARY)
Application.mk
APP_ABI := all
APP_STL := stlport_static
Error:
Android NDK: jni/Android.mk:AVL: LOCAL_MODULE_FILENAME must not contain a file extension
/home/manevbg/Documents/android-sdks/android-ndk-r10/build/core/build-static-library.mk:29: *** Android NDK: Aborting . Stop.
Any idea how to build shared library?
PP: Using eclipse.
Remove the LOCAL_MODULE_FILENAME:= libAVL. The build system will correctly prefix the library with 'lib' for you.

NDK, LOCAL_EXPORT_C_INCLUDES not working as expected

Right now I am working on a native Android project and I want to use DevIL.
I don't want to put all the NDK code into one file, since DevIL needs multiple other libraries (libpng/libjpeg/...) and the Android.mk would end up being bloated.
I created a sub directory called Devil in my jni directory. I put all the code needed for DevIl (+ the libraries) in this directory. I also created an extra Android.mk file in this directory. In my "main" Android.mk file I added$(call import-module,DevIL) as well as: LOCAL_SHARED_LIBRARIES += libdevil. In the DevIL Android.mk I created an libdevil module and I used LOCAL_EXPORT_C_INCLUDES to link to the DevIL header files. When I put #include into my main.cpp file the ndk-build fails and complains "No such file or directory" in regards to the included header. If I don't put the #include into the code, the code compiles fine and all the shared libraries are created and put into the libs folder. What am I doing wrong?
My Main Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include cflags.mk
LOCAL_MODULE := arm
LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES += libdevil
include $(BUILD_SHARED_LIBRARY)
$(call import-module,DevIL)
The Android.mk used for DevIl
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include cflags.mk
JPEG_SRC_PATH := Libjpeg/
DEVIL_SRC_PATH := DevIL/
#many more
#libjpeg
include $(CLEAR_VARS)
LOCAL_MODULE := libjpeg
LOCAL_C_INCLUDES := ${JPEG_SRC_PATH}
FILE_LIST := $(wildcard $(LOCAL_PATH)/JPEG_SRC_PATH/*.c)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
include $(BUILD_SHARED_LIBRARY)
#many other libraries; basically the same as libjpeg
#libdevil
include $(CLEAR_VARS)
LOCAL_MODULE := libdevil
LOCAL_EXPORT_C_INCLUDES := \
${DEVIL_SRC_PATH}include \
${DEVIL_SRC_PATH}src-IL/include \
#many more
FILE_LIST := $(wildcard $(LOCAL_PATH)/DEVIL_SRC_PATHsrc-IL/src/*.c)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_STATIC_LIBRARIES := \
libjpeg \
#many more
LOCAL_LDLIBS += -lz
include $(BUILD_SHARED_LIBRARY)
The cflags.mk file
LOCAL_CFLAGS := -DANDROID_NDK
LOCAL_CFLAGS += -Werror
LOCAL_CFLAGS += -Wall
LOCAL_CFLAGS += -Wextra
LOCAL_CFLAGS += -Wno-strict-aliasing
LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_CFLAGS += -Wno-missing-field-initializers
LOCAL_CFLAGS += -Wno-multichar
LOCAL_CPPFLAGS := -Wno-type-limits
LOCAL_CPPFLAGS += -Wno-invalid-offsetof
LOCAL_CPPFLAGS += -std=c++11
LOCAL_CFLAGS += -std=c++11
LOCAL_CFLAGS += -fexceptions
LOCAL_CFLAGS += -Wno-error=deprecated-declarations
LOCAL_ARM_MODE := arm
Structure of the Directories
jni
|
+-- main.cpp
+-- Android.mk <- main Android
+-- Application.mk
+-- cflags.mk
|
+--DevIL
|
+-- Android.mk <- the Android.mk for DevIL
+-- cflags.mk
+--DevIL <-Directory containing DevIL source code
+--Libjpeg <-Directory containing code of specific DevIL dependency
+--...<-Directory containing code of specific DevIL dependency
Edit:
I noticed that I did not add my Application.mk, thus my Application.mk
Application.mk
APP_PLATFORM := android-19
APP_ABI := armeabi-v7a
APP_STL:=c++_static
APP_LDFLAGS := -Wl,--build-id
NDK_TOOLCHAIN_VERSION := 4.9
ROOT_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
NDK_MODULE_PATH := $(ROOT_DIR)
This does not answer the question, but if you are here from a search engine and happen to be having issues with LOCAL_EXPORT_C_INCLUDES on an AOSP module (not an NDK project!), Google's documentation at https://developer.android.com/ndk/guides/android_mk.html applies only to NDK projects.
For AOSP modules, the variable name is LOCAL_EXPORT_C_INCLUDE_DIRS, not LOCAL_EXPORT_C_INCLUDES.

Android-NDK: incompatible target while linking ZeroMQ static library into a shared library

I have successfully compiled multiple static libraries with the ndk toolchain and linked them into my own project. I have to use many cpp files and they need protocol buffers and a ZeroMQ, as a library, to compile successfully. Linking against protocol buffers works great, however, when I link against the ZeroMQ I get the following error:
C:/Users/x/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/windows- x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux- androideabi/bin/ld.exe: error: ./zmq/lib/libzmq.a(libzmq
_la-zmq.o): incompatible target
collect2.exe: error: ld returned 1 exit status
make.exe: *** [C:/Users/x/Workspace/y/app/src/main//obj/local/armeabi- v7a/libZ.so] Error 1
I have replaced personal information with x, y, z for a clear reason.
I'm using Windows 8.1 with Android Studio 1.1 RC1 and NDK10d. I compiled the libraries on a Ubuntu and a Debian system (tried different ones). Both use the same arm toolchain.
To compile ZeroMQ I followed the steps from the official page. I tried zeromq3-x and zeromq4-x. I tried the mentioned ndk8 and the new ndk10d.
My Application.mk:
APP_STL := gnustl_static #tried: c++_static/shared stlport_static/shared
APP_PLATFORM := android-21
APP_USE_CPP0X := true #tried to omit
APP_CXXFLAGS := -std=gnu++11
APP_CPPFLAGS := -frtti -fexceptions --std=c++11
APP_ABI := armeabi-v7a #tried different like armeabi, all, x86 - obviously only arm should work
NDK_TOOLCHAIN_VERSION := 4.9
Android.mk without important files to compile because it will crash on the first need of zmq:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ../jni/protobuf
LOCAL_SRC_FILES := ../jni/protobuf/libprotobuf.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include\google
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include\google\proto
LOCAL_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include
LOCAL_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include\google
LOCAL_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include\google\protobuf
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_MODULE := zmq
LOCAL_SRC_FILES := zmq/lib/libzmq.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\ZMQ\ARM-FINAL\include
LOCAL_EXPORT_C_INCLUDES := zmq/include
LOCAL_C_INCLUDES := C:\Users\x\Android\ZMQ\ARM-FINAL\include
LOCAL_C_INCLUDES := zmq/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Z
LOCAL_CFLAGS := -I/zmq -std=c++11
LOCAL_CPPFLAGS := -I/zmq -std=c++11
LOCAL_CPP_FEATURES += exceptions
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog
LOCAL_CPP_EXTENSION := .cxx .cpp .cc .h
LOCAL_DISABLE_FORMAT_STRING_CHECKS := true
LOCAL_SRC_FILES := \
../jni/protogen/applications.pb.cc \ # this will work
common/bytearray.cpp \ # this will fail
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_C_INCLUDES += C:\Users\x\Android-MasterUI\app\src\main\jni
LOCAL_C_INCLUDES += ../jni/protogen
LOCAL_C_INCLUDES += common
LOCAL_C_INCLUDES += C:\Users\x\Android\ZMQ\ARM-FINAL\include
LOCAL_C_INCLUDES += C:\Users\x\Workspace\\app\src\main\jni\protobuf
LOCAL_C_INCLUDES += C:\Users\x\Workspace\Android- MasterUI\app\src\main\jni\protobuf\include
LOCAL_C_INCLUDES += C:\Users\x\Android- MasterUI\app\src\main\jni\protobuf\include\google
LOCAL_C_INCLUDES += C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include
LOCAL_C_INCLUDES += C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include\google
LOCAL_C_INCLUDES += C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include\google\protobuf
LOCAL_STATIC_LIBRARIES := zmq protobuf
include $(BUILD_SHARED_LIBRARY)
The objdump from the static library looks like this
libzmq_la-address.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
I will omit the further ones because they are all the same. There was a better way to dump all the pieces of information with more details about the architecture, but I can not find it anymore.
If you know a better way you may tell me and I will add more information.
Any idea is welcome and appreciated...

Android NDK linking, "undefined reference" When linking with a Static Lib

Environment
android-ndk-r10c
VisualGDB
Windows x64
Use-case 1
ADB Cmdline executable ( no Java / APK ) is consist of several C++ files
Executable is compiled having "APP_STL := gnustl_static" at Application.mk
Executable is successfully compiled and running
Use-case 2
The ADB tool of Use-case 1 is split into two separate projects
A static library encapsulating general purpose functionality
The ADB Tool minus the functionality moved out to the static lib
Executable & static Lib are compiled having "APP_STL := gnustl_static" at Application.mk
ADB Exe is compiled having LOCAL_LDLIBS := -L$(PATH_TO_STATIC_LIB) -lstaticlib
Compilation fail with "undefined reference to `std::terminate()'" Linker error
Problem at hand
When compiling all CPP files as one project all goes fine, no linker error.
When spiting the logic into a thin executable and a staticlib (that the executable is linked against ) I get an "undefined reference to `std::terminate()'" Linker error.
It seems to me as if "gnustl_static" is not linked with the executable although "APP_STL := gnustl_static" is specified...
What am I missing here? Is there any way to force 'gnustl_static' to link ?
The make files for reference:
Makefile where all files are part of the same executable (WORKING)
Application.mk
APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp SimpleTCPStream.cpp SocketsServer.cpp uuids.cpp
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS :=
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_EXECUTABLE)
Makefiles where files are split into a static lib and executable that links against the lib
(NOT WORKING)
Executable Application.mk
APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9
Executable Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -llog -L$(PATH_TO_STATIC_LIB) -lCollections_statis
LOCAL_CFLAGS :=
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_EXECUTABLE)
Static Lib Application.mk
APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9
APP_MODULES := Collections-static Collections-shared
Static Lib Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Collections-shared
LOCAL_SRC_FILES := SimpleTCPStream.cpp SocketsServer.cpp uuids.cpp
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS :=
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Collections-static
LOCAL_SRC_FILES := $(COMMON_SRC_FILES)
include $(BUILD_STATIC_LIBRARY)
This isn't a bug in the NDK build system, but it is an issue with how you are using it.
If you run ndk-build V=1, you see the actual commands that it tries to execute, and you'd see that it already tries to link in gnustl_static, but it links it in before linking in your own static library. The linker only tries libraries in the order they are specified on the linker command line, which means that it won't try to use the earlier specified gnustl_static library to resolve undefined references from a later library.
The correct solution here is to not use LOCAL_LDLIBS for forcing linking to a static library, but use the NDK provided infrastructure for linking to static libraries. That is, change your executable Android.mk like this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp
LOCAL_STATIC_LIBRARIES := Collections_static
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := Collections_static
LOCAL_SRC_FILES := $(PATH_TO_STATIC_LIB)/libCollections_static.a
include $(PREBUILT_STATIC_LIBRARY)
This way, you include the static library into the build of the executable in the same way regardless if the static library is built as part of the same build, or is a prebuilt library.
This syntax also allows you to add LOCAL_EXPORT_C_INCLUDES in the section for the static library, to add the right include path when building the executable, without having to manually add it to section for the executable.
It appears that indeed although "APP_STL := gnustl_static" is strictly specified at Application.mk of the Executable it is not really linked, to force gnustl_static to link I have added the following to LOCAL_LDLIBS of Android.mk
LOCAL_LDLIBS += -L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(TARGET_ARCH_ABI) -lgnustl_static
Seems to me like a bug in the NDK build system...

Categories

Resources