Look for Android.mk in $(APP_PROJECT_PATH)/jni by default.

This gets rid of the 'sources' directory and allows all sources
of a given Android application to be in the same directory tree
without using a symlink trick.

Note that apps/<name>/Application.mk is still required though.
A later release of the NDK will get rid of it too, but the change
is too drastic for the upcoming release.

The change moves various source files from sources into their
app/<name>/project/jni directory as well.

The whole documentation is updated to reflect the change.
This commit is contained in:
David 'Digit' Turner
2009-07-29 19:04:44 +02:00
parent 197a8fea8e
commit eee1675aa4
42 changed files with 163 additions and 91 deletions

View File

@@ -5,6 +5,8 @@ Welcome, this NDK is designed to allow Android application developers
to include native code in their Android application packages, compiled
as JNI shared libraries.
See docs/CHANGES.TXT for a list of changes since the previous release.
A high-level overview of the NDK's features and limitations can be found
in docs/OVERVIEW.TXT. Please read this document as it contains crucial
information for correct usage.

View File

@@ -3,3 +3,4 @@ APP_MODULES := \
test-LOCAL_CPPFLAGS
APP_PROJECT_PATH := /tmp/ndk-unit-tests
APP_BUILD_SCRIPT := $(call my-dir)/Android.mk

View File

