Compiling C++11 sources for Android NDK - android

I'm trying to compile some C++11 sources with Android NDK on Windows, but without much luck. Please note, that I've read some other questions about compiling C++11, but they didn't help much unfortunately.
I've downloaded the ADT Bundle and latest NDK (android-ndk-r9b-windows-x86.zip).
These are my configuration files:
Application.mk
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION = 4.8
LOCAL_CPP_FEATURES += exceptions
LOCAL_CFLAGS += -std=c++11
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := procalc-core
LOCAL_SRC_FILES := pcc_arithmetics.cpp \
pcc_arithmetics_tools.cpp \
pcc_common.cpp \
pcc_core.cpp \
pcc_dms_tokenizer.cpp \
pcc_dynamic_numerics.cpp \
pcc_exceptions.cpp \
pcc_expressiontree.cpp \
pcc_expression_containers.cpp \
pcc_messages.cpp \
pcc_numerics.cpp \
pcc_resolvers.cpp \
pcc_syntaxtree.cpp \
pcc_tokenizer.cpp \
sm_Bignum.cpp \
sm_Math2D.cpp \
sm_MathNumerics.cpp \
ss_Streams.cpp
include $(BUILD_SHARED_LIBRARY)
Build command
cd %AndroidProjects%ProCalc\jni\
D:\Android\ndk\ndk-build
pause
The error
That's actually one of the errors, but it's clearly not recognizing new C++11 keywords like auto or nullptr.
D:/(path)/jni/pcc_arithmetics.cpp: In static member function 'static
ProCalcCore::BaseNumeric* (* ProCalcCore::Arithmetics::GetFunctionMethod(std::string))
(const std::vector<const ProCalcCore::BaseNumeric*>&)':
D:/(path)/jni/pcc_arithmetics.cpp:4077:11: error: 'nullptr' was not declared in
this scope
return nullptr;
^
What am I doing wrong?

LOCAL_CPP_FEATURES += exceptions
LOCAL_CFLAGS += -std=c++11
Should go into Android.mk file. Alternatively, you could put
APP_CFLAGS += -std=c++11
into Application.mk. You can also use APP_CPPFLAGS instead, so that the C sources in your project (if you choose to add them) could compile (the C compiler will not like -std=c++11).

Related

How do you find an Android module by name in AOSP?

I am building AOSP Kitkat (4.4) and trying to find the Android.mk file that defines the libnfc-nci module. The libnfc_nci_jni module depends on this local shared library (Android.mk included below) and I want to see the source that generates this .so file. I know that the nfc.h exists in /hardware/libhardware/include/hardware/nfc.h, but that is only the headers.
As far as I know, the available tools for searching android source code are cgrep, jgrep, and resgrep. However, (to my knowledge) these don't search Android.mk files. Is there a tool that I'm missing that I can use to find the directory that contains the module libnfc-nci?
Here is the Android.mk for libnfc_nci_jni (found in /packages/apps/Nfc/nci/jni/Android.mk)
VOB_COMPONENTS := external/libnfc-nci/src
NFA := $(VOB_COMPONENTS)/nfa
NFC := $(VOB_COMPONENTS)/nfc
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
ifneq ($(NCI_VERSION),)
LOCAL_CFLAGS += -DNCI_VERSION=$(NCI_VERSION) -O0 -g
endif
LOCAL_CFLAGS += -Wall -Wextra
define all-cpp-files-under
$(patsubst ./%,%, \
$(shell cd $(LOCAL_PATH) ; \
find $(1) -name "*.cpp" -and -not -name ".*") \
)
endef
LOCAL_SRC_FILES:= $(call all-cpp-files-under, .)
LOCAL_C_INCLUDES += \
bionic \
bionic/libstdc++ \
external/stlport/stlport \
external/libxml2/include \
external/icu4c/common \
frameworks/native/include \
libcore/include \
$(NFA)/include \
$(NFA)/brcm \
$(NFC)/include \
$(NFC)/brcm \
$(NFC)/int \
$(VOB_COMPONENTS)/hal/include \
$(VOB_COMPONENTS)/hal/int \
$(VOB_COMPONENTS)/include \
$(VOB_COMPONENTS)/gki/ulinux \
$(VOB_COMPONENTS)/gki/common
LOCAL_SHARED_LIBRARIES := \
libicuuc \
libnativehelper \
libcutils \
libutils \
liblog \
libnfc-nci \
libstlport
LOCAL_STATIC_LIBRARIES := libxml2
LOCAL_MODULE := libnfc_nci_jni
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
I am running Ubuntu 14.04
I found libnfc-nci in /external/libnfc-nci after some more googling. It seems there is no better tool to search aosp for a module than google (unless you write your own script).
As Gabe Sechan noted, a grep solution is possible. Here is the command I used that seemed to do the trick (working directory is the root of AOSP).
grep -inIEr "LOCAL_MODULE := libnfc-nci" .
You should try :
godir libnfc-nci
It should give you options in case thete ae several such directories

Why do i get a unrecognized option '--dynamic-linker' error while Building avin2/SensorKinect for android, NDK, gcc

