Headers with Android NDK - android

I'm trying to compilate my own library with the Android NDK But I've got some problems.
Here is my Android.mk file:
# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := MyLib
LOCAL_SRC_FILES := ../../../src/mylib/utils/Timer.cpp
LOCAL_C_INCLUDES := ../../../src/mylib/
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_LDLIBS := -llog
LOCAL_CPPFLAGS := -std=c++0x
include $(BUILD_SHARED_LIBRARY)
When I build my project with "ndk-build" I've got the following error :
Clean: mylib [armeabi]
Clean: stlport_shared [armeabi]
Clean: stlport_static [armeabi]
Compile++ thumb : mylib <= Timer.cpp
jni/../../../src/mylib/utils/Timer.cpp:1:34: fatal error: mylib/utils/Timer.hpp: No such file or directory
compilation terminated.
For information, I'm including the .hpp like that :
#include <mylib/utils/Timer.hpp>
I don't know why headers aren't found, my library working in Xcode and eclipse.
Thanks for your time!
Edit: Here is my project's architecture to understand my problem: http://i.imgur.com/aiah6zH.jpg
I'm trying to indicate where is located my ".hpp" files in the Android.mk file.

Your LOCAL_C_INCLUDES should include the ../../../src/ or ../../../inc directory in order for you to use #include <mylib/utils/Timer.hpp> i.e:
LOCAL_C_INCLUDES := ../../../src/
Why don't you put your C and C++ headers and source files inside the jni/ directory of the Android project, near the Android.mk file?
See: What is the difference between #include <filename> and #include "filename"?
Also this is incorrect, because the second LOCAL_LDLIBS overrides the previous LOCAL_LDLIBS directive in the current module :
LOCAL_LDLIBS = -lz -lm
LOCAL_LDLIBS := -llog
If you want to append to a make directive use:
LOCAL_LDLIBS := -lz -lm
LOCAL_LDLIBS += -llog
or LOCAL_LDLIBS := -lz -lm -llog
EDIT:
Using the following Android.mk it seems to work if you run ndk-build from the Android/jni directory.
LOCAL_PATH := $(call my-dir)
# first lib, which will be built statically
#
include $(CLEAR_VARS)
LOCAL_MODULE := MyLib
LOCAL_C_INCLUDES := ../../../inc/
LOCAL_SRC_FILES := ../../../src/mylib/utils/Timer.cpp
include $(BUILD_STATIC_LIBRARY)
# second lib, which will depend on and include the first one
#
include $(CLEAR_VARS)
LOCAL_MODULE := MyNativeFinalSharedLib
LOCAL_LDLIBS := -lz -lm -llog
LOCAL_CPPFLAGS := -std=c++0x
LOCAL_STATIC_LIBRARIES := MyLib
include $(BUILD_SHARED_LIBRARY)
Also you forgot to put LOCAL_PATH := (call my-dir) on the first line and some other missing make directives.
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).
(from android-ndk-r8d/docs/ANDROID-MK.html)

It's highly recommended to have your Android.mk file define $(LOCAL_PATH). In your case, the best choice would probably be
LOCAL_PATH := $(call my-dir)/../../../../src
Now you can simply write
LOCAL_SRC_FILES := mylib/utils/Timer.cpp
But for the includes, the path should be defined as relative from current, i.e. MyProject/build/Android directory. In your case, it seems, the correct path would be
LOCAL_C_INCLUDES := ../../../inc
This when you specify mylib in the #include statement:
#include <mylib/utils/Timer.hpp>

Related

all-proto-files-under doesn't work on android.mk

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.

Android NDK: Directive not visible to includes of static library