@@ -76,6 +76,30 @@ ifdef _bad_platform
$(call __ndk_error,Aborting...)
endif
# If APP_BUILD_SCRIPT is defined, check that the file exists.
# If undefined, look in $(APP_PROJECT_PATH)/jni/Android.mk
#
APP_BUILD_SCRIPT := $(strip $(APP_BUILD_SCRIPT))
ifdef APP_BUILD_SCRIPT
_build_script := $(strip $(wildcard $(APP_BUILD_SCRIPT)))
ifndef _build_script
$(call __ndk_info,Your APP_BUILD_SCRIPT points to an unknown file: $(APP_BUILD_SCRIPT))
$(call __ndk_error,Aborting...)
endif
APP_BUILD_SCRIPT := $(_build_script)
$(call ndk_log, Using build script $(APP_BUILD_SCRIPT))
else
_build_script := $(strip $(wildcard $(APP_PROJECT_PATH)/jni/Android.mk))
ifndef _build_script
$(call __ndk_info,There is no Android.mk under $(APP_PROJECT_PATH)/jni)
$(call __ndk_info,If this is intentional, please define APP_BUILD_SCRIPT to point)
$(call __ndk_info,to a valid NDK build script.)
$(call __ndk_error,Aborting...)
endif
APP_BUILD_SCRIPT := $(_build_script)
$(call ndk_log, Defaulted to APP_BUILD_SCRIPT=$(APP_BUILD_SCRIPT))
endif
$(if $(call get,$(_map),defined),\
$(call __ndk_info,Weird, the application $(_name) is already defined by $(call get,$(_map),defined))\
$(call __ndk_error,Aborting)\

View File

@@ -262,7 +262,7 @@ NDK_APP_VARS_REQUIRED := APP_MODULES APP_PROJECT_PATH
# the list of variables that *may* be defined in Application.mk files
NDK_APP_VARS_OPTIONAL := APP_OPTIM APP_CPPFLAGS APP_CFLAGS APP_CXXFLAGS \
APP_PLATFORM
APP_PLATFORM APP_BUILD_SCRIPT
# the list of all variables that may appear in an Application.mk file
NDK_APP_VARS := $(NDK_APP_VARS_REQUIRED) $(NDK_APP_VARS_OPTIONAL)

View File

@@ -108,7 +108,7 @@ $(foreach tc,$(NDK_ALL_TOOLCHAINS),\
NDK_PLATFORMS_ROOT := $(BUILD_SYSTEM)/../platforms
NDK_ALL_PLATFORMS := $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)))
$(info NDK_ALL_PLATFORMS=$(NDK_ALL_PLATFORMS))
$(call ndk_log,Found supported platforms: $(NDK_ALL_PLATFORMS))
$(foreach _platform,$(NDK_ALL_PLATFORMS),\
$(eval include $(BUILD_SYSTEM)/add-platform.mk)\

View File

@@ -45,5 +45,5 @@ NDK_APP_DEST := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ABI_SUBDIR)
# free the dictionary of LOCAL_MODULE definitions
$(call modules-clear)
# now parse all Android.mk build files
include sources/*/Android.mk
# now parse the Android.mk for the application
include $(NDK_APP_BUILD_SCRIPT)

View File

@@ -51,25 +51,33 @@ source code easier for application developers.
Simple example:
---------------
Before describing the syntax in details, let's consider a simple
"hello world" example, i.e. the following files:
Before describing the syntax in details, let's consider the simple
"hello JNI" example, i.e. the files under:
sources/helloworld/helloworld.c
sources/helloworld/Android.mk
apps/hello-jni/project
Where 'helloworld.c' is the source of a simple JNI shared library
that implements a native method that returns the "hello world"
string.
Here, we can see:
The corresponding Android.mk file will look like this:
- The 'src' directory containing the Java sources for the
sample Android project.
- The 'jni' directory containing the native source for
the sample, i.e. 'jni/hello-jni.c'
This source file implements a simple shared library that
implements a native method that returns a string to the
VM application.
- The 'jni/Android.mk' file that describes the shared library
to the NDK build system. Its content is:
---------- cut here ------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := helloworld
LOCAL_SRC_FILES := helloworld.c
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
---------- cut here ------------------
@@ -93,7 +101,7 @@ with the exception of LOCAL_PATH. This is needed because all build
control files are parsed in a single GNU Make execution context where
all variables are global.
LOCAL_MODULE := helloworld
LOCAL_MODULE := hello-jni
The LOCAL_MODULE variable must be defined to identify each module you
describe in your Android.mk. The name must be *unique* and not contain
@@ -107,10 +115,10 @@ add another 'lib' prefix and will generate libfoo.so as well.
This is to support Android.mk files that originate from the
Android platform sources, would you need to use these.
LOCAL_SRC_FILES := helloworld.c
LOCAL_SRC_FILES := hello-jni.c
The LOCAL_SRC_FILES variables must contain a list of C and/or C++ source
files that will be built and assemble into a module. Note that you should
files that will be built and assembled into a module. Note that you should
not list header and included files here, because the build system will
compute dependencies automatically for you; just list the source files
that will be passed directly to a compiler, and you should be good.
@@ -128,7 +136,7 @@ information you defined in LOCAL_XXX variables since the latest
'include $(CLEAR_VARS)' and determine what to build, and how to do it
exactly. There is also BUILD_STATIC_LIBRARY to generate a static library.
There are more complex examples under sources/samples, with commented
There are more complex examples under apps/, with commented
Android.mk files that you can look at.
Reference:
@@ -332,7 +340,7 @@ LOCAL_C_INCLUDES
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
These are placed before any corresponding inclusion flag in
LOCAL_CFLAGS / LOCAL_CXXFLAGS / LOCAL_CPPFLAGS
LOCAL_CFLAGS / LOCAL_CPPFLAGS
LOCAL_CFLAGS

View File

@@ -104,10 +104,19 @@ APP_CPPFLAGS
You can now use APP_CFLAGS for flags that shall apply to C and
C++ souces.
APP_BUILD_SCRIPT
By default, the NDK build system will look for a file named Android.mk
under $(APP_PROJECT_PATH)/jni, i.e. for the file:
$(APP_PROJECT_PATH)/jni/Android.mk
If you want to override this behaviour, you can define APP_BUILD_SCRIPT
to point to an alternate build script. A non-absolute path will always
be interpreated as relative to the NDK's top-level directory.
A trivial Application.mk file would be:
-------------- cut here -------------------------
APP_MODULES := <list of modules>
APP_PROJECT_PATH := <path to project>
-------------- cut here -------------------------

View File

@@ -3,13 +3,16 @@ Android NDK ChangeLog:
-------------------------------------------------------------------------------
current version
IMPORTANT BUG FIXES:
- Fix build/host-setup.sh to:
* execute as a Bourne shell script
* remove unused host gcc dependency
* improve Windows host auto-detection
* add GNU Make version check
* add Nawk/Gawk check
* ensure that the script is run from $NDKROOT as build/host-setup.sh
* add --help, --verbose and --no-make-check options
* add --help, --verbose, --no-awk-check and --no-make-check options
- Properly add sysroot library search path at build time. This makes a line
in Android.mk like:
@@ -20,6 +23,46 @@ current version
could not find the corresponding libz.so library. Also clear LOCAL_LDLIBS
in $(CLEAR_VARS) script.
IMPORTANT CHANGES
- The 'sources' directory is gone. The NDK build system now looks for
$(APP_PROJECT_PATH)/jni/Android.mk by default. You can override this with
the new APP_BUILD_SCRIPT variable in Application.mk
For example, the 'hello-jni' sample uses the following files:
apps/hello-jni/project/jni/Android.mk
apps/hello-jni/project/jni/hello-jni.c
The 'apps/<name>' directory is still needed in this release though.
- Change LOCAL_CFLAGS / LOCAL_CPPFLAGS to work as in the full Android build
system. This means that:
- LOCAL_CFLAGS is now used for *both* C and C++ sources (was only for C)
- LOCAL_CPPFLAGS is now used for C++ sources only (was for both C and C++)
- LOCAL_CXXFLAGS is used like LOCAL_CPPFLAGS but is considered obsolete.
(will disappear in next release)
Also fixed APP_CPPFLAGS / APP_CFLAGS / APP_CXXFLAGS correspondingly.
- Rename build/platforms/android-1.5 to build/platforms/android-3 to match
the Android API level instead of the marketing speak.
Also add a new build/platforms/android-4, and make the build system select
which platform to use based on the content of the project file named
$(APP_PROJECT_PATH)/default.properties.
- Add OpenGL ES 1.x headers and libraries to the android-4 stable APIs.
(NOTE: they are *not* available for android-3)
Also provide a small port of the "San Angeles Observation" demo to show
how to make a simple Android application that uses them.
OTHER FIXES & CHANGES
- Generate thumb binaries by default.
- Add support for LOCAL_ARM_MODE in Android.mk.
@@ -33,23 +76,5 @@ current version
- Fix compilation of assembler files (e.g. foo.S)
- Fix LOCAL_CFLAGS / LOCAL_CPPFLAGS to work as in the full Android build
system. This means that:
- LOCAL_CFLAGS is used for both C and C++ sources
- LOCAL_CPPFLAGS is used for C++ sources only
- LOCAL_CXXFLAGS is used like LOCAL_CPPFLAGS but is considered obsolete.
Also fixed APP_CPPFLAGS / APP_CFLAGS / APP_CXXFLAGS.
- Add build/platforms/android-4, and make the build system select which
platform to use based on the content of the project file named
$(APP_PROJECT_PATH)/default.properties.
- Add OpenGL ES 1.x headers and libraries to the android-1.4 stable APIs.
Also provide a small port of the "San Angeles Observation" demo to show
how to make a simple Android application that uses them.
-------------------------------------------------------------------------------
android-ndk-1.5_r1 released.

View File

@@ -23,28 +23,35 @@ Use GNU Make's "-B" option, as in:
make APP=<yourapp> -B
How to store your native sources in under your project's path:
--------------------------------------------------------------
How to store your native sources in a location other than $PROJECT/jni:
-----------------------------------------------------------------------
It is often more convenient to store your native sources at a
different location than $NDK_ROOT/sources. For example, you would
typically place them under the same directory than your other project
files, to keep everything under source control, etc...
First, you can simply tell your $PROJECT/jni/Android.mk to include
another Android.mk that are located in different places.
The NDK build system needs to access the sources from $NDK_ROOT/sources
and your Application.mk from $NDK_ROOT/apps/<name>. This is essentially
to keep its implementation sane and simple, and to ensure that certain
features, like automatic dependency management, work reliably.
Alternatively, you can define APP_BUILD_SCRIPT in your Application.mk
to point to an alternative Android.mk file, getting rid of the
$PROJECT/jni directory hierarchy entirely if you need to.
You can however use simple symlinks to redirect paths to your project's
storage location. For example:
$NDK_ROOT/sources/<foo> ----> $PROJECT_PATH/jni/<foo>
$NDK_ROOT/apps/<foo> ----> $PROJECT_PATH/jni/<foo>
How to store your Application.mk in a location other than $NDK/app/<name>:
--------------------------------------------------------------------------
Where $PROJECT_PATH/jni/<foo> contains both an Android.mk and an
Application.mk. Note that things like $(call my-dir) will always evaluate
to the NDK paths (i.e. $NDK_ROOT/sources/<foo>) at build time.
At the moment, the application descriptor files must be accessible from
$NDK/app/<name>. You can however create a symlink to a different directory.
For example, imagine that you wrote:
$PROJECT/jni/Application.mk
You can create a symlink like with a command like:
ln -s $PROJECT/jni $NDK/apps/<name>
This will make $NDK/apps/<name>/Application.mk point directly to
$PROJECT/jni/Application.mk
Note that generated files will still go under $NDK/out/apps/<name> though.
Windows users: The NDK is only supported on Cygwin, which implements
symbolic links through the "ln -s" command, as in:
@@ -94,5 +101,3 @@ Which uses a path relative to $(LOCAL_PATH), in the case where you would
need to move 'foo' and 'bar' to a deeper level in the 'sources' hierarchy.

View File

@@ -26,7 +26,7 @@ IMPORTANT:
This is due to subtle toolchain and ABI related changed that make
it incompatible with 1.0 and 1.1 system images.
The NDK also requires GNU Make 3.81 or later being available on your development
The NDK requires GNU Make 3.81 or later being available on your development
system. Earlier versions of GNU Make might work but have not been tested.
You can check this by running 'make -v' from the command-line. The output
@@ -40,6 +40,10 @@ On certain systems, GNU Make might be available through a different command like
'gmake' or 'gnumake'. For these systems, replace 'make' by the appropriate command
when invoking the NDK build system as described in the documentation.
The NDK also requires a Nawk or GNU Awk executable being available on your
development system. Note that the original 'awk' program doesn't implement
the 'match' and 'substr' functions used by the NDK build system.
On Windows, you will need to install a recent release of Cygwin to use the NDK.
See http://www.cygwin.com for instructions.
@@ -53,5 +57,3 @@ command from the root folder:
build/host-setup.sh
This will test your setup and make sure the NDK can work properly.

View File

@@ -46,32 +46,34 @@ implemented in native code through the JNI. In a nutshell, this means that:
The Android NDK is a complement to the Android SDK that helps you to:
- generate JNI-compatible shared libraries that can run on the Android
- Generate JNI-compatible shared libraries that can run on the Android
1.5 platform (and later) running on ARM CPUs.
- copy the generated shared libraries to a proper location of your
- Copy the generated shared libraries to a proper location of your
application project path, so they will be automatically added to your
final (and signed) .apks
- in later revisions of the NDK, we intend to provide tools that help
- In later revisions of the NDK, we intend to provide tools that help
debug your native code through a remote gdb connection and as much
source/symbol information as possible.
Moreover, the Android NDK provides:
- a set of cross-toolchains (compilers, linkers, etc..) that can
- A set of cross-toolchains (compilers, linkers, etc..) that can
generate native ARM binaries on Linux, OS X and Windows (with Cygwin)
- a set of system headers corresponding to the list of stable native APIs
- A set of system headers corresponding to the list of stable native APIs
supported by the Android platform. This corresponds to definitions that
are guaranteed to be supported in all later releases of the platform.
They are documented in the file docs/STABLE-APIS.TXT
IMPORTANT:
Keep in mind that most of the native system libraries in Android system
images are not frozen and might changed drastically, or even deleted,
in later updates and releases of the platform.
- a build system that allow developers to only write very short build files
- A build system that allow developers to only write very short build files
to describe which sources need to be compiled, and how. The build system
deals with all the hairy toolchain/platform/CPU/ABI specifics. Moreover,
later updates of the NDK can add support for more toolchains, platforms,
@@ -96,11 +98,11 @@ A good understanding of JNI is highly recommended, since many operations
in this environment require specific actions from the developers, that are
not necessarily common in typical native code. These include:
- not being able to directly access the content of VM objects through
- Not being able to directly access the content of VM objects through
direct native pointers. E.g. you cannot safely get a pointer to a
String object's 16-bit char array to iterate over it in a loop.
- requiring explicit reference management when the native code wants to
- Requiring explicit reference management when the native code wants to
keep handles to VM objects between JNI calls.
@@ -127,9 +129,9 @@ Android NDK:
1/ Run build/host-setup.sh to configure the NDK
2/ Place your sources under sources/<mysrc>/...
2/ Place your native sources under $PROJECT/jni/...
3/ Write sources/<mysrc>/Android.mk to describe your sources
3/ Write $PROJECT/jni/Android.mk to describe your sources
to the NDK build system
4/ Write apps/<myapp>/Application.mk to describe your application
@@ -167,35 +169,32 @@ error message telling you what to do.
III.2/ Placing C and C++ sources:
- - - - - - - - - - - - - - - - -
The NDK build system expects your sources to be visible under the top-level
'sources' directory. You should first create a directory like:
You should place your native sources under the following directory:
$NDK/sources/<mysrc>/
$PROJECT/jni/
You are pretty free to organize the content of 'sources' as you want,
Where $PROJECT corresponds to the path of your Android application
project.
You are pretty free to organize the content of 'jni' as you want,
the directory names and structure here will not influence the final
generated application packages, so you don't have to use pseudo-unique
names like com.<mycompany>.<myproject> as is the case for application
package names.
For the record, the NDK comes with a 'sources/samples' directory which
itself contains several subdirectories for various sample modules.
Note that C and C++ sources are supported. The default C++ file extensions
supported by the NDK is '.cpp', but other extensions can be handled as well
(see docs/ANDROID-MK.TXT for details).
It is possible to store your sources in a different location, as long as
you create $NDK/sources/<mysrc> as a symbolic link. For proper operation, the
NDK build system must be able to 'see' your source files and build scripts
from $NDK/sources.
It is possible to store your sources in a different location by adjusting
your Android.mk file (see below).
III.3/ Writing an Android.mk build script:
- - - - - - - - - - - - - - - - - - - - - -
An Android.mk file is a small build script that you write to describe your
sources to the NDK build system. Their syntax is described in details in
sources to the NDK build system. Its syntax is described in details in
the file docs/ANDROID-MK.TXT.
In a nutshell, the NDK groups your sources into "modules", where each module
@@ -207,13 +206,11 @@ can be one of the following:
You can define several modules in a single Android.mk, or you can write
several Android.mk files, each one defining a single module.
All Android.mk files are parsed by the build system before any build occurs.
Note also that a single Android.mk might be parsed several times by the build
Note that a single Android.mk might be parsed several times by the build
system so don't assume that certain variables are not defined in them.
By default, the NDK will look for the following build script:
By default, the NDK will look for all files that match the following:
$NDK/sources/*/Android.mk
$PROJECT/jni/Android.mk
If you want to define Android.mk files in sub-directories, you should
include them explicitely in your top-level Android.mk. There is even

View File

@@ -60,7 +60,7 @@ The standard mandates that this value is stored in network order (and thus
should be converted to host order through ntohs()). However, the 1.5
implementation is buggy and returns the number.
This bug will be fixed in future releases of the platform, and applications
This bug is fixed in later releases of the platform, and applications
should not depend on the wrong behaviour in the future. Avoid using this
function if possible; if this is not possible, try to use a small wrapper
like the following one:

View File

@@ -1 +0,0 @@
include $(call all-subdir-makefiles)