the makefiles i got from the git repo are looking like this:
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../../../Include/ \
$(LOCAL_PATH)/../../../../Source/ \
$(LOCAL_PATH)/../../../../Source/XnCommon \
$(LOCAL_PATH)/../../../../Source/External/LibJPEG \
LOCAL_CFLAGS := -fvisibility=hidden -DXN_FORMATS_EXPORTS
LOCAL_LDFLAGS += -Wl,--export-dynamic --dynamic-linker
LOCAL_SHARED_LIBRARIES := OpenNI libusb XnCore
LOCAL_PREBUILT_LIBS := libc
LOCAL_MODULE := XnFormats
ok the pushed the makefiles with a little syntax error - it worked like this (no space,comma)
LOCAL_LDFLAGS += -Wl,--export-dynamic,--dynamic-linker

Android NDK linking C module with C++ app

This is my complete Android.mk file, when I try to build this, I get a linker problem (see further down)
LOCAL_PATH := $(call my-dir)
#
# Opus - low-latency audio codec
#
include $(CLEAR_VARS)
LOCAL_DIR := opus-1.0.3
LOCAL_MODULE := opus
LOCAL_CELT_SOURCES := \
$(LOCAL_DIR)/celt/bands.c \
...
LOCAL_SILK_SOURCES := \
$(LOCAL_DIR)/silk/CNG.c \
...
LOCAL_SILK_SOURCES_FIXED := \
$(LOCAL_DIR)/silk/fixed/LTP_analysis_filter_FIX.c \
...
LOCAL_SILK_SOURCES_FLOAT := \
$(LOCAL_DIR)/silk/float/apply_sine_window_FLP.c \
...
LOCAL_OPUS_SOURCES := \
$(LOCAL_DIR)/src/opus.c \
...
LOCAL_CFLAGS := -DNONTHREADSAFE_PSEUDOSTACK
LOCAL_C_INCLUDES := \
$(LOCAL_DIR)/include \
$(LOCAL_DIR)/celt \
$(LOCAL_DIR)/silk \
$(LOCAL_DIR)/silk/fixed \
$(LOCAL_DIR)/silk/float
LOCAL_SRC_FILES := $(LOCAL_CELT_SOURCES) \
$(LOCAL_SILK_SOURCES) \
$(LOCAL_SILK_SOURCES_FIXED) \
$(LOCAL_SILK_SOURCES_FLOAT)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_DIR)/include
include $(BUILD_STATIC_LIBRARY)
################
include $(CLEAR_VARS)
LOCAL_MODULE := audio-client-jni
LOCAL_SRC_FILES := audio-client-jni.cpp
# low latency codec
LOCAL_STATIC_LIBRARIES += opus
# for native audio
LOCAL_LDLIBS += -lOpenSLES
# for logging
LOCAL_LDLIBS += -llog
# for native asset manager
LOCAL_LDLIBS += -landroid
include $(BUILD_SHARED_LIBRARY)
To rule out that there's a problem with the way opus is being built I've done the exact same thing using a different build system called tundra and it compliles just fine on Windows using MSVC++.
Here's the linker command and errors (I've formatted the command-line for readability)
C:/Projects/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++
-Wl,-soname,libaudio-client-jni.so
-shared
--sysroot=C:/Projects/android-ndk-r8e/platforms/android-14/arch-arm
C:/Projects/workspace/AudioClient//obj/local/armeabi/objs/audio-client-jni/audio-client-jni.o
C:/Projects/workspace/AudioClient//obj/local/armeabi/libopus.a
C:/Projects/workspace/AudioClient//obj/local/armeabi/libstdc++.a
-lgcc
-no-canonical-prefixes
-Wl,--no-undefined
-Wl,-z,noexecstack
-Wl,-z,relro
-Wl,-z,now
-LC:/Projects/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib
-lOpenSLES
-llog
-landroid
-lstdc++
-lc
-lm
-o C:/Projects/workspace/AudioClient//obj/local/armeabi/libaudio-client-jni.so
errors follow
C:/Projects/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: C:/Projects/workspace/AudioClient//obj/local/armeabi/objs/audio-client-jni/audio-client-jni.o: in function (anonymous namespace)::AuClient::ReceiveThenEnqueue():C:/Projects/workspace/AudioClient//jni/audio-client-jni.cpp:419: error: undefined reference to 'opus_decode'
C:/Projects/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: C:/Projects/workspace/AudioClient//obj/local/armeabi/objs/audio-client-jni/audio-client-jni.o: in function InitializeThread:C:/Projects/workspace/AudioClient//jni/audio-client-jni.cpp:387: error: undefined reference to 'opus_decoder_create'
I need a second pair of eyes on this, it's definetly linking audio-client-jni.o before libopus.a but if that is the issue I don't understand how to modify the makefile to get the desiered result. The opus.h API is defined with extern "C" when included in a C++ app. No luck so far.
Thanks to #AlexCohn for the assist, obviously there wasn't anything wrong, instead all the source files wasn't included properly, slight overlook from my part.
In my case, I wasn't sure how I should set things up to be able to run the bin util commands, luckily, it's as simple as:
"C:\Projects\android-ndk-r8e\toolchains\arm-linux-androideabi-4.6\prebuilt\windows-x86_64\bin\arm-linux-androideabi-nm.exe" "C:\Projects\workspace\AudioClient\obj\local\armeabi\libopus.a"
I just picked what seemed reasonable from the prebuilt toolchain.
With the output from nm I could verify that the exports weren't there. After closer inspection I noticed I had forgotten to include $(LOCAL_OPUS_SOURCES) in my LOCAL_C_INCLUDES. Fixing that, fixed the problem.

