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)/%=%)
Related
Searching on several projects, I found this line on their android.mk $(call all-proto-files-under, $(src_proto)), and I tried to use this like that:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := my_test
src_proto := $(LOCAL_PATH)/proto
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPPFLAGS += -std=c++11
LOCAL_SRC_FILES := main.cc \
$(call all-proto-files-under, $(src_proto))
# print the source files
$(warning $(LOCAL_SRC_FILES))
# print only main.cc
$(warning $(LOCAL_SRC_FILES))
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \
$(LOCAL_PATH)/proto
# for logging
LOCAL_LDLIBS += -llog
# for native asset manager
LOCAL_LDLIBS += -landroid
include $(BUILD_SHARED_LIBRARY)
But it doesn't work, the warning prints nothing, and the second warning prints only main.cc, the line $(call all-proto-files-under, $(src_proto)) does nothing. I would like to know how can I use protobuf with android ndk.
I don't know how to solve it with the all-proto-files-under function specifically, but if you want to add all source files in a directory you can do that in the following way:
PROTOBUF_FILES := $(wildcard $(LOCAL_PATH)/proto/*.cc)
LOCAL_SRC_FILES += $(PROTOBUF_FILES:$(LOCAL_PATH)/%=%)
I suppose you could simplify that into a oneliner if you wanted to. It's also possible to add all source files in all subdirectories under a given directory if you need that:
PROTOBUF_FILES := $(wildcard $(LOCAL_PATH)/proto/**/*.cc)
When I built protobuf myself, I just took the corresponding Android.mk file from the AOSP git and removed all the stuff I didn't need.
I have an NDK-based project (written mostly on C++) and I want to split its sources into two parts: "lib" (to be shared with other projects) and "app" (files specific to current project).
Now my Android.mk looks as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyProj
MY_LIB_SOURCES := \
libfile1.cpp \
libfile2.cpp
MY_APP_SOURCES := \
appfile1.cpp \
appfile2.cpp
LOCAL_SRC_FILES += $(MY_LIB_SOURCES)
LOCAL_SRC_FILES += $(MY_APP_SOURCES)
LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
The only reason for splitting is that I want to add/remove lib source file once, because now I have to change Android.mk for all projects which need sources from MY_LIB_SOURCES.
Do I have to create a separate project that would produce a shared library? Or should it be a static library? Or maybe it's possible to just #include somehow file that enumerates MY_LIB_SOURCES into Android.mk of each app?
We usually create a separate folder for library sources, e.g.
project
jni
appfile1.cpp
appfile2.cpp
Android.mk (1)
my_lib
libfile1.cpp
libfile2.cpp
Android.mk (2)
This is the first (application) Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyProj
MY_APP_SOURCES := \
appfile1.cpp \
appfile2.cpp
LOCAL_SRC_FILES += $(MY_APP_SOURCES)
LOCAL_STATIC_LIBRARIES := android_native_app_glue
LOCAL_STATIC_LIBRARIES += MyLib
include $(BUILD_SHARED_LIBRARY)
include $(LOCAL_PATH)/../../my_lib/Android.mk
$(call import-module,android/native_app_glue)
This is the second (library) Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyLib
MY_LIB_SOURCES := \
libfile1.cpp \
libfile2.cpp
LOCAL_SRC_FILES += $(MY_LIB_SOURCES)
include $(BUILD_STATIC_LIBRARY)
Using the Andorid.mk name for MyLib is by convention; you could use some other file name, and change the include statement (line 17 of the first Android.mk file) accordingly.
You could also use the same $(call import-module) syntax, like
$(call import-module,my_lib)
But to do so, you must provide a NDK_MODULE_PATH environment variable that includes $(LOCAL_PATH)/../../.
Your library will be rebuilt anew for each app (project) that includes it - either with the first naïve include method, or with $(call import-module) method. You can provide a prebuilt static library, but this is a different story.
You must divide your android.mk in two sections:
LOCAL_PATH := $(call my-dir)
## The lib ##
include $(CLEAR_VARS)
LOCAL_MODULE := my_lib
SRC_LIB := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_SRC_FILES := $(SRC_LIB:$(LOCAL_PATH)/%=%)
include $(PREBUILT_SHARED_LIBRARY)
## The App ##
include $(CLEAR_VARS)
LOCAL_MODULE := my_app
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_SRC_FILES := \
appfile1.cpp \
appfile2.cpp
LOCAL_STATIC_LIBRARIES := android_native_app_glue
LOCAL_SHARED_LIBRARIES := my_lib
LOCAL_LDLIBS += -landroid
include $(BUILD_EXECUTABLE)
$(call import-module,android/native_app_glue)
If you want static library you have only to change include $(PREBUILT_SHARED_LIBRARY) to include $(PREBUILT_STATIC_LIBRARY) and LOCAL_SHARED_LIBRARIES := my_lib to LOCAL_STATIC_LIBRARIES += my_lib
so I'm relatively new to Android-NDK and trying to add an uncompiled c-library to android.
I've downloaded the library's source from here and followed these instructions to create a static library (.a-File) from the downloaded files using ndk-build.
So now I have a folder-structure that looks like this:
-srtp
--include (srtp.h, crypto.h)
--srtp (srtp.c...)
--obj
---local
----armeabi
-----libsrtp_static.a
In my Android-project I want to include srtp.h in a c-file inside my /jni/ folder. I've tried to just add the .a-file to the /jni folder but than it says "srtp.h no such file or direcotry". If I add the entire srtp-folder to the project and include the header with "srtp/include/srtp.h" it compiles but fails to link the source as I get the error "Undefined reference to srtp-function-call"
Here's my Android.mk (parts of it copied from Android.mk within the downloaded source):
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndk1 #name of my project
LOCAL_SRC_FILES := native.c #name of the c-source file
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH:= /home/dev/programing/srtp
common_SRC_FILES := \
srtp/srtp.c \
srtp/ekt.c \
crypto/cipher/cipher.c \
#...more files like that
common_CFLAGS := \
-DPOSIX -iquote$(LOCAL_PATH)/crypto/include \
-Werror \
-Wno-ignored-qualifiers \
-Wno-sign-compare \
-Wno-missing-field-initializers
common_C_INCLUDES = $(LOCAL_PATH)/include
# For the device
# =====================================================
# Device static library
include $(CLEAR_VARS)
ifneq ($(TARGET_ARCH),x86)
LOCAL_NDK_VERSION := 5
LOCAL_SDK_VERSION := 9
endif
LOCAL_SRC_FILES := libsrtp_static.a
LOCAL_CFLAGS += $(common_CFLAGS)
LOCAL_C_INCLUDES += /home/dev/programing/srtp/include
LOCAL_MODULE:= libsrtp_static
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)
Any help is greatly appreciated! Thank you very much.
You need to add the reference to libsrtp_static from your lib (ndk1) declaration :
LOCAL_STATIC_LIBRARIES := libsrtp_static
Also, you don't need to copy all the strp sources to your project, only add this to your static prebuilt library definition
LOCAL_EXPORT_C_INCLUDES += /home/dev/programing/srtp/include
This path will then be automatically added to the LOCAL_C_INCLUDES of your library that is using the library.
Are you building libsrtp or just using a prebuilt static library ? If you're using a prebuilt (lib*.a), replace BUILD_STATIC_LIBRARY with PREBUILT_STATIC_LIBRARY and set only the .a as SRC_FILE:
In summary, once libstrp_static.a is built, this should work:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndk1 #name of my project
LOCAL_SRC_FILES := native.c #name of the c-source file
LOCAL_STATIC_LIBRARIES := libsrtp_static
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := /home/dev/programing/srtp/libsrtp_static.a #check path to libsrtp_static.a
LOCAL_EXPORT_C_INCLUDES += /home/dev/programing/srtp/include
LOCAL_MODULE:= libsrtp_static
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)
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
i'm wrapping a native API to Android by NDK.
But when building it don't find the header files.
I have the following structure.
project/jni
Android.mk
LOCAL_PATH := $(call my-dir)
include $(call all-subdir-makefiles)
LOCAL_PATH :=/home/marcos/dev/workspace/rmsdk.native.wraper/jni
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndk1
LOCAL_SRC_FILES := native.c DelegateDRMProcessorClient.cpp
LOCAL_STATIC_LIBRARY := adept cryptopenssl dp expat fonts hobbes jpeg mschema png t3 xml zlib
include $(BUILD_SHARED_LIBRARY)
project/jni/prereqs/
Android.mk (Used to call all subdirs Android.mk files)
LOCAL_PATH := $(call my-dir)
include $(call all-subdir-makefiles)
include $(CLEAR_VARS)
project/jni/prereqs/%lib%/
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=dp
LOCAL_SRC_FILES :=libdp.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
And there's a include folder on each %lib% folder.
When using ndk-build I get a
"/home/marcos/dev/workspace/rmsdk.native.wraper/jni/DelegateDRMProcessorClient.h:18:20: error: dp_all.h: No such file or directory"
Anyone knows how to include these header to be available to the compiler?
I solve it, getting all the headers in a folder and including the following line in the Android.mk
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include-all
This works, but not looks like the best approach.
I'm a bit late to this party, but ran into the same issue and might have an answer for your comment:
"This works, but not looks like the best approach"
There;s a sample in the NDK called "module-exports"
It shows how to construct an Android.mk file which respects header files living in their proper directories and not all dumped into a single include directory.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_CFLAGS := -DFOO=2
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/foo
LOCAL_EXPORT_CFLAGS := -DFOO=1
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar/bar.c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/bar
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := zoo
LOCAL_SRC_FILES := zoo/zoo.c
LOCAL_SHARED_LIBRARIES := bar
include $(BUILD_SHARED_LIBRARY)
Years later...
To export the include directory instead of individual files, I use the following:
LOCAL_EXPORT_C_INCLUDE_DIRS := $(MY_DIRECTORY_PATH)
For example, for the above question the export for "foo" would look like:
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/foo
For new people's convenience, I just want to add that move all your header files in folder which is referred by LOCAL_C_INCLUDES := $(LOCAL_PATH) and then save android.mk and restart eclipse. After trying all the above solutions, that worked for me.