Missing LOCAL_MODULE before including BUILD_SHARED_LIBRARY - android

I am trying to set a NDK project in Eclipse. I have build the NDK as my sample programs are working properly. But, now when I am running my code I am facing this error
*** Android NDK: Missing LOCAL_MODULE before including BUILD_SHARED_LIBRARY in jni/Android.mk . Stop.
I have tried solving it through this question
Android NDK: Missing LOCAL_MODULE before including BUILD_SHARED_LIBRARY
But, Its not working. Please help me.
Following is my Android.mk file
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES:= off
OPENCV_MK_PATH:D:\FYP\darwinwallet-master\OpenCV-2.4.9-android-sdk\sdk\native\jni\OpenCV.mk
OPENCV_LIB_TYPE:=STATIC
OPENCV_INSTALL_MODULES:=on
include $(OPENCV_MK_PATH)
LOCAL_C_INCLUDES:=D:\FYP\darwinwallet-master\OpenCV-2.4.9-android-sdk\sdk\native\jni\include\
LOCAL_MODULE:=native_wallet
LOCAL_SRC_FILES:=jni_recognizer.cpp NativeVision/vision.cpp
LOCAL_CFLAGS=-ffast-math -O3 -funroll-loopsLOCAL_LDLIBS+=-llog -ldl
include $(BUILD_SHARED_LIBRARY)
And following is my build-shared-library.mk
LOCAL_BUILD_SCRIPT := BUILD_SHARED_LIBRARY
LOCAL_MAKEFILE := $(local-makefile)
$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
$(call check-LOCAL_MODULE_FILENAME)
my := TARGET_
$(call handle-module-filename,lib,$(TARGET_SONAME_EXTENSION))
$(call handle-module-built)
LOCAL_MODULE_CLASS := SHARED_LIBRARY
include $(BUILD_SYSTEM)/build-module.mk

Don't use backslash in your make files, it's too dangerous. Even on Windows, you can use forward slashes, i.e. change all \ to /. This will resolve your problem immediately.
Specifically, the line where you define LOCAL_C_INCLUDES ends with \ which means for make that it does not end. make dutifully joins the next line, so what it actually sees is something like
…
LOCAL_C_INCLUDES:=D:\…\include\LOCAL_MODULE:=native_wallet
LOCAL_SRC_FILES:=jni_recognizer.cpp NativeVision/vision.cpp
…
But actually, there is no need to re-define LOCAL_C_INCLUDES after you include OpenCV.mk. This script takes care of setting the include paths, flags, and library dependencies for you.

Related

$(LOCAL_PATH) not returning the path to current directory correctly