libjpeg-turbo for android

I need libjpeg-turbo for android ndk. Did anyone managed to compile it as .a (static) lib?
I have tried a few times, but it gave me a lot of errors only.
Install Android NDK. Following instructions were verified with r8b, older versions may have problems, I don't know.
Get the Android sources for libjpeg-turbo from Benjamin Gaignard:
git clone git://git.linaro.org/people/tomgall/libjpeg-turbo/libjpeg-turbo.git -b linaro-android
In the libjpeg-turbo directory created by git, edit file Android.mk: after line 70, LOCAL_MODULE := libjpeg, add the following:
ifeq ($(notdir $(MAKECMDGOALS)),libjpeg.a)
LOCAL_SRC_FILES += $(libsimd_SOURCES_DIST)
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := dummy
endif
Run ndk-build:
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk obj/local/armeabi/libjpeg.a
Profit!
PS: You may want the armeabi-v7a version:
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=armeabi-v7a obj/local/armeabi-v7a/libjpeg.a
Or compile for ARM, to improve performance, add to command line:
LOCAL_ARM_MODE=arm
If your target has NEON support, add to command line:
LOCAL_ARM_NEON=true ARCH_ARM_HAVE_NEON=true
UPDATE: to get it work with Android NDK r15 and later, remove all references to libcutils from Android.mk.
This answer expands on Alex Cohn's answer. Full credit goes to him for getting me started. This answer will allow you to build libjpeg-turbo with assembly for ARM (with or without NEON) as well as x86. Compatibility is also provided for MIPS so that you can be a good citizen and build your app for all of the platforms that the r8e version of the Android NDK supports.
I still a relative newbie to actually answering questions, so don't have permissions to include attachments. So I'm going to have to inline a bunch of code. I'm also sure there are better ways to do bits and pieces of the below, so am open to suggestions for improvement.
Getting this all to work was done in six main steps (step two has many sub-steps -- each of which can be found after the main six steps):
Download via git the libjpeg-turbo library containing a set of code and .mk files for Android. I downloaded it from here with git:
git clone git://git.linaro.org/people/tomgall/libjpeg-turbo/libjpeg-turbo.git -b linaro-android
Full credit and thanks must be given to Tom Gall for doing the initial work.
Download YASM (an assembler for x86) and configure the Android build environment to support it. See the set of instructions on configuring YASM for the Android NDK that I am including below the horizontal rule at the end of my Android.mk changes in step 6. Supporting x86 requires that you aren't shy about tweaking the NDK install.
I perhaps could have used the NASM compiler, but was far enough down the YASM path before investigating NASM that I brought the YASM path to completion.
Create the simd/jsmidcfg.inc file. The libjpeg-turbo library provides simd/jsmidcfg.inc.h. It is meant for the pre-processor to take the .h and convert it to a .inc. I'm sure there is a better way for it to happen than what I did. But couldn't get it sorted out due to time pressures. Instead, I manually ran one the gcc that came with Android to create the file using the following command:
C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.4.3\prebuilt\windows-x86_64\bin\i686-linux-android-gcc.exe -E C:\development\thirdparty\libjpeg-turbo\libjpeg-turbo-android-1.2.0\simd\jsimdcfg.inc.h -o C:\development\thirdparty\libjpeg-turbo\libjpeg-turbo-android1.2.0\simd\jsimdcfg.inc
After the pre-processor completed, I had to hand-edit the file to get it into a usable state. I had to select all of the lines above "; -- jpeglib.h" and delete them.
Next, I had to find each of the %defines that started with _cpp_protection_ and duplicate each of those %defines WITHOUT the _cpp_protection_. For example, %define _cpp_protection_RGB_RED 0 became %define RGB_RED 0
For ARM, I wanted my code to dynamically support NEON instructions on hardware that had it, and to fallback to something simpler on hardware that didn't, I modified simd/jsimd_arm.c to dynamically query for the information. I didn't want to have to make that choice when building libjpeg-turbo.
I added the following lines of code:
#ifdef ANDROID
#include <cpufeatures/cpu-features.h>
#endif
and
#ifdef ANDROID
uint64_t cpuFeatures = android_getCpuFeatures();
if (cpuFeatures & ANDROID_CPU_ARM_FEATURE_NEON) {
simd_support |= JSIMD_ARM_NEON;
}
#endif
within the init_simd() method.
Enabling MIPS.
To be a good citizen, I wanted to enable compilation on MIPS. While there isn't any assembler code for MIPS, the code should at least compile and run. To do that, I copied simd/jsimd_arm.c to simd/jsimd_mips.c. I edited the file so that init_simd() set simd_support = 0; I also changed all of the jsimd_can_*() methods to return 0. Finally, I removed the implementation from all of the other methods.
Because I was interested in more than just a build for ARM, I changed the Application.mk file to include the following lines:
APP_ABI := all
APP_OPTIM := release
The APP_OPTIM comes from How to optimize a native code with android-ndk (Speed Optimization)
Within Android.mk, I commented out everything from the "cjpeg" comment block and below. To do a block comment, I followed the advice of How to add multi line comments in makefiles
I next customized the Android.mk file itself so that I could build for all currently supported CPUs (ARM, x86, MIPS). Here is what I ended up with (some code commented out because I wanted a static library -- also to leave the original code in place so I can see what changed). You will most likely have to change (or remove) the addprefix method calls because the file below is customized for my build environment. But other than that, it should work for you.
.
##################################################
### simd ###
##################################################
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#ifeq ($(ARCH_ARM_HAVE_NEON),true)
#LOCAL_CFLAGS += -D__ARM_HAVE_NEON
#endif
# From autoconf-generated Makefile
EXTRA_DIST = simd/nasm_lt.sh simd/jcclrmmx.asm simd/jcclrss2.asm simd/jdclrmmx.asm simd/jdclrss2.asm \
simd/jdmrgmmx.asm simd/jdmrgss2.asm simd/jcclrss2-64.asm simd/jdclrss2-64.asm \
simd/jdmrgss2-64.asm simd/CMakeLists.txt
#libsimd_SOURCES_DIST = simd/jsimd_arm_neon.S \
simd/jsimd_arm.c
libsimd_SOURCES_DIST :=
ifeq ($(TARGET_ARCH),arm)
libsimd_SOURCES_DIST := simd/jsimd_arm_neon.S \
simd/jsimd_arm.c
endif
ifeq ($(TARGET_ARCH),x86)
#libsimd_SOURCES_DIST := simd/jsimd_mips.c
# List of assembly files needed is derived from content within simd/CMakelists.txt
# The Intel Atom supports x86 32-bit assembly. So take those files and leave the
# 64-bit behind.
libsimd_SOURCES_DIST := simd/jsimd_i386.c \
simd/jsimdcpu.asm simd/jccolmmx.asm simd/jcgrammx.asm simd/jdcolmmx.asm simd/jcsammmx.asm simd/jdsammmx.asm \
simd/jdmermmx.asm simd/jcqntmmx.asm simd/jfmmxfst.asm simd/jfmmxint.asm simd/jimmxred.asm simd/jimmxint.asm simd/jimmxfst.asm simd/jcqnt3dn.asm \
simd/jf3dnflt.asm simd/ji3dnflt.asm simd/jcqntsse.asm simd/jfsseflt.asm simd/jisseflt.asm simd/jccolss2.asm simd/jcgrass2.asm simd/jdcolss2.asm \
simd/jcsamss2.asm simd/jdsamss2.asm simd/jdmerss2.asm simd/jcqnts2i.asm simd/jfss2fst.asm simd/jfss2int.asm simd/jiss2red.asm simd/jiss2int.asm \
simd/jiss2fst.asm simd/jcqnts2f.asm simd/jiss2flt.asm
endif
ifeq ($(TARGET_ARCH),mips)
libsimd_SOURCES_DIST := simd/jsimd_mips.c
endif
#LOCAL_SRC_FILES := $(libsimd_SOURCES_DIST)
#LOCAL_SRC_FILES := $(addprefix ../../libjpeg-turbo-android-1.2.0/,$(LOCAL_SRC_FILES))
LOCAL_C_INCLUDES := $(LOCAL_PATH)/simd \
$(LOCAL_PATH)/android
LOCAL_C_INCLUDES := simd android
#LOCAL_C_INCLUDES := $(addprefix ../../libjpeg-turbo-android-1.2.0/,$(LOCAL_C_INCLUDES))
#AM_CFLAGS := -march=armv7-a -mfpu=neon
#AM_CCASFLAGS := -march=armv7-a -mfpu=neon
#LOCAL_MODULE_TAGS := debug
#LOCAL_MODULE := libsimd
#include $(BUILD_STATIC_LIBRARY)
######################################################
### libjpeg.so ##
######################################################
#include $(CLEAR_VARS)
# From autoconf-generated Makefile
libjpeg_SOURCES_DIST = jcapimin.c jcapistd.c jccoefct.c jccolor.c \
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c \
jaricom.c jcarith.c jdarith.c \
turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c #\
turbojpeg-mapfile
LOCAL_SRC_FILES:= $(libjpeg_SOURCES_DIST) $(libsimd_SOURCES_DIST)
#LOCAL_SRC_FILES:= $(libjpeg_SOURCES_DIST)
LOCAL_SRC_FILES := $(addprefix ../../../libjpeg-turbo-android-1.2.0/,$(LOCAL_SRC_FILES))
#LOCAL_SHARED_LIBRARIES := libcutils
#LOCAL_STATIC_LIBRARIES := libsimd
#LOCAL_C_INCLUDES := $(LOCAL_PATH)
# Include C:/development/android/ide/android-ndk-r8e-windows-x86_64/sources/android
# instead of the lower-level cpufeatures because of how I had to include
# cpu-features.h. It appears as if there is a naming conflict, so I had to
# change how the file was included to avoid naming conflicts.
LOCAL_C_INCLUDES := $(addprefix ../../../libjpeg-turbo-android-1.2.0/,$(LOCAL_C_INCLUDES)) \
C:/development/thirdparty/libjpeg-turbo/libjpeg-turbo-android-1.2.0 \
C:/development/android/ide/android-ndk-r8e-windows-x86_64/sources/android
#LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES)) ./
#LOCAL_C_INCLUDES := $(addprefix $(LOCAL_PATH),$(LOCAL_C_INCLUDES)) $(LOCAL_PATH)../../../libjpeg-turbo-android-1.2.0/
LOCAL_CFLAGS := -DAVOID_TABLES -O3 -fstrict-aliasing -fprefetch-loop-arrays -DANDROID \
-DANDROID_TILE_BASED_DECODE -DENABLE_ANDROID_NULL_CONVERT
LOCAL_CFLAGS += -DJPEG_LIB_VERSION=80 # I need version 8 because of some of the methods I depend on
LOCAL_YASMFLAGS := -P../../libjpeg-turbo-android-1.2.0/simd/jsimdcfg.inc
#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_STATIC_LIBRARY)
#LOCAL_MODULE_TAGS := debug
#LOCAL_MODULE := libjpeg
LOCAL_MODULE := jpeg-turbo
#include $(BUILD_SHARED_LIBRARY)
#LOCAL_STATIC_LIBRARIES := cpufeatures
include $(BUILD_STATIC_LIBRARY)
# We reference android/cpufeatures in the Android.mk file of our main app, so
# we don't need to do anything here.
#$(call import-module,android/cpufeatures)
Some of the source code that ships with libjpeg-turbo is in .asm format. That is, it needs to be compiled with the NASM assembler. As it ships, the Android NDK doesn't have support for it.
To get .asm support working with NDK, I followed the rough outline presented here: http://software.intel.com/en-us/articles/using-yasm-compiler-on-android-ndkbuild
Here are a set of more detailed instructions. Within android-ndk-r8\build\core, the following things need to occur:
build-binary.mk:
all_source_extensions := .c .s .S $(LOCAL_CPP_EXTENSION) => all_source_extensions := .c .s .asm .S $(LOCAL_CPP_EXTENSION)
For me, the above was on line 228.
After the line that starts with: "# Build the sources to object files" you will see several foreach loops. Add one like this (I added it on line 272):
$(foreach src,$(filter %.asm,$(LOCAL_SRC_FILES)), $(call compile-asm-source,$(src),$(call get-object-name,$(src))))
definitions.mk:
Create a new compile-asm-source to match the new entry we added within the new for loop above. We also have to add a new define within the make file. I added the following. It is a combination and simplification of the various rules used to build .c files. We need a different set of options when using yasm that necessitate these changes.
define ev-compile-asm-source
_SRC:=$$(LOCAL_PATH)/$(1)
_OBJ:=$$(LOCAL_OBJS_DIR)/$(2)
_FLAGS := -f elf -DELF -DPIC $$(LOCAL_YASMFLAGS)
_TEXT := "Compile $$(call get-src-file-text,$1)"
_CC := $$(NDK_CCACHE) $$(TARGET_ASM)
$$(_OBJ): PRIVATE_SRC := $$(_SRC)
$$(_OBJ): PRIVATE_OBJ := $$(_OBJ)
$$(_OBJ): PRIVATE_DEPS := $$(call host-path,$$(_OBJ).d)
$$(_OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE)
$$(_OBJ): PRIVATE_TEXT := "$$(_TEXT)"
$$(_OBJ): PRIVATE_CC := $$(_CC)
$$(_OBJ): PRIVATE_CFLAGS := $$(_FLAGS)
ifeq ($$(LOCAL_SHORT_COMMANDS),true)
_OPTIONS_LISTFILE := $$(_OBJ).cflags
$$(_OBJ): $$(call generate-list-file,$$(_FLAGS),$$(_OPTIONS_LISTFILE))
$$(_OBJ): PRIVATE_CFLAGS := #$$(call host-path,$$(_OPTIONS_LISTFILE))
$$(_OBJ): $$(_OPTIONS_LISTFILE)
endif
$$(call generate-file-dir,$$(_OBJ))
$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) $$(NDK_DEPENDENCIES_CONVERTER)
#$$(HOST_ECHO) "$$(PRIVATE_TEXT) : $$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))"
$$(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) $$(call host-path,$$(PRIVATE_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ)) \
$$(call cmd-convert-deps,$$(PRIVATE_DEPS))
endef
compile-asm-source = $(eval $(call ev-compile-asm-source,$1,$2))
Search for the line that starts with 'compile-s-source'. I found it at line 1491. The new compile-asm-source can go right below that.
Next, search for the line that starts with "get-object-name". I found it at line 1270. Add ".asm" to the inner for-loop. Put it together with the .c, .s, and .S
import-locals.mk:
Add the following line below the LOCAL_CFLAGS and the LOCAL_CPPFLAGS line
LOCAL_YASMFLAGS := $(LOCAL_CFLAGS) $(strip $(LOCAL_YASMFLAGS))
default-build-commands.mk:
Add the following line anywhere in the file. I put mine under the TARGET_CXX section and above the TARGET_LD section.
TARGET_ASM = $(TOOLCHAIN_PREFIX)yasm
Download and copy yasm.exe to the build folders:
Download a copy of YASM from here: http://yasm.tortall.net/
I have the Win64 version of the NDK, so downloaded the Win64 version of YASM. If you have the Win32 version of the NDS, download th Win32 version of YASM.
You should just get the .exe. Copy it to the following directories as yasm.exe. If you have any other toolchain versions, copy it to those directories as well:
C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.4.3\prebuilt\windows-x86_64\i686-linux-android\bin
C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.6\prebuilt\windows-x86_64\i686-linux-android\bin
C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.7\prebuilt\windows-x86_64\i686-linux-android\bin
Then, copy the file again to the directories below as i686-linux-android-yasm.exe. And as above, if you have any other toolchain versions, copy it to those directories as well:
C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.4.3\prebuilt\windows-x86_64\bin
C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.6\prebuilt\windows-x86_64\bin
C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.7\prebuilt\windows-x86_64\bin
Thanks Alex Cohn and answered Dec for share;
This answer expands on Alex Cohn's answer & answered Dec's answer;
I'm use jpeg turbo 1.3.9, ndk-r9d, about yasm.exe, the ndk-r9d is contained, on after did answered Dec's step 3, I had one error in simd/jsimdext.inc line:182 "%define EXTN(name) _ %+ name ; foo() -> _foo"; change it to "%define EXTN(name) name"; then ok, this problem had fixed;
this is my Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -D__ARM_HAVE_NEON
#ifeq ($(ARCH_ARM_HAVE_NEON),true)
#LOCAL_CFLAGS += -D__ARM_HAVE_NEON
#endif
# From autoconf-generated Makefile
EXTRA_DIST = nasm_lt.sh CMakeLists.txt \
jccolext-mmx.asm jcgryext-mmx.asm jdcolext-mmx.asm jdmrgext-mmx.asm \
jccolext-sse2.asm jcgryext-sse2.asm jdcolext-sse2.asm jdmrgext-sse2.asm \
jccolext-sse2-64.asm jcgryext-sse2-64.asm jdcolext-sse2-64.asm \
jdmrgext-sse2-64.asm
ifeq ($(TARGET_ARCH),arm)
libsimd_SOURCES_DIST := simd/jsimd_arm_neon.S \
simd/jsimd_arm.c
AM_CFLAGS := -march=armv7-a -mfpu=neon
AM_CCASFLAGS := -march=armv7-a -mfpu=neon
endif
ifeq ($(TARGET_ARCH),x86)
# List of assembly files needed is derived from content within simd/CMakelists.txt
# The Intel Atom supports x86 32-bit assembly. So take those files and leave the
# 64-bit behind.
#libsimd_SOURCES_DIST := simd/jsimd_i386.c \
simd/jsimdcpu.asm \
simd/jfdctflt-3dn.asm \
simd/jidctflt-3dn.asm \
simd/jquant-3dn.asm \
simd/jccolor-mmx.asm \
simd/jcgray-mmx.asm \
simd/jcsample-mmx.asm \
simd/jdcolor-mmx.asm \
simd/jdmerge-mmx.asm \
simd/jdsample-mmx.asm \
simd/jfdctfst-mmx.asm \
simd/jfdctint-mmx.asm \
simd/jidctfst-mmx.asm \
simd/jidctint-mmx.asm \
simd/jidctred-mmx.asm \
simd/jquant-mmx.asm \
simd/jfdctflt-sse.asm \
simd/jidctflt-sse.asm \
simd/jquant-sse.asm \
simd/jccolor-sse2.asm \
simd/jcgray-sse2.asm \
simd/jcsample-sse2.asm \
simd/jdcolor-sse2.asm \
simd/jdmerge-sse2.asm \
simd/jdsample-sse2.asm \
simd/jfdctfst-sse2.asm \
simd/jfdctint-sse2.asm \
simd/jidctflt-sse2.asm \
simd/jidctfst-sse2.asm \
simd/jidctint-sse2.asm \
simd/jidctred-sse2.asm \
simd/jquantf-sse2.asm \
simd/jquanti-sse2.asm
libsimd_SOURCES_DIST := simd/jsimd_i386.c simd/jsimd.h simd/jsimdcfg.inc.h simd/jsimdext.inc \
simd/jcolsamp.inc simd/jdct.inc simd/jsimdcpu.asm \
simd/jfdctflt-3dn.asm simd/jidctflt-3dn.asm simd/jquant-3dn.asm \
simd/jccolor-mmx.asm simd/jcgray-mmx.asm simd/jcsample-mmx.asm \
simd/jdcolor-mmx.asm simd/jdmerge-mmx.asm simd/jdsample-mmx.asm \
simd/jfdctfst-mmx.asm simd/jfdctint-mmx.asm simd/jidctfst-mmx.asm \
simd/jidctint-mmx.asm simd/jidctred-mmx.asm simd/jquant-mmx.asm \
simd/jfdctflt-sse.asm simd/jidctflt-sse.asm simd/jquant-sse.asm \
simd/jccolor-sse2.asm simd/jcgray-sse2.asm simd/jcsample-sse2.asm \
simd/jdcolor-sse2.asm simd/jdmerge-sse2.asm simd/jdsample-sse2.asm \
simd/jfdctfst-sse2.asm simd/jfdctint-sse2.asm simd/jidctflt-sse2.asm \
simd/jidctfst-sse2.asm simd/jidctint-sse2.asm simd/jidctred-sse2.asm \
simd/jquantf-sse2.asm simd/jquanti-sse2.asm
endif
ifeq ($(TARGET_ARCH),mips)
libsimd_SOURCES_DIST := simd/jsimd_mips.c
endif
LOCAL_C_INCLUDES := $(LOCAL_PATH)/simd \
$(LOCAL_PATH)/android
LOCAL_SRC_FILES:= $(libsimd_SOURCES_DIST)
LOCAL_CFLAGS := -DAVOID_TABLES -O3 -fstrict-aliasing -fprefetch-loop-arrays -DANDROID \
-DANDROID_TILE_BASED_DECODE -DENABLE_ANDROID_NULL_CONVERT
LOCAL_CFLAGS += -DJPEG_LIB_VERSION=80 # I need version 8 because of some of the methods I depend on
$(warning "libsimd")
LOCAL_MODULE := libsimd
LOCAL_MODULE_FILENAME := libsimd
include $(BUILD_STATIC_LIBRARY)
######################################################
### libjpeg.so ##
######################################################
#include $(CLEAR_VARS)
# From autoconf-generated Makefile
libjpeg_SOURCES_DIST = jcapimin.c jcapistd.c jccoefct.c jccolor.c \
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c \
jaricom.c jcarith.c jdarith.c \
turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c \
turbojpeg-mapfile
LOCAL_SRC_FILES:= $(libjpeg_SOURCES_DIST)
LOCAL_SHARED_LIBRARIES += libcutils
LOCAL_STATIC_LIBRARIES += libsimd
LOCAL_C_INCLUDES := $(LOCAL_PATH)
$(warning "libjpeg")
LOCAL_CFLAGS := -DAVOID_TABLES -O3 -fstrict-aliasing -fprefetch-loop-arrays -DANDROID \
-DANDROID_TILE_BASED_DECODE -DENABLE_ANDROID_NULL_CONVERT
LOCAL_CFLAGS += -DJPEG_LIB_VERSION=80 # I need version 8 because of some of the methods I depend on
#D:\android-ndk-r9d\toolchains\x86-4.8\prebuilt\windows-x86_64\bin\i686-linux-android-gcc.exe -E D:\WORKSPACE\MINE\libjpeg_turbo_1.3.9_multi_platform\jni\simd\jsimdcfg.inc.h -o D:\WORKSPACE\MINE\libjpeg_turbo_1.3.9_multi_platform\jni\simd\jsimdcfg.inc
LOCAL_MODULE := libjpeg
LOCAL_MODULE_FILENAME:=libjpeg
LOCAL_STATIC_LIBRARIES += cpufeatures
include $(BUILD_STATIC_LIBRARY)
For anyone trying to build the official repo version, I had success using the patch attached here: libjpeg-turbo cross-compile to Android fails.
Then, depending on whether you're compiling for 32-bit or 64-bit:
export CFLAGS="-DSIZEOF_SIZE_T=4"
or
export CFLAGS="-DSIZEOF_SIZE_T=4"
And run cmake with -DWITH_SIMD=FALSE -DCMAKE_TOOLCHAIN_FILE=your_toolchain_file.
Of course, I'm aware that disabling SIMD is not ideal, but at least I managed to get a build I can start using. Hopefully, the buildsystem's NEON SIMD support will get fixed, in the future. Using ./configure also failed to build the correct SIMD for ARM.
Incidentally, I wish folks would contribute fixes to the main repo, rather than simply forking it. It's been 2 years since the last change to the repo cited in alex-cohn's answer.

Compiling tesseract through android NDK

I am trying to compile tesseract for android using android ndk r5, code of tesseract is obtained by checking out http://code.google.com/p/tesseract-android-tools/, i am unable to compile tesseract and got errors,
Install : libjpeg.so => libs/armeabi/libjpeg.so
make: *** No rule to make target `//cygdrive/e/DemoExamples_WorkSpace/tesseract-android-tools/jni/../external/leptonlib-1.66/src/adaptmap.c', needed b
y `/cygdrive/e/DemoExamples_WorkSpace/tesseract-android-tools/obj/local/armeabi/objs/lept//cygdrive/e/DemoExamples_WorkSpace/tesseract-android-tools/j
ni/../external/leptonlib-1.66/src/adaptmap.o'. Stop.
Please help me to sort out this problem.
I had the same issue and I think I solved it. May be helpful for those who get similar errors:
On OSX, I just changed the Android.mk files by giving the absolute paths as follows
First: jni/Android.mk
TESSERACT_PATH := /Users/.../tesseract-android-tools/tesseract-android-tools/external/tesseract-3.00
LEPTONICA_PATH := /Users/.../tesseract-android-tools/tesseract-android-tools/external/leptonlib-1.66
LIBJPEG_PATH := /Users/.../tesseract-android-tools/tesseract-android-tools/external/libjpeg
Then: jni/com_googlecode_leptonica_android/Android.mk
REAL_LOCAL_PATH := /Users/.../tesseract-android-tools/tesseract-android-tools/jni/com_googlecode_leptonica_android
and jni/com_googlecode_tesseract_android/Android.mk accordingly.
I believe the problem is caused by the relative path which is returned by the following command:
$(call my-dir)
Then I needed to run the ndk-build as superuser and all compiled just fine.
Search for adaptmap among the makefiles. Build the makefile that creates this module first.
So, I have compiled in windows 7 and windows xp, but it´s an ugly workaround.
The basic problem is "LOCAL_PATH := "with blank value, I don´t know why cygwin have problem with this, so you have to change paths on Android.mk files to work.
I will refer for Android.mk using numbers, my jni path is:
-jni
Android.mk(1)
Aplication.Mk
-com_googlecode_tesseract_android(dir)
Android.mk(2)
tesseract(dir)
-com_googlecode_leptonica_android(dir)
Android.mk(3)
leptonlib(dir)
-libjpeg
Android.mk(4)
=================================
Android.mk(1)
Put tesseract and leptonica sources on googlecode subdirectories like this:
TESSERACT_PATH := $(call my-dir)/com_googlecode_tesseract_android/tesseract -- directory to source, change for respective name
LEPTONICA_PATH := $(call my-dir)/com_googlecode_leptonica_android/leptonlib -- directory to source, change for respective name
LIBJPEG_PATH := $(call my-dir)/libjpeg
=================================
Android.mk(2)
1 - Change:
LOCAL_PATH:=
to
LOCAL_PATH:= $(call my-dir)
2 - Change:
BLACKLIST_SRC_FILES := \
%endiantest.c \
%freetype.c \
%xtractprotos.c
LOCAL_SRC_FILES := \
$(filter-out $(BLACKLIST_SRC_FILES),$(wildcard $(LEPTONICA_PATH)/src/*.c))
to
LOCAL_SRC_FILES := \
leptonlib/src/adaptmap.c \
leptonlib/src/affine.c \
leptonlib/src/affinecompose.c \ ... continue (Put all the files on src directory, without files listed on blacklist).
Note: replace leptonlib for subrectory name of leptonlib source.
3- Change:
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SRC_FILES += \
$(REAL_LOCAL_PATH)/stdio/open_memstream.c \
$(REAL_LOCAL_PATH)/stdio/fopencookie.c \
$(REAL_LOCAL_PATH)/stdio/fmemopen.c
LOCAL_C_INCLUDES += \
$(REAL_LOCAL_PATH)/stdio
endif
# jni
LOCAL_SRC_FILES += \
$(REAL_LOCAL_PATH)/box.cpp \
$(REAL_LOCAL_PATH)/pix.cpp \
$(REAL_LOCAL_PATH)/pixa.cpp \
$(REAL_LOCAL_PATH)/utilities.cpp \
$(REAL_LOCAL_PATH)/readfile.cpp \
$(REAL_LOCAL_PATH)/writefile.cpp \
$(REAL_LOCAL_PATH)/jni.cpp
LOCAL_C_INCLUDES += \
$(REAL_LOCAL_PATH) \
$(LEPTONICA_PATH)/src
to
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SRC_FILES += \
stdio/open_memstream.c \
stdio/fopencookie.c \
stdio/fmemopen.c
LOCAL_C_INCLUDES += \
stdio
endif
# jni
LOCAL_SRC_FILES += \
box.cpp \
pix.cpp \
pixa.cpp \
utilities.cpp \
jni.cpp
LOCAL_C_INCLUDES += \
leptonlib/src
=================================
Android.mk(3)
1 - Change:
LOCAL_PATH:=
to
LOCAL_PATH:= $(call my-dir)
2 - Change
On LOCAL_SRC_FILES change $(TESSERACT_PATH) to tesseract --Note: replace tesseract for subrectory name of tesseract source.
DON´T REPLACE $(TESSERACT_PATH) on LOCAL_C_INCLUDES only LOCAL_SRC_FILES.
DON´T REPLACE $(LEPTONICA_PATH) on LOCAL_C_INCLUDES.
3 - Change:
In #jni
LOCAL_SRC_FILES += \
$(REAL_LOCAL_PATH)/tessbaseapi.cpp
LOCAL_C_INCLUDES += \
$(REAL_LOCAL_PATH) \
$(TESSERACT_PATH)/api \
$(LEPTONICA_PATH)/src
to
LOCAL_SRC_FILES += \
tessbaseapi.cpp
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(TESSERACT_PATH)/api \
$(LEPTONICA_PATH)/src
For me working on windows 7, windows xp, Mac and Ubuntu.

Categories

Resources