Including Python libraries within Android.mk - android

Say I've got a file structure like so:
/top_lib
Android.mk
/sub_lib1
Android.mk
__init__.py
cheese_maker.py
/middle_lib/
Android.mk
/sub_lib2
Android.mk
__init__.py
bread_baker.py
/another_lib
Android.mk
/sub_lib3
Android.mk
__init__.py
leaf_raker.py
And have defined a make function within top_lib/Android.mk and another_lib/Android/mk and middle_lib/Android.mk
define add-file
include $$(PROJECT_DEFAULTS)
LOCAL_MODULE := $(1)
LOCAL_MODULE_TAGS := job_stuff
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(DESTINATION_DIR)/job_stuff/$(strip $(2))
LOCAL_SRC_FILES := $(1)
include $$(PROJECT_PREBUILT)
endef
define add-files-to-job
$(foreach f,$(2),$(eval $(call add-file,$f,$(1))))
endef
include $(call all-subdir-makefiles)
Within each sub_lib/Android.mk I have the following:
LOCAL_PATH := $(call my-dir)
FileList := $(notdir $(wildcard $(LOCAL_PATH)/*.py))
DirName := $(notdir $(LOCAL_PATH:%/=%))
$(call add-files-to-job, $(DirName), $(FileList))
Within another_lib, if I do mm, it all works nicely. Or even within middle_lib or top_lib. But if I'm at the top of the tree, and say run m job_stuff, eventually I hit an error:
build/core/base_rules.mk:147 ** path/to/middle_lib: MODULE.TARGET.ETC.__init__.py already defined by path/to/top_lib Stop.
I think I understand what's happening. It's staging the files in MODULE.TARGET.ETC, and having files with the same name throws the error. But what I have no idea about is how to fix it. I tried changing LOCAL_MODULE := $(1) to LOCAL_MODULE := $(2).$(1) and that made the folder name show up before each file name (ex: sub_lib1.cheese_maker.py), which is I suppose what I told it to do.
I know if I change the LOCAL_MODULE_CLASS := ETC to anything else, like LOCAL_MODULE_CLASS := ETCA in one of the Android.mk files, it'll work for that file. But I can't seem to find much documentation on LOCAL_MODULE_CLASS and how to utilize it, and since the build system is pretty complex, I'm not sure the repercussions of creating new classes all over the place.
I also tried changing the file adding from add-file to be more along the lines of
LOCAL_PATH := $(call my-dir)
FileList := $(notdir $(wildcard $(LOCAL_PATH)/*.py))
DirName := $(notdir $(LOCAL_PATH:%/=%))
include $$(PROJECT_DEFAULTS)
LOCAL_MODULE := $(DirName)
LOCAL_MODULE_TAGS := job_stuff
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(DESTINATION_DIR)/job_stuff/$(DirName)
LOCAL_SRC_FILES := $(FileList)
include $$(PROJECT_PREBUILT)
And that said it did stuff when I ran mm, but at top of tree m job_stuff did nothing (well, it built a lot of stuff but $(DESTINATION_DIR) was empty)
So I'm stuck. How do I get around having more than one init.py file within different libraries?

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.mk with multiple Modules, what does CLEAR_VARS do to each module?

I'm trying to understand the Android.mk better. I'm using a library to build a project right now and my Android.mk looks like this:
LOCAL_PATH := $(call my-dir)
SUPERPOWERED_PATH := ../../../../superpowered/Superpowered
include $(CLEAR_VARS)
LOCAL_MODULE := Superpowered
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_SRC_FILES := $(SUPERPOWERED_PATH)/libSuperpoweredARM.a
else
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
LOCAL_SRC_FILES := $(SUPERPOWERED_PATH)/libSuperpoweredARM64.a
else
LOCAL_SRC_FILES := $(SUPERPOWERED_PATH)/libSuperpoweredX86.a
endif
endif
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := SuperpoweredExample
LOCAL_SRC_FILES := \
SuperpoweredExample.cpp \
$(SUPERPOWERED_PATH)/SuperpoweredAndroidAudioIO.cpp
LOCAL_C_INCLUDES += $(SUPERPOWERED_PATH)
LOCAL_LDLIBS := -llog -landroid -lOpenSLES
LOCAL_STATIC_LIBRARIES := Superpowered
LOCAL_CFLAGS = -O3
include $(BUILD_SHARED_LIBRARY)
My question is about the include $(CLEAR_VARS) line between include $(PREBUILT_STATIC_LIBRARY) and LOCAL_MODULE := SuperpoweredExample
From reading http://android.mk My understanding of CLEAR_VARS is that is clears all of the LOCAL_ variables on the execution space for MAKE parsing. So how am I able to point at the Superpowered module later in the file. It seems to me like this should no longer be possible.
My thinking is that the MAKE parser does its parsing, and then maintains some "Module" space after each module is declared and parsed, which is separate from the actual parsing space. Thats a complete guess though, and I've had some difficulty finding a resource that covers whats happening in the background.
The current directory is not changed for the whole lifecycle of ndk-build, even when there are many modules, embedded Android.mk files, etc. That's why $(SUPERPOWERED_PATH) will stay relevant for all modules (it won't be so if it uses $(LOCAL_PATH) or other *make* variables).
The role of CLEAR_VARS is to reset all make variables that are listed in the variable modules-LOCALS. Here is an example how this behavior can be customized.
SUPERPOWERED_PATH set a current path of you jni folder path in that line and also in
particular format
C:/Users/Text/Desktop/TimeStreach/app/src/main/jni

Adding file in Development/apps folder, not showing in apps menu

I am trying to add my app in Android_source/Development/apps/ folder. I confirmed that my code is compiled, as if i add syntax error compiler stopped there.
But the thing is that my app is not getting shown in apps menu. should i add my app package somewhere else too.
Android.Mk file content(i copied these contents from Bluetooth App in packages/apps/Bluetooth)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
$(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := Bluetooth_LE
LOCAL_CERTIFICATE := platform
#LOCAL_JNI_SHARED_LIBRARIES := libbluetooth_jni
LOCAL_JAVA_LIBRARIES := javax.obex
LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard
LOCAL_REQUIRED_MODULES := libbluetooth_jni bluetooth.default
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
It seems that you've forgot to include your package into the build. Put the name of your module (Bluetooth_LE) into appropriate build file (for instance, into build/target/product/core.mk) into section PRODUCT_PACKAGES.

Linking dependent .so files with ndk-build for Android

I have created a .so file that exposes a native C call to Java via JNI. This works well and I can deploy the app onto my Android system if I just use system libraries in my C code. However, if I want to make calls to functions in other .so files, I cannot get my project to link correctly.
For example, say I have the "libotherso.so" file which contains APIs defined in C that I can call from the "MyJNILibrary.c" code I'm using to generate "libMyJNILibrary.so".
I tried to change my Android.mk file as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyJNILibrary
LOCAL_SRC_FILES := MyJNILibrary.c
LOCAL_LDLIBS += -lotherso
include $(BUILD_SHARED_LIBRARY)
But when I call ndk-build on this, I get errors finding -lotherso. Where do I put the "libotherso.so" file so that ndk-build can pick it up?
Thanks for any help you can provide.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := otherso
LOCAL_SRC_FILES := ../lib/libotherso.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := MyJNILibrary
LOCAL_SRC_FILES := MyJNILibrary.c
LOCAL_SHARED_LIBRARIES := otherso
include $(BUILD_SHARED_LIBRARY)
Note that LOCAL_SRC_FILES is relative to your LOCAL_PATH.
Don't forget to load your dependency before your own JNI library:
static {
System.loadLibrary("otherso");
System.loadLibrary("MyJNILibrary");
}

GNU make - finding sources from parent directories with wildcard

I'm re-asking this question, with a twist:
How do I specify the wildcard pattern when the files are in parent directory of LOCAL_PATH?
say, files would be ../../src/foo.cpp and ../../src/bar.cpp.
code LOCAL_SRC_FILES := $(wildcard ../../src/*.cpp) assigns an empty string.
I found the solution, but I'm not quite sure what was the problem.
Old script:
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := $(wildcard ../../src/*.cpp)
The new script that works:
LOCAL_PATH := $(call my-dir)/..
LOCAL_SRC_FILES := $(wildcard ../src/*.cpp)
I guess my-dir and wildcard do not refer to same working directory.
Android ndk toolchain expects to find the make file (android.mk) in /jni folder. $(call my-dir) seems to return /jni directory (because that's where the make file is). However $(wildcard ) seems to look from the current directory.
I'm not quite sure if I'm right here, but effectively it seems to be so.
EDIT: And here's the working script that I used before this attempt with wildcard
(just to explain you why I initially did what I did)
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := ../../src/foo.cpp \
../../src/bar.cpp

Categories

Resources