I know that to build so file, I should put the source file in /jni/ folder.
But how can I build separate so in different folders.
For example, the structure of my project:
/jni/Android.mk
/jni/submodule1/Android.mk
/jni/submodule1/sub1.c
/jni/submodule2/Android.mk
/jni/submodule2/sub2.c
I have tried to write this in Android.mk in the top level:
$(LOCAL_PATH) :=$(call all-makefiles-under)
then wrote make info in Android.mk in submodule
the error is:
ndk-build
make: *** No rule to make target `/home/../workspace/jni/sub.c', needed b
y `/home/../workspace/obj/local/armeabi/objs/submodule/sub.o'. Stop.
Can someone give me a solution? Thank you!
Update 1:
The code of Android.mk in submoudle:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := sub.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_MODULE := sub
LOCAL_LDLIBS := -ldl -llog
LOCAL_STATIC_LIBRARIES := libc
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := debug
include $(BUILD_EXECUTABLE)
SOLVED:
I should use ndk-build in the root directory, but not in jni directory. Thanks all of you!
You should try include $(call all-subdir-makefiles) rather then $(LOCAL_PATH) :=$(call all-makefiles-under) in main Android.mk and make folder under jni folder with there separate c files and Android.mk files
Have you tried something like:
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := /submodule1/sub1.c
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)
I'm using Eclipse for Windows, Android SDK and Android NDK (I'm sure that all paths are set correclty).
I'm looking for compiling a .c library locatad in jni folder, but some error occur. This library depends on external .so libraries, these are my Makefile, Android.mk and library:
jni folder.
Android.mk :
LOCAL_PATH := $(call my-dir)
#---------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := pdbeatdetection
LOCAL_C_INCLUDES := $(LOCAL_PATH)\C:\PROGRAMMING\pd-0.45-4\src
LOCAL_CFLAGS := -DPD
LOCAL_SRC_FILES := pdbeatdetection.c
LOCAL_LDLIBS := -L$(LOCAL_PATH)\C:\PROGRAMMING\PdCore\libs\armeabi\ -lpdnative
include $(BUILD_SHARED_LIBRARY)
Makefile :
all:
C:\PROGRAMMING\android-ndk-r10d\ndk-build.cmd
mkdir ../tmp
cp ..\libs\armeabi\libpdBeatDetection.so ..\tmp\pdbeatdetection.pd_linux
cd ..\tmp && zip externals.zip *.pd_linux && mv externals.zip ..\res\raw
rm -rf ..\tmp
I followed some tutorials, but I'm not still able to solve this issue.
Could you please give me suggestions to compile the library, avoiding the following error?
ERROR:
Description Resource Path Location Type
make.exe: *** [obj/local/armeabi/libpdbeatdetection.so] Error 1 Discoteque C/C++ Problem
Thank you!
If your code depends on an external .so file, you should declare it properly using the PREBUILT_SHARED_LIBRARY macro, like so:
LOCAL_PATH := $(call my-dir)
#dependency
include $(CLEAR_VARS)
LOCAL_MODULE := pdnative
LOCAL_SRC_FILES := C:/PROGRAMMING/PdCore/libs/$(TARGET_ARCH_ABI)/libpdnative.so
LOCAL_EXPORT_C_INCLUDES := C:/PROGRAMMING/pd-0.45-4/src
include $(PREBUILT_SHARED_LIBRARY)
#your module
include $(CLEAR_VARS)
LOCAL_MODULE := pdbeatdetection
LOCAL_SRC_FILES := pdbeatdetection.c
LOCAL_CFLAGS := -DPD
include $(BUILD_SHARED_LIBRARY)
If that's not enough to solve your issue, give us the error reported by calling ndk-build.cmd directly.
I am unable to locate a working example of the Android NDK's module importation feature. The following Android.mk files seem correct, and the inner module builds and executes without error. However, building the outer module fails with the following error messages:
Android NDK: jni/inner/Android.mk:inner: LOCAL_MODULE_FILENAME should not include file extensions
Android NDK: jni/inner/Android.mk:inner: LOCAL_MODULE_FILENAME must not contain a file extension
/home/caleb/dev/android-ndk-r8e/build/core/build-shared-library.mk:30: * Android NDK: Aborting . Stop.
The inner, contained Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := inner
LOCAL_MODULE_FILENAME := libinner
LOCAL_SRC_FILES := inner-module.c
include $(BUILD_SHARED_LIBRARY)
The outer, containing Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := outer
$(call import-module,inner)
LOCAL_SHARED_LIBRARIES += inner
include $(BUILD_SHARED_LIBRARY)
Try placing the call to import-module at the end of your outer file. It is not a must to place it before referencing 'inner', and the NDK documentation actually advice you to place it at the end.
There's a few problems with what you are doing so here is how things should look.
The inner, contained Android.mk file:
# save away the previous local path
INNER_SAVED_LOCAL_PATH := $(LOCAL_PATH)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := inner
LOCAL_MODULE_FILENAME := libinner
LOCAL_SRC_FILES := inner-module.c
include $(BUILD_SHARED_LIBRARY)
# at this point LOCAL_MODULE_FILENAME will have been auto
# set to libinner.so or similar by the call to BUILD_SHARED_LIBRARY
# restore previous local path
LOCAL_PATH := $(INNER_SAVED_LOCAL_PATH)
The outer, containing Android.mk file:
LOCAL_PATH := $(call my-dir)
$(call import-module,inner)
# at this point
# a) we've still got the correct LOCAL_PATH as we didn't trash it in
# the included Android.mk file
# b) LOCAL_MODULE_FILENAME is still set to libinner.so which if not
# unset will cause BUILD_SHARED_LIBRARY to complain
include $(CLEAR_VARS)
# we've now got a clean slate
LOCAL_MODULE := outer
# the build system has 'remembered' the inner module
LOCAL_SHARED_LIBRARIES += inner
include $(BUILD_SHARED_LIBRARY)
I'm not sure if this is the way to do it but it works for me :)
I'm trying to build an Android project using the ndk, but I have run into some troubles.
Here's the Android.mk file that works:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := main.cpp, Screen.cpp, ScreenManager.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
Is there a way that allows me to specify all the *.cpp files in the directory, without listing them manually under LOCAL_SRC_FILES?
So far I tried using LOCAL_SRC_FILES = $(wildcard *.cpp), but it did now work, it seems that no files get selected.
You could try something like this...
FILE_LIST := $(wildcard $(LOCAL_PATH)/[DIRECTORY]/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
... Change [DIRECTORY] to the actual directory of the files. If they are in the same directory as your .mk file then remove that part. Create the FILE_LIST variable to find all of the .cpp files under the [DIRECTORY] directory. Then use it in the file listing. The LOCAL_SRC_FILES line will then remove the LOCAL_PATH from the listing.
I've been using this script for my Android.mk saved me so much time!
#traverse all the directory and subdirectory
define walk
$(wildcard $(1)) $(foreach e, $(wildcard $(1)/*), $(call walk, $(e)))
endef
#find all the file recursively under jni/
ALLFILES = $(call walk, $(LOCAL_PATH))
FILE_LIST := $(filter %.cpp, $(ALLFILES))
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
Here is the gist
How about like this:
LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/*.cpp))
If you'd be afraid that expansion of * contains $(LOCAL_PATH)/, it might be OK:
LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/./,,$(wildcard $(LOCAL_PATH)/./*.cpp))
Using this:
LOCAL_SRC_FILES += $($(wildcard $(LOCAL_PATH)/*.cpp):$(LOCAL_PATH)/%=%)
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)