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
Related
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)
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)
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?
I need to build some cross platform cpp files in my android mk file. These sources are not in sub directories of the jni directory.
Currently i have something like below, is there some way to avoid the long relative paths to describe where the source files are located? What is best practice here?
Thanks
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := host
LOCAL_SRC_FILES := ../../../../../Dev/common/host.c
include $(BUILD_STATIC_LIBRARY)
You can define your own variables in mk file:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
SRC_ROOT := ../../../../../Dev
LOCAL_MODULE := host
LOCAL_SRC_FILES := $(SRC_ROOT)/common/host.c
include $(BUILD_STATIC_LIBRARY)
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)