I'm trying to implement an OEX (open engine exchange protocol) chess program for Android.
This has been discussed at What is OEX (Open Exchange Protocol?) and can I call such APK from my app? earlier.
The java-part of the program runs fine, yet the native library always segfaults. Even with something simple as
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello, world!\n");
return 0;
}
I noticed one thing to be different: the libstockfish.so library seems to be linked to /system/bin/linker while my library is not linked at all?
file libs/x86_64/libstockfish.so:
ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /system/bin/linker64,
BuildID[sha1]=b690a6bb7630099c6618950a9e1604850f1de836, stripped
file libs/x86_64/libDog.so
libs/x86_64/libDog.so: ELF 64-bit LSB shared object, x86-64, version 1
(SYSV), dynamically linked,
BuildID[sha1]=93a9d3635eef9fc0f2140a87956db9ac80459993, stripped
What is it that I could be doing wrong?
I'm using the ndk-build script:
jni/Application.mk:
APP_ABI := all
APP_PLATFORM := 21
#NDK_TOOLCHAIN_VERSION := 4.9
APP_STL := c++_shared
APP_CPPFLAGS += -frtti
APP_CPPFLAGS += -std=c++17
jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Dog
LOCAL_SRC_FILES := test.cpp
LOCAL_STRIP_MODE := none
LOCAL_PRELINK_MODULE := false
LOCAL_CPPFLAGS += -std=c++17 -Wall -DVERSION=\"0.8\" -DNAME_EXTRA=\"\" -fexceptions -Wno-c++11-narrowing -fPIC -pie -fPIE
LOCAL_LDLIBS += -shared
LOCAL_LDFLAGS += -fPIC -pie -fPIE -Wl,--entry=main,-dynamic-linker=/system/bin/linker
LOCAL_CPP_FEATURES := exceptions
include $(BUILD_SHARED_LIBRARY)
Any ideas?
Found the solution: apparently the idea is to trick the packaging system by creating a regular binary and renaming it to e.g. libstockfish.so. Then the board-programs can happily import them and play chess with them.
Related
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.
I've set up a makefile for my game in SDL. The template of the Application.mk file included in SDL has three architectures:
APP_ABI := armeabi armeabi-v7a x86
Everything compiles just fine for armeabi, but for armeabi-v7a it fails. To me, it looks like compilation completes, but the linker has all obj files of two certain folders twice. While this does not happen for armeabi. The linker (ld) gives me an error of this kind:
/path/to/bin/ld: error: /path/to/myObjFile.obj: multiple definition of 'foo(int, int)'
/path/to/bin/ld: /path/to/myObjFile.obj: previous definition here
The path is exactly the same, so this makes me assume that the linker uses every file twice. A full example of such an error is here:
/Users/martijncourteaux/Development/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: /Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Box2D/Collision/b2Distance.o: multiple definition of 'b2Distance(b2DistanceOutput*, b2SimplexCache*, b2DistanceInput const*)'
/Users/martijncourteaux/Development/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: /Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Box2D/Collision/b2Distance.o: previous definition here
However, the object files that are linked double also generate this warning when I launch ndk-build:
/Users/martijncourteaux/Development/android-ndk-r10c/build/core/build-binary.mk:449: warning: ignoring old commands for target `/Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Collision/b2Distance.o'
/Users/martijncourteaux/Development/android-ndk-r10c/build/core/build-binary.mk:449: warning: overriding commands for target `/Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Collision/b2Distance.o'
Note that I have the impression that all these obj-files that have these multiple definition errors generate also generate this warning.
This is my Application.mk:
APP_STL := gnustl_static
APP_ABI := armeabi armeabi-v7a x86
NDK_TOOLCHAIN_VERSION := clang
APP_CPPFLAGS += -std=c++11
APP_PLATFORM := android-10
And here is my Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
SDL_PATH := ../SDL
THIRD_PARTY_FOLDER := $(LOCAL_PATH)/../ThirdParty
LOCAL_CPPFLAGS += -frtti
LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -funwind-tables
PCH_FILE := $(LOCAL_PATH)/Gump/Gump-Prefix.pch
#PCH_FILE := Gump/Gump-Prefix.pch
LOCAL_CPPFLAGS += -include $(PCH_FILE)
#LOCAL_PCH := $(PCH_FILE)
#LOCAL_CPPFLAGS += -DPCH
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \
$(LOCAL_PATH)/$(SDL_PATH)_mixer/ \
$(LOCAL_PATH)/$(SDL_PATH)_image/ \
$(LOCAL_PATH)/$(SDL_PATH)_net/ \
$(LOCAL_PATH)/../ThirdParty/ \
$(LOCAL_PATH)/Gump/
# Add your application source files here...
GUMP_SRC_FILES := $(wildcard $(LOCAL_PATH)/Gump/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/tinyxml2/tinyxml2.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/Box2D/*/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/Box2D/*/*/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/poly2tri/**/*.cc)
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c $(THIRD_PARTY_SRC_FILES) $(GUMP_SRC_FILES)
LOCAL_SHARED_LIBRARIES := SDL2_image SDL2_mixer SDL2_net SDL2
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
include $(BUILD_SHARED_LIBRARY)
My Guess (turns out false):
After writing this question and looking closely to provide you guys the most accurate information as possible about my problem, I noticed that the obj-files that are giving errors are those were I've used a wildcard on folder level as well. Eg: $(ROOT)/*/*.cpp. While these wildcards give no problem: $(ROOT)/Gump/*.cpp. I don't know for sure, but I guess that the wildcards work different on when linking for these different architectures...
Update:
I've tested it again not using wildcards for folders, and the same error about multiple definition appears.
Your list of files is appended every time a new ABI is being built. LOCAL_SRC_FILES is erased through include $(CLEAR_VARS); GUMP_SRC_FILES is redefined each time. But THIRD_PARTY_SRC_FILES only grows longer and longer. This has nothing to do with the wildcards, as you noticed. Simply add line
THIRD_PARTY_SRC_FILES :=
after include $(CLEAR_VARS), and your build will be fine.
Running ndk-build V=1 shows the build commands executed during the process. There I could see the .o files being linked twice. I'm not sure what the reason for that is. I guess it might have been due to the fact that the android makefile in the src/ folder used sources from his parent directory: ../ThirdParty/[morehere].
I fixed it by creating extra makefiles for these third party libraries, so now every library creates a shared library in a .so file. Which gets linked at compile-time. I think this is neater, because changing a makefile requires only that subproject to be recompiled.
I am trying to use the png quantization library at pngquant.org/lib in my Android project using the NDK r10 (64bit) on OS X.
I am making progress in compiling the library. The problem I have now is that the size_t type cannot be resolved. I tried including the following folder:
LOCAL_C_INCLUDES := $(NDK_TOOLCHAIN)/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9/include
but that does not help.
I would be really interested in an empty working Android project with pngquant included.
Any help is really appreciated.
NB sorry for changing the question, but the original question I asked had some incorrect facts in it.
I don't have enough information to directly solve your specific problem, are you trying to use the standalone toolchain ?
When building for Android, since you have more than one architecture to target and the toolchain is a bit complex, it's better to use the ndk-build script from the NDK.
I've made a project here that you can integrate to your Android project directory: https://github.com/android-native-libraries/pngquant-android
The original library is using configure script but instead of extending these I've rewritten NDK Makefiles to directly compile all the lib sources, with the same cflags (openmp, sse...)
Android.mk:
LOCAL_PATH := $(call my-dir)
SRC_PATH := pngquant/lib
include $(CLEAR_VARS)
LOCAL_MODULE := imagequant
LOCAL_SRC_FILES := \
$(SRC_PATH)/blur.c \
$(SRC_PATH)/libimagequant.c \
$(SRC_PATH)/mediancut.c \
$(SRC_PATH)/mempool.c \
$(SRC_PATH)/nearest.c \
$(SRC_PATH)/pam.c \
$(SRC_PATH)/viter.c
LOCAL_C_INCLUDES := pngquant/lib
LOCAL_CFLAGS += -O3 -fno-math-errno -funroll-loops -fomit-frame-pointer -Wall -std=c99 -fopenmp
LOCAL_LDFLAGS += -fopenmp
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_CFLAGS += -mtune=atom -msse -mfpmath=sse -mssse3 -DUSE_SSE=1
endif
include $(BUILD_SHARED_LIBRARY)
You can extend this Android.mk file to add your own native library with your sources, that are using libimagequant:
include $(CLEAR_VARS)
LOCAL_MODULE := yourlib
LOCAL_SRC_FILES := yoursources.c
LOCAL_C_INCLUDES := pngquant/lib
LOCAL_SHARED_LIBRARIES := imagequant
LOCAL_CFLAGS += -O3 -fno-math-errno -funroll-loops -fomit-frame-pointer -Wall -std=c99 -fopenmp
LOCAL_LDFLAGS += -fopenmp
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_CFLAGS += -mtune=atom -msse -mfpmath=sse -mssse3 -DUSE_SSE=1
endif
include $(BUILD_SHARED_LIBRARY)
If you just want to use this library with default settings, I've made a simple Android library that may suit your purposes.
In your build.gradle:
dependencies {
compile 'com.ndahlquist:pngquant-android:0.2'
}
In your Android app:
File inputPngFile = getYourPng();
File outputPngFile = getOutputFile()
new LibPngQuant().pngQuantFile(inputFile, outputFile);
I have recently purchased a book to assist in my development of C++ for Android which contained some code samples. However, when I come to build some of the sample code, I receive the following error:
C:\ndk\android-ndk-r9\ndk-build.cmd all
"Compile++ : Chapter10 <= Chapter10.cpp
process_begin: CreateProcess(NULL, C:/ndk/android-ndk-r9/toolchains/arm-linux-androideabi-4.7/prebuilt/windows/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi/objs/Chapter10/Chapter10.o.d -fno-exceptions -fno-rtti -Ijni -IC:/ndk/android-ndk-r9/sources/android/native_app_glue -IC:/ndk/android-ndk-r9/sources/cxx-stl/stlport/stlport -IC:/ndk/android-ndk-r9/sources/cxx-stl//gabi++/include -Ijni -DANDROID -Wa,--noexecstack -Wformat -Werror=format-security -frtti -c jni/Chapter10.cpp -o ./obj/local/armeabi/objs/Chapter10/Chapter10.o, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [obj/local/armeabi/objs/Chapter10/Chapter10.o] Error 2
The make file is as shown below:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_MODULE := Chapter10
LOCAL_SRC_FILES := Chapter10.cpp \
(Other cpp Files . . . )
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 -lOpenSLES
LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
The Application.mk file is as below:
APP_PLATFORM := android-9
APP_STL := stlport_static
NDK_TOOLCHAIN_VERSION := 4.7
This was compiled using ADT v22.2.1 and Android NDK r9 on a Windows 7 Machine.
The NDK was installed to 'C:\ndk\android-ndk-r9\'.
Android NDK r9 contains the following toolchains:
arm-linux-androideabi-4.6
arm-linux-androideabi-4.8
arm-linux-androideabi-clang3.2
arm-linux-androideabi-clang3.3
llvm-3.2
llvm-3.3
mipsel-linux-android-4.6
mipsel-linux-android-4.8
mipsel-linux-android-clang3.2
mipsel-linux-android-clang3.3
x86-4.6
x86-4.8
x86-clang3.2
x86-clang3.3
There is no toolchain for gcc 4.7. However, your Application.mk contains the line:
NDK_TOOLCHAIN_VERSION := 4.7
Which tells the NDK to look for the 4.7 toolchain. And it fails.
So, the solution to your problem is changing the NDK_TOOLCHAIN_VERSION variable to 4.6, 4.8, clang3.2, clang3.3, or just clang (which will use the most recent version of Clang available in the NDK).
Check your project path if is contain spaces and non-english characters.
I moved my project into somewhere without spaces, re-build it and works.
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.