I simply want use a static library for an NDK project. The library works with build systems like automake, but in Android.mk I have a problem with the source files. For some reason, directives don't work over different header files and I get the following error:
error: 'myname' does not name a type
It seems that the directive defined in file1.hpp is not visible in file2.hpp which includes file1.hpp (as I said, this problem does not occur with other build systems like automake.
What am I doing wrong here?
Android.mk:
include $(CLEAR_VARS)
LOCAL_MODULE := libstat
LOCAL_LDLIBS := -lm
LOCAL_SRC_FILES := /home/dir/libstat.a
LOCAL_EXPORT_C_INCLUDES := /home/dir/src
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_CFLAGS := -lm -ldl /home/dir/src
LOCAL_LDFLAGS := -L/home/dir/
LOCAL_C_INCLUDES += /home/dir/src
LOCAL_SRC_FILES := hello-jni.cpp
LOCAL_LDLIBS := -ggdb
LOCAL_STATIC_LIBRARIES := libstat
include $(BUILD_SHARED_LIBRARY)
src includes all header and source files. Any hint would be appreciated.

android ndk undefined reference to a method

Hi Sorry for the long post I am trying to compile some static classes namely jsmn.c,json.c and buf.c which are part of the jsmn json library I downloaded from https://github.com/alisdair/jsmn-example/downloads.
I am compiling two STATIC_LIBRARIES lib1 and json_librrary.lib1 has native code which is dependent on json_library.Then I am making two libraries into a shared library containing
gnustl_static AND lib1
My folder structure is as follows
jni/lib1/ANdroid.mk
include $(CLEAR_VARS)
LOCAL_MODULE := json_library
LOCAL_SRC_FILES := /3rdParty/jsmn/json_library.a
LOCAL_SRC_FILES := /3rdParty/jsmn/jsmn.c /3rdParty/jsmn/buf.c /3rdParty/jsmn/log.c /3rdParty/jsmn/json.c
LOCAL_C_INCLUDES := /3rdParty/jsmn/jsmn.h /3rdParty/jsmn/buf.h /3rdParty/jsmn/log.h /3rdParty/jsmn/json.h
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Module Name
LOCAL_MODULE := lib1
LOCAL_STATIC_LIBRARIES := json_library
........
.......
......
include $(BUILD_STATIC_LIBRARY)
jni/Android.mk
# Here we give our module name
LOCAL_MODULE := lib2
# list the static modules included here!!!
LOCAL_STATIC_LIBRARIES := gnustl_static lib1
....
include $(BUILD_SHARED_LIBRARY)
jni/Application.mk
APP_MODULES := lib2
# Optimization for release
APP_OPTM := release
#Targets
APP_ABI := armeabi-v7a armeabi
So inside the lib1 I have class which calls a method from the json library named json_tokenise
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <jsmn/jsmn.h>
#include <jsmn/json.h>
#include <jsmn/buf.h>
jsmntok_t *tokens=json_tokenise((char *)data);
typedef enum {
START,
WRAPPER,
MESSAGE,
ROUTE,
OBJECT,
ARRAY,
SKIP,
STOP
}parse_state;
I am getting the following error
undefined reference to `json_tokenise(char*)'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi-v7a/lib2.so] Error 1
**** Build Finished ****
When I have a look inside [obj/local/armeabi-v7a/ I can see
libjson_library.a liblib1.a libgnustl_static.a are getting generated for the armabi-v7 and it fails to generate lib2 because of the error.
Please help or guide me where I am going wrong I have spent two days on this and I am new to NDK.
You should fix your jni/lib1/Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := json_library
LOCAL_SRC_FILES := 3rdParty/jsmn/jsmn.c 3rdParty/jsmn/buf.c 3rdParty/jsmn/log.c 3rdParty/jsmn/json.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/3rdParty/jsmn
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
If you still have problems after this, please run ndk-build with parameter V=1 on command line and post the full output of this build and full content of all your Android.mk files.
I faced similar problem. The json_library.a should be included in prebuild static library module. And that should be compiled for the desired platform.
include $(CLEAR_VARS)
LOCAL_MODULE := json_core
LOCAL_SRC_FILES := /3rdParty/jsmn/json_library.a
include $(PREBUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := json_library
LOCAL_SRC_FILES := /3rdParty/jsmn/jsmn.c /3rdParty/jsmn/buf.c /3rdParty/jsmn/log.c /3rdParty/jsmn/json.c
There is no need to include each file separately.
LOCAL_C_INCLUDES := /3rdParty/jsmn/
Finally, it is needed to specify that json_library module is dependent on json_core (prebuilt library) .
LOCAL_STATIC_LIBRARIES := json_core
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
In this way the linker knows where to find all the definitions of methods for each module.

How to include a prebuilt static library in Android NDK's Android.mk file correctly?

I'm stuck getting my libraries included inside the Android NDK build.
The libraries are correctly compiled and work fine when creating a dummy cpp file and building everything with a direct g++ command in the shell.
The current Android.mk file doesn't work and throws an error that the corresponding header files (that are part of the .a files) can't be found.
How do I include prebuilt static libraries correctly?
My Android.mk file looks like this:
LOCAL_PATH := $(call my-dir)
# V8 Base
include $(CLEAR_VARS)
LOCAL_MODULE := v8_base
LOCAL_MODULE_FILENAME := v8_base_static
LOCAL_SRC_FILES := ../lib/libv8_base.a
include $(PREBUILT_STATIC_LIBRARY)
# V8 Nosnapshot
include $(CLEAR_VARS)
LOCAL_MODULE := v8_nosnapshot
LOCAL_MODULE_FILENAME := v8_nosnapshot_static
LOCAL_SRC_FILES := ../lib/libv8_nosnapshot.a
include $(PREBUILT_STATIC_LIBRARY)
# V8GL Runtime
include $(CLEAR_VARS)
LOCAL_MODULE := v8gl-runtime
LOCAL_SRC_FILES := main.c ../src/v8gl/v8gl.cpp
LOCAL_CPPFLAGS := -D__ANDROID__
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue v8_base v8_nosnapshot
# LOCAL_EXPORT_CPPFLAGS := -D__ANDROID__
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
The compiler output is the following, which makes sense, but only shows me that there is no single .a file included and I don't know why:
Compile++ thumb : v8gl-runtime <= v8gl.cpp
(... g++ call)
In file included from jni/../src/v8gl/v8gl.cpp:6:
jni/../src/v8gl/v8gl.h:5:16: error: v8.h: No such file or directory
SOLUTION with absolute path
Thanks to the hint of #alex-cohn I found out that the includes were falsely pointed out.
So I decided to use an environment variable that is set before calling ndk-build that contains the absolute path. That fixes the problem with the includes.
So the last Module, where the actual inclusion is done, is now looking like:
ADK_PATH=/var/whatever/to/your/project/root_not_jni
include $(CLEAR_VARS)
LOCAL_MODULE := v8gl-runtime
LOCAL_SRC_FILES := main.c ../src/v8gl/v8gl.cpp
LOCAL_C_INCLUDES:= $(ADK_PATH)/external/v8/include
LOCAL_CPPFLAGS := -D__ANDROID__
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue v8_base v8_nosnapshot
Now it also shows that the libraries are included, because they are compiled afterwards - for whatever reason.
SOLUTION with relative path
All include paths are relative to the project root folder and not the jni folder. That means it will land as a compiler -I flag as something like this:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../file_in_project.root
# resulting g++ flag:
-Ijni/../file_in_project.root
So there's a difference between the relative include paths and the LOCAL_SRC_FILES, which are relative to the jni folder!
You probably have file v8.h in directory ../include or somewhere else...
You should add line
LOCAL_C_INCLUDES = $(LOCAL_PATH)/../include
Note that unlike LOCAL_SRC_FILES where you don't need $(LOCAL_PATH), here you must put the full paths of all directories where the necessary .h files are.

Build shared library linking to other not standard shared libarary

I have some two shared libraries and header for them.
I want to build third shared library using functions from previous two libs.
Have problem with makefile i think. When i try to build receive this:
Android NDK: /cygdrive/d/.../jni/Android.mk: Cannot find module with tag 'shared1' in import path
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined ?
Android NDK: The following directories were searched:
Android NDK:
/cygdrive/d/.../jni/Android.mk:36: *** Android NDK: Aborting. . Stop.
structure of my project:
jni/
- myfile.c
- Android.mk
jni/dec/
- lot of header files
jni/enc/
- lot of header files
libs/armeabi/
- shared1.so
- shared2.so
also Android.mk sourse:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/dec \
$(LOCAL_PATH)/enc
LOCAL_SHARED_LIBRARIES := shared1 shared2
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := myfile.c
LOCAL_LDLIBS += -lOpenSLES
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS += -landroid
include $(BUILD_SHARED_LIBRARY)
$(call import-module, shared1)
$(call import-module, shared2)
Take a look to this question: Android JNI APK Packing
You need to give another name for libs/armeabi/ folder to avoid conflicts with NDK build and add the following code before the include $(CLEAR_VARS) statement:
include $(CLEAR_VARS)
LOCAL_MODULE:=shared1
LOCAL_SRC_FILES:=3rdparty_libs/shared1.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:=shared2
LOCAL_SRC_FILES:=3rdparty_libs/shared2.so
include $(PREBUILT_SHARED_LIBRARY)
As I understand it, the correct method is to use ndk-build and not invoking the compiler directly.
In Android.mk you need to specify a module for each static library you want to compile, and then specify that your shared library should use it.
Example of a modified Android.mk file of the hello-jni sample project:
LOCAL_PATH := $(call my-dir)
# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := <list_of_src_files>
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
# First lib, which will be built statically.
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_STATIC_LIBRARIES := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
If you want control over which modules to compile when you run ndk-build you can create create a Application.mk file (in the same directory as Android.mk) and list all the modules as in the following example:
APP_MODULES := <module_name_1> <module_name_2> ... <module_name_n>
I think it Helps you

Categories

Resources