Android Copy directory tree recursively using make files - android

I need to copy a directory tree with XML files recursively to the out directory using Android.mk file
The directory structure is like this:
parent directory has three sub-directories each with an XML file. The parent directory also includes an Android.mk file.
The Android.mk file in parent has the following rules:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := file.xml
LOCAL_MODULE_TAGS := optional debug
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_SRC_FILES := file.xml
include $(BUILD_PREBUILT)
I need to define LOCAL_SRC_FILES and LOCAL_MODULE_PATH as the source and target directories.
Could someone please let me know how to do it?

Basically the issue here is the "LOCAL_MODULE" needs to be defined for each file in this case. And it needs to be unique. If we try to have the same name for all three subdirectories, make fails with an 'already defined' error.
As a workaround, I defined LOCAL_MODULE for each of the three files with unique filenames. I don't think there is any other option of resolving this.
As an aside, I ought to mention that it is possible to copy files by running cp command directly from make. Please see Copy multiple txt files in /system using Android.mk
However, please note that running shell commands directly from within Android.mk files is deprecated starting from Android N.

Related

Replacing some files before packaging system folder to system.img

As the title is self-explanatory, I'd want to replace some files in system/bin/ and system/lib/ right before when the system.img is being generated.
To be more exact, I've got some prebuilt .so files which shuold be copied over the existing ones. For example libart.so. Please note that replacing art/ (source code of art) with the modified art source code is not an option.
To do this, which mk file should I investigate and put my replacing code into?
You may follow the same structure as the one proposed in this other question, but use this macro:
PRODUCT_COPY_FILES += \
device/common/my_bin.bin:cache/my_bin.bin \
device/common/my_so.so:system/art/my_so.so
This works as follows:
The file is copied from left to(:) right.
When the image is generated, in this case cache or system, it would be generated with the files contained in those folders.
As we have copied our files to that destination, when system.img is generated, our file will be contained.
Also, the order in which this files are copied, matters. For instance if you are copying a file that already exists, hence, you want it replaced. (As your libart.so), you would need YOUR call to that copy to be done before the default one.
For this, I recommend doing:
source build/envsetup.sh
lunch <<device>>
mgrep libart.so -> This does a grep through mk files, so you can see where the default copy is done.
Insert $(info whatever) calls in desired mk files to trace where is a good spot to add your PRODUCT_COPY_FILES.
It's not easy to answer where to add it. I have never modified libart.so myself, but I have copied many files this way and it works like a charm.
I hope it works for your case as well.
A quick dirty way to this:
Copy desired files to out(..)/system/lib or wherever after system.img has been built
make snod
Other way is using Android.mk. Create a new dir in device tree eg libart-prebuilt. Put here your lib, then create an Android.mk file with content
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libart-prebuilt
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib
LOCAL_MODULE_STEM := libart
LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX)
LOCAL_SRC_FILES := libart.so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
include $(BUILD_PREBUILT)
Now just add libart-prebuilt to PRODUCT_PACKAGES in your device.mk
Also there's an option to add binary .so library as a product package, using PREBUILT_SHARED_LIBRARY option in .mk file: Include prebuilt shared library in Android AOSP or BUILD_PREBUILT https://stackoverflow.com/a/25682674/1028256

Generate stubs in Android Framework

According to this post : How are .java files in android_stubs_current_intermediates directory generated?
I tried to generate the stubs present in the test/generics/src folder and I just changed the two of the last lines :
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=$(call all-java-files-under,src)
LOCAL_MODULE:=test_stubs
LOCAL_DROIDDOC_OPTIONS:=\
-stubs $(OUT_DIR)/__test_stubs__
LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
include $(BUILD_DROIDDOC)
But when I do the mm in the current folder of the makefile nothing happends (and no generation of the __test_stubs__ folder) and I don't know why.
I manage to find the answer :
Go to the folder where the Android.mk is
do mm <local_module_name>-docs. In this context : mm test_stubs-docs
Hope it helps

Android.mk relative or absolute paths?

I'm trying to build a project using the android ndk (on Windows), and I'm having some issues specifically with the source files (LOCAL_SRC_FILES in the Android.mk)
I'm trying to use relative paths to a parent folder such as
LOCAL_SRC_FILES := ../../../src/main.cpp
And when running ndk_build.cmd, it outputs the following error:
Compile++ thumb : GTP <= main.cpp
The system cannot find the file specified.
make: *** [obj/local/armeabi/objs/GTP/__/__/__/src/.o] Error 1
So I tried using absolute paths:
LOCAL_SRC_FILES := D:/Path/To/src/main.cpp
Unfortunately this doesn't work because the : causes issues on windows
Is there any way I can specify source files in a relative directory (or absolute)? The reason I am asking is because I want to avoid making a symbolic link to the src folder if possible.
According to ndk documentation it is recommended to use relative paths and the following macro (Android.mk uses syntax of make files):
LOCAL_PATH := $(call my-dir)
An Android.mk file must begin with the definition of the LOCAL_PATH variable.
It is used to locate source files in the development tree. In this example,
the macro function 'my-dir', provided by the build system, is used to return
the path of the current directory (i.e. the directory containing the
Android.mk file itself).
So you can replace your LOCAL_SRC_FILES with something similar to:
LOCAL_SRC_FILES := $(LOCAL_PATH)/../../../src/main.cpp
The easiest way to work with source files spread across many directories, is to compile separate static libraries for each directory or group of directories. In NDK, these libraries are called "modules". For each module, you specify LOCAL_SRC_PATH in Android.mk. LOCAL_SRC_FILES are relative to this path. The caveat is that LOCAL_C_INCLUDES etc. are relative to project root directory (usually, the one above the jni directory).
You can have many Android.mk files in your project, but you can build many modules with single Android.mk.
Try this:
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := YOUR_SRC_IN_LIB_JNI

How can I specify a file to be copied in an Android.mk file

Is there a macro or command to copy files? I'd like a 3rd party library (libThirdParty.so) to be copied to the output directory (lib). This is the contents of my Android.mk file
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ndkFoo
LOCAL_SRC_FILES := ndkFoo.c
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
I have a build step I added for one of my .cpp files that's generated; you could do something similar.
Note that I was told that what I was doing was Not Supported by Google, so use at your own risk. I've been using something like the code below for more than a year, though. Here's a rough idea of what it would look like:
LOCAL_PATH:= $(call my-dir)
# this was important for some cases; can't remember if it's important here, but I don't want to steer you wrong if it isn't
REAL_LOCAL_PATH:=$(LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := ndkFoo
# again, I'm being paranoid here
REAL_LOCAL_MODULE := $(LOCAL_MODULE)
LOCAL_SRC_FILES := ndkFoo.c
$(REAL_LOCAL_PATH)/obj/local/armeabi/$(REAL_LOCAL_MODULE).so : $(REAL_LOCAL_PATH)/libs/armeabi/libThirdParty.so
$(REAL_LOCAL_PATH)/libs/armeabi/libThirdParty.so : $(PATH_TO_LIB_THIRD_PARTY)/libThirdParty.so
cp $(PATH_TO_LIB_THIRD_PARTY)/libThirdParty.so $(REAL_LOCAL_PATH)/libs/armeabi/libThirdParty.so
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
Note you'll need to define PATH_TO_LIB_THIRD_PARTY.
ALSO note that copy-and-paste may or may not work. Makefiles are notoriously picky about indents. I'd make sure that the "cp" line has a real tab indent, and that nothing else is indented. If "cp" doesn't work, then make may be delegating to CMD, and you can try "copy" instead.
Good luck.
I know this thread is old, but found it while searching for something myself.
From the PowerVR SDK, Android.mk file.
You can create folders and copy files.
PVRSDKDIR := $(LOCAL_PATH)
ASSETDIR := $(PVRSDKDIR)/TrainingCourse/IntroducingPOD/OGLES2/Build/Android/assets
$(ASSETDIR):
-mkdir $(ASSETDIR)
$(ASSETDIR)/tex_base.pvr: $(ASSETDIR) $(PVRSDKDIR)/TrainingCourse/IntroducingPOD/OGLES2/tex_base.pvr
cp "$(PVRSDKDIR)/TrainingCourse/IntroducingPOD/OGLES2/tex_base.pvr" "$(ASSETDIR)/"
Google has a feature that is exactly intended for your use case: PREBUILT_SHARED_LIBRARY
If you check the documentation in the docs directory included in the NDK, you will find ANDROID-MK.html which mentions this feature briefly, and PREBUILTS.html which completely documents the feature. You can specify the source and destination directories, and you can specify a new name for the file when it is copied.
There is also PREBUILD_STATIC_LIBRARY which does the same thing for a static library.
It might be possible to trick it into copying arbitrary files... the above features are implemented by files called, respectively, prebuilt-shared-library.mk and prebuilt-static-library.mk. Inside, they define an extension that must be on the file (respectively .so and .a). You could probably make another .mk file that defined some other extension to enable copying some other kind of file. But we have only needed to copy libraries and we haven't experimented with trying to trick the build system.
P.S. This blog posting is interesting. It refers to BUILD_PREBUILT, which doesn't exist in my copy of the NDK. I wonder if this blog posting refers to an earlier version of the NDK, which had BUILD_PREBUILT to copy any kind of file (with no check for a required extension).
http://karthiksden.blogspot.com/2011/03/copying-data-files-using-androidmk.html

Reading Android.mk files in sub-dirs recursively

I would just like to ask what should be written in the Android.mk file to also call the mk files in the sub-directories of the current directory.
Example:
/packages/Android.mk
/package/groupA/Android.mk
/packages/groupA/AppA/Android.mk
/packages/groupA/AppB/Android.mk
I know that by using include $(call all-subdir-makefiles), the Android.mk file in the immediate sub-directory will be read (example: /package/groupA/Android.mk). However, /packages/groupA/AppA/Android.mk and /packages/groupA/AppB/Android.mk will not be read.
I wonder if there is other macro that do the recursive reading of the Android.mk for all sub-directories.
Thanks,
artsylar
The most convenient solution is putting include $(call all-subdir-makefiles) command also inside /package/groupA/Android.mk file.
However, if you want only third-level mk files then you can use the following command:
include $(wildcard $(call my-dir)/*/*/Android.mk)
And here is a fully recursive solution, but it relies on find command from the shell:
include $(filter-out $(call my-dir)/Android.mk,$(shell find $(call my-dir)/ -type f -name Android.mk))

Categories

Resources