I am using Android NDK to compile a shared library. I am using the latest build of Android Studio (Android Studio 15- #AI-141.2422023 ). In my cpp code, I am using a thirdparty shared library. When writing the Android.mk file, I have first created a PREBUILT_SHARED_LIBRARY with the following code.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := essentia
LOCAL_SRC_FILES := $(LOCAL_PATH)/../../../essentia-shared/lib/libessentia.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../essentia-shared/include/essentia
include $(PREBUILT_SHARED_LIBRARY)
The problem I am facing is that $(LOCAL_PATH) is behaving a bit weirdly. The path it is returning is
jni/jni/../../../essentia-shared/lib/libessentia.so
I have the following questions:
I am not sure, why there are two jni's appended at the front of the path. Also when I tried to print the value of LOCAL_PATH by using $(warning $(LOCAL_PATH)), it prints jni.
Shouldn't $(LOCAL_PATH) return the absolute path? This is even more confusing because at times I got the absolute path using $(LOCAL_PATH).
PS: I am using the terminal internal to Android Studio to run ndk-build
Edit 1: I run the ndk-build from src/main
$(call my-dir) from src/main for src/main/jni/Android.mk results in "jni". On the other hand, LOCAL_SRC_FILES are always treated relative to the LOCAL_PATH, which is "jni". That's how jni/jni appears for your .so.
On the other hand, all …_INCLUDES are treated relative to working directory, which in your case is src/main from where you launched ndk-build. Due to the delicate nature of current directory, it is a good practice to use absolute paths for all include paths.
So, this is the suggested rewrite of this part of your Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := app-lib
LOCAL_SRC_FILES := a.cpp b.cpp
LOCAL_SHARED_LIBRARIES := essentia
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH += /../../../essentia-shared
include $(CLEAR_VARS)
LOCAL_MODULE := essentia
LOCAL_SRC_FILES := lib/libessentia.so
LOCAL_EXPORT_C_INCLUDES := $(abspath $(LOCAL_PATH)/include/essentia)
include $(PREBUILT_SHARED_LIBRARY)

Android - item in LOCAL_STATIC_LIBRARIES not being built

I'm having trouble getting the dependency module to build while building a static library in AOSP. Call this library A, it has a dependency on another static lib B.
A's Android.mk looks like this:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := A
LOCAL_SRC_FILES := <files...>
LOCAL_STATIC_LIBRARIES := B
include $(BUILD_STATIC_LIBRARY)
Individually B builds fine (mma).
Problem is when I build A, B is not being built. Instead I see this at output:
Export includes file: <...>/B/Android.mk -- out/<...>/STATIC_LIBRARIES/B_intermediates/export_includes
Can someone explain what does this line mean and, why is it not trying use B's Android.mk to properly build B?
I understand it's not ideal to package a static lib inside another, but here I'm more courious about why is it the build system not running through B's makefile, when it's clearly a dependency?
Thank you!
The build system ignores lots of irrelevant statements, LOCAL_STATIC_LIBRARIES being one of examples. They don't write every entry in LOCAL_STATIC_LIBRARIES as a dependency for libA.a. Instead, they interpret the Android.mk files to produce make rules for all targets, and if a dependency happens to show up, it will eventually get built, too.
Therefore, the easiest workaround for you would be to add a dummy shared library to your Android.mk, like
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := A
LOCAL_SRC_FILES := <files...>
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := dummyA
LOCAL_SRC_FILES := dummy.c
LOCAL_STATIC_LIBRARIES := B
include $(BUILD_SHARED_LIBRARY)
I am not sure if you can drop LOCAL_SRC_FILES completely. In terms of good old plain make files, the above is roughly equivalent to:
all: libA.a libdummyA.so
libdummyA.so: dummy.c libB.a
gcc -o $# dummy.c -lb
Alternatively, you can manually specify the dependency:
$(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libA_intermediates/libA.a: $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libB_intermediates/libB.a
Re: export_includes message, it is the result of processing LOCAL_EXPORT_C_INCLUDES statement for libB.

Android makefile can't find libs because of extra LOCAL_PATH in path

So I've been scratching my head for quite some time with this: basically, I have two Android makefile, one in my jni folder, and one in another folder that contains my native c++ code.
Thing is, for the following makefile,
LOCAL_PATH := $(call my-dir)
GENERATED_PATH := $(LOCAL_PATH)/../../generated/release/api/Android
############################ Includes ############################
#------------------------------------------------------------------ Assimp
LOCAL_MODULE := Assimp
LOCAL_EXPORT_C_INCLUDES := $(GENERATED_PATH)/assimp/include
LOCAL_SRC_FILES := $(GENERATED_PATH)/assimp/lib/libassimp.a
include $(PREBUILT_STATIC_LIBRARY)
# More Libraries included....
#....
I get the following error:
Android NDK: ERROR:jni/../../../appCommon/Android.mk:Assimp: LOCAL_SRC_FILES points to a missing file
Android NDK: Check that jni/../../../appCommon/jni/../../../appCommon/../../generated/release/api/Android/assimp/lib/libassimp.a exists or that its path is correct
What bugs me is that there's twice the LOCAL_PATH in the path where the ndk searches for the library. I've already read about a few cases like this one (like using the notdir macro) but couldn't find a satisfying solution.
How can I specify correctly (and not manually) the correct directory ?
So it turns out that the problem stems from the PREBUILT_STATIC_LIBRARY script, which looks for the lib in the following path: $(LOCAL_PATH)/$(LOCAL_SRC_FILES)
Thus, a simple workaround that worked is to have separate variables for the directories, like that:
GENERATED_PATH := ../../generated/release/api/Android
GENERATED_INCLUDE_PATH := $(LOCAL_PATH)/$(GENERATED_PATH)
and then use them like that:
LOCAL_MODULE := Assimp
LOCAL_EXPORT_C_INCLUDES := $(GENERATED_INCLUDE_PATH)/assimp/include
LOCAL_SRC_FILES := $(GENERATED_PATH)/assimp/lib/libassimp.a
include $(PREBUILT_STATIC_LIBRARY)

Static Linking OpenCV 2.4.3.2

I would like to statically link OpenCV(2.4.3.2) to my project. Right now my Android.mk looks like this
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include /Users/jamiematthews/Documents/Android-Projects/OpenCV-2.4.3-android-sdk/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := jni_part
LOCAL_SRC_FILES := jni_part.cpp
LOCAL_LDLIBS += -llog -ldl
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
Which throws the errors:
Android NDK: ERROR:/Users/jamiematthews/Documents/workspace/AuthentiGuard/jni/Android.mk:on: LOCAL_SRC_FILES points to a missing file
/Users/jamiematthews/Documents/android-ndk-r8d/build/core/prebuilt-library.mk:43: *** Android NDK: Aborting . Stop.
Android NDK: Check that /Users/jamiematthews/Documents/Android-Projects/OpenCV-2.4.3-android-sdk/sdk/native/jni/../libs/mips/libon.so exists or that its path is correct
Anyone know what "LOCAL_SRC_FILES points to a missing file" could mean?
PS if I remove the lines
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
it compiles fine, but then I cant statically link
Found the solution. Believe it or not it was an issue with Application.mk, not Android.mk. I had set
APP_ABI := all
Previously, and not even considered that it could effect the build process of this statically. I ended up changing it to
APP_ABI := armeabi-v7a
And now, everything works fine. Note that I ended up not needing OPENCV_CAMERA_MODULES:=on, I believe that is only if you are calling the camera from JNI, which I am not
LOCAL_SRC_FILES show the file where your native code resides. If you use native OpenCV code then you have to add the name of your cpp file here.
If you do not have a native part then you should add the OpenCV library to the libs folder of your project. (in case of static initialization). Please check this page for details.

Using Make's 'wildcard' function in Android.mk

I'm having a problem using Make's wildcard function in my Android.mk build file.
My other makefiles use a line like this one to specify "All .c files in this folder":
CFILES := $(wildcard *.c)
In my Android.mk file I tried this:
LOCAL_SRC_FILES := $(wildcard *.c)
However, this has the same affect as not including any files at all.
If I include the files manually the build works as I'd expect.
I'm wondering if maybe the current working directory isn't my project path at the time this statement is evaluated? If so, can I use a combination of $(call my-dir) and the wildcard function to get the list I want?
Here's what I've used in the past for doing this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylibrary
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.c)
include $(BUILD_STATIC_LIBRARY)
'my-dir' is a macro provided by the build system and returns the path of the directory containing the Android.mk file.
If your definition of "this directory" is "the directory containing this makefile", then
$(wildcard $(dir $(lastword $(MAKEFILE_LIST)))*.c)
ought to work.
(caveat: I don't know from Android)

Categories

Resources