I am try to build Android Cpp project using Ndk.
when i build app its only generate jni folder files
cannot generate jni sub folder files
i got this error
make: *** No rule to make target src/main/jni/src/main/jni/A/B/Helper.cpp', needed bybuild/intermediates/ndk/obj/local/armeabi/objs/demo/src/main/jni/A/B/Helper.o'. Stop.
TOP_LOCAL_PATH:=$(call my-dir)
LOCAL_PATH := $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := demo
LOCAL_SRC_FILES := a.cpp b.cpp c.cpp d.cpp
LOCAL_SRC_FILES := $(LOCAL_PATH)/A/B/Helper.cpp
LOCAL_CFLAGS += -std=c++11 -frtti -fexceptions -fpermissive
LOCAL_LDLIBS += -llog -lGLESv2 -lEGL -landroid -lOpenSLES -lGLESv1_CM -lz
LOCAL_C_INCLUDES := $(LOCAL_PATH)/A/B
include $(BUILD_SHARED_LIBRARY)
The file names that are listed in LOCAL_SRC_FILES are relative to LOCAL_PATH. ALso, you can define this list on multiple lines, but by appending the list, not replacing it.
So, your Android.mk file should probably look like this:
TOP_LOCAL_PATH:=$(call my-dir)
LOCAL_PATH := $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := demo
LOCAL_SRC_FILES := a.cpp b.cpp c.cpp d.cpp
LOCAL_SRC_FILES += A/B/Helper.cpp
LOCAL_CFLAGS += -std=c++11 -frtti -fexceptions -fpermissive
LOCAL_LDLIBS += -llog -lGLESv2 -lEGL -landroid -lOpenSLES -lGLESv1_CM -lz
LOCAL_C_INCLUDES := $(LOCAL_PATH)/A/B
include $(BUILD_SHARED_LIBRARY)
Note that the list LOCAL_C_INCLUDES should use full paths.
Related
I am getting error during ndk build. I have only one android.mk file and only one Application.mk file in my project
Android NDK: Trying to define local module 'protobuf' in /home/parag.j/AndroidArm//jni/Android.mk.
Android NDK: But this module was already defined by /home/parag.j/AndroidArm//jni/Android.mk.
Here is my Android.mk file
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE=ndktest
LOCAL_SRC_FILES=ndktest.cpp
include $(CLEAR_VARS)
LOCAL_MODULE := c++_shared
LOCAL_SRC_FILES := $(LOCAL_PATH)/inc/build/libc++_shared.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := armnn
LOCAL_SRC_FILES := $(LOCAL_PATH)/inc/build/libarmnn.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := armnnTfParser
LOCAL_SRC_FILES := $(LOCAL_PATH)/inc/build/libarmnnTfParser.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := protobuf
LOCAL_SRC_FILES := $(LOCAL_PATH)/inc/build/libprotobuf.so
include $(PREBUILT_SHARED_LIBRARY)
LOCAL_LDLIBS += -lm -llog -landroid
LOCAL_CFLAGS += -DARM_NEON_64BIT -O3 -mfpu=neon -mcpu=kryo -std=c++14 -pie
LOCAL_SHARED_LIBRARIES := opencv_java3 armnn armnnTfParser protobuf c++_shared
LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc/include\
include $(BUILD_SHARED_LIBRARY)
Here is my Application.mk file
APP_ABI:=arm64-v8a
APP_CFLAGS += -Ofast
APP_OPTIM := release
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM := android-22
ANDROID_TOOLCHAIN_NAME := clang++
You forgot to (re)set LOCAL_MODULE for the last part of your makefile. I think the last few lines should be:
LOCAL_MODULE=ndktest
LOCAL_SRC_FILES=ndktest.cpp
LOCAL_LDLIBS += -lm -llog -landroid
LOCAL_CFLAGS += -DARM_NEON_64BIT -O3 -mfpu=neon -mcpu=kryo -std=c++14 -pie
LOCAL_SHARED_LIBRARIES := opencv_java3 armnn armnnTfParser protobuf c++_shared
LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc/include
include $(BUILD_SHARED_LIBRARY)
(and get rid of the ndktest lines at the start of the file, of course)
I'm trying to link a C static library to a C++ shared library, but it seems that the shared library completely ignores the LOCAL_STATIC_LIBRARIES line, and doesn't link the static lib.
TextureEngine is the static lib, and CustomTexture is the shared library. Here are the make files
Static library - TextureEngine
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TextureEngine
LOCAL_SRC_FILES := ../TextureEngine.c
# LOCAL_SHARED_LIBRARIES :=
#LOCAL_LDLIBS := -llog -landroid -lGLESv2
include $(BUILD_STATIC_LIBRARY)
Application.mk:
APP_ABI := all
APP_PLATFORM := android-23
APP_MODULES := TextureEngine
Shared library - CustomTexture
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TextureEngine
LOCAL_SRC_FILES := \
../TextureEngine/obj/local/$(TARGET_ARCH_ABI)/libTextureEngine.a
LOCAL_LDLIBS += -landroid -lGLESv2 -lm -lz -llog
include $(PREBUILT_STATIC_LIBARAY)
include $(CLEAR_VARS)
LOCAL_MODULE := CustomTexture
LOCAL_STATIC_LIBRARIES := TextureEngine
LOCAL_C_INCLUDES := ../TextureEngine
LOCAL_SRC_FILES := \
../CustomTexture.cpp \
../TextureProvider.cpp \
../Logfile.c \
../SineImage.cpp
LOCAL_LDLIBS += -landroid -lGLESv2 -lm -lz -llog
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_static
APP_CPPFLAGS += -std=c++11
APP_ABI := all
APP_PLATFORM := android-23
When I run ndk-build on TextureEngine, I get libTextureEngine.a files on all architecture folders. When I run ndk-build on CustomTexture however, I get undefined references.
Running ndk-build with V=1 on CustomTexture gives
[arm64-v8a] SharedLibrary : libCustomTexture.so
/opt/android-ndk-r12b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-g++ -Wl,-soname,libCustomTexture.so -shared --sysroot=/opt/android-ndk-r12b/platforms/android-23/arch-arm64 ./obj/local/arm64-v8a/objs/CustomTexture/__/CustomTexture.o ./obj/local/arm64-v8a/objs/CustomTexture/__/TextureProvider.o ./obj/local/arm64-v8a/objs/CustomTexture/__/Logfile.o ./obj/local/arm64-v8a/objs/CustomTexture/__/SineImage.o /opt/android-ndk-r12b/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/libgnustl_static.a -lgcc -no-canonical-prefixes -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -L/opt/android-ndk-r12b/platforms/android-23/arch-arm64/usr/lib -landroid -lGLESv2 -lm -lz -llog -lc -lm -o ./obj/local/arm64-v8a/libCustomTexture.so
As you can probably see - TextureEngine doesn't appear in the linker line. Sure enough, I can change the LOCAL_SRC_FILES on the prebuilt part of CustomTexture's Android.mk - And no new errors arise.
Why doesn't ndk-build try and link TextureEngine?
include $(PREBUILT_STATIC_LIBARAY)
Because of the typo here. LIBRARY, not LIBARAY :)
I actually discovered a bug last night where modules in LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES that don't exist don't actually cause errors, which explains why its easy to make this kind of mistake and not have any clear errors in your build.
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.
I've compiled a 3rd party library on Linux using a standalone toolchain, and I'm now trying to load that library in my app.
Problem is I'm getting java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_Znwj" referenced by "libmxnet_predict.so"
I've tried adding CFLAGS and LDFLAGS, both APP & LOCAL, but to no avail.
Before you ask, I'm developing with ADT because I have to.
This is my Application.mk:
APP_STL := gnustl_shared
APP_CFLAGS += -std=c++11
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-19
My (simplified) Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=SHARED
OPENCV_CAMERA_MODULES:=off
OPENCV_INSTALL_MODULES:=on
NDK_TOOLCHAIN_VERSION=4.9
include $(CLEAR_VARS)
include $(PREBUILT_SHARED_LIBRARIES)
include C:/OpenCV-2.4.8-android-sdk/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := FreshubML
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_SRC_FILES := Mldevlib.cpp \
Tablet.cpp \
Interface.cpp \
LOCAL_LDLIBS += -llog -ldl -landroid -lm -ljnigraphics -lstdc++
C:\KitchenVision\Workspaces\MLDevWorkspace\MLDev\assets\share
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libmxnet_predict
LOCAL_SRC_FILES := lib/armeabi-v7a/libmxnet_predict.so
include $(PREBUILT_SHARED_LIBRARY)
Searching the standalone toolchain I saw that the symbol was referenced in libgnust_shared.so which I added to my project via APP_STL and in libstdc++.so but still, same error.
How do I get this to work?
I'm trying to only use c++ to porting all my apps on Android devices from IOS and from ANDROID with JAVA EGL.
One thing I just met is "fatal error: android_native_app_glue.h: No such file or directory" so I'm going over my make file , 'Android.mk' below
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_DEFAULT_CPP_EXTENSION := cpp
LOCAL_MODULE := StarEngine
LOCAL_SRC_FILES := \
main.cpp \
StarEngine.cpp \
../../../StarEngine/StarShader.cpp \
../../../StarEngine/StarTexture.cpp \
../../../StarEngine/StarFBO.cpp\
../../../StarEngine/StarTimer.cpp\
../../../StarEngine/StarMath/Matrix.cpp\
../../../StarEngine/StarMath/Random.cpp\
../../../StarEngine/StarMath/Transform.cpp\
../../../StarEngine/StarMath/Vector.cpp\
../../../StarEngine/StarMath/neonmath/neon_matrix_impl.cpp\
../../../StarEngine/StarMath/vfpmath/matrix_impl.cpp\
../../../StarEngine/StarMath/vfpmath/utility_impl.cpp\
#../../../StarEngine/StarSound/StarSound.cpp
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_CFLAGS := -D_ARM_ARCH_7=1
LOCAL_CPPFLAGS := -D_ARM_ARCH_7=1
else
endif
LOCAL_CFLAGS := -DCONFIG_EMBEDDED -DUSE_IND_THREAD -marm -mfpu=neon -mfloat-abi=softfp
APP_STL := stlport_static
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -ldl -lGLESv2 -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue cpufeatures
include $(BUILD_SHARED_LIBRARY)
$(call import-module,cpufeatures,android/native_app_glue)
Answer :
When you use more than two static libraries you should put import-module more than twice like this
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
$(call import-module,cpufeatures)
According to the reference in NDK folder :
import-module
A function that allows you to find and include the Android.mk
of another module by name. A typical example is:
$(call import-module,<name>)
And this will look for the module tagged <name> in the list of
directories referenced by your NDK_MODULE_PATH environment
variable, and include its Android.mk automatically for you.