Skip to main content
The ndk-build system uses GNU Make to build native code. It relies on two key configuration files: Android.mk (module definitions) and Application.mk (application-wide settings).

Android.mk variables

The Android.mk file defines build modules and their properties. Each module describes a single library or executable.

Module definition

LOCAL_PATH
path
required
Must be the first line of every Android.mk file. Defines the location of source files in the development tree.
LOCAL_PATH := $(call my-dir)
LOCAL_MODULE
string
required
The name of the module you want to build. Must be unique across all module names and not contain spaces.
LOCAL_MODULE := native-lib
LOCAL_MODULE_FILENAME
string
Optional override for the generated file name. By default, the module name determines the output file name.
LOCAL_MODULE_FILENAME := libnative

Source files

LOCAL_SRC_FILES
list
required
List of C/C++ source files to compile. Paths are relative to LOCAL_PATH.
LOCAL_SRC_FILES := native-lib.c \
                   utils.cpp \
                   helpers.cpp
LOCAL_CPP_EXTENSION
string
File extensions for C++ source files. Default is .cpp. Use this if your files use different extensions.
LOCAL_CPP_EXTENSION := .cxx .cc

Compilation flags

LOCAL_CFLAGS
string
Compiler flags for C and C++ files. Use for optimization, warnings, and feature flags.
LOCAL_CFLAGS := -Wall -Wextra -O2 -DNDEBUG
LOCAL_CPPFLAGS
string
Compiler flags for C++ files only.
LOCAL_CPPFLAGS := -std=c++17 -fno-rtti -fno-exceptions
LOCAL_CONLYFLAGS
string
Compiler flags for C files only.
LOCAL_CONLYFLAGS := -std=c11
LOCAL_ASMFLAGS
string
Assembler flags for assembly files.
LOCAL_ASMFLAGS := -march=armv7-a

Include paths and libraries

LOCAL_C_INCLUDES
list
Additional include directories. Paths can be absolute or relative to NDK root.
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \
                    $(NDK_ROOT)/sources/android/cpufeatures
LOCAL_EXPORT_C_INCLUDES
list
Include paths to export to modules that depend on this one.
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_STATIC_LIBRARIES
list
List of static libraries to link against. Reference other ndk-build modules by name.
LOCAL_STATIC_LIBRARIES := cpufeatures android_support
LOCAL_SHARED_LIBRARIES
list
List of shared libraries to link against.
LOCAL_SHARED_LIBRARIES := log android
LOCAL_WHOLE_STATIC_LIBRARIES
list
Static libraries to link with --whole-archive flag. All object files from the library are included.
LOCAL_WHOLE_STATIC_LIBRARIES := mystaticlib

Linking flags

LOCAL_LDFLAGS
string
Linker flags to use when building shared libraries or executables.
LOCAL_LDFLAGS := -Wl,--no-undefined -Wl,--version-script=exports.txt
LOCAL_LDLIBS
string
System libraries to link against. Use the -l prefix.
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2
LOCAL_ALLOW_UNDEFINED_SYMBOLS
boolean
Allow undefined symbols in shared libraries. Default is false.
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

Preprocessor definitions

LOCAL_CFLAGS
string
Use -D flags to define preprocessor macros.
LOCAL_CFLAGS += -DENABLE_LOGGING -DVERSION=\"1.0.0\"
LOCAL_EXPORT_CFLAGS
string
Compiler flags to export to dependent modules.
LOCAL_EXPORT_CFLAGS := -DUSE_FEATURE_X

Module types

Each module must include one of these module type definitions:
Module TypeDescriptionUsage
BUILD_SHARED_LIBRARYBuilds a shared library (.so)include $(BUILD_SHARED_LIBRARY)
BUILD_STATIC_LIBRARYBuilds a static library (.a)include $(BUILD_STATIC_LIBRARY)
BUILD_EXECUTABLEBuilds a native executableinclude $(BUILD_EXECUTABLE)
PREBUILT_SHARED_LIBRARYUses a prebuilt shared libraryinclude $(PREBUILT_SHARED_LIBRARY)
PREBUILT_STATIC_LIBRARYUses a prebuilt static libraryinclude $(PREBUILT_STATIC_LIBRARY)

Complete Android.mk example

LOCAL_PATH := $(call my-dir)

# Clear variables
include $(CLEAR_VARS)

# Module configuration
LOCAL_MODULE := native-audio
LOCAL_SRC_FILES := native-audio.cpp \
                   audio-engine.cpp \
                   audio-player.cpp

# Compilation flags
LOCAL_CPPFLAGS := -std=c++17 -Wall -Wextra
LOCAL_CFLAGS := -O2 -DNDEBUG

# Include paths
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include

# Libraries
LOCAL_LDLIBS := -llog -lOpenSLES -landroid
LOCAL_STATIC_LIBRARIES := cpufeatures

# Build shared library
include $(BUILD_SHARED_LIBRARY)

# Import prebuilt modules
$(call import-module,android/cpufeatures)

Application.mk variables

The Application.mk file describes application-wide settings. It’s optional and located in jni/Application.mk.

Platform and ABI configuration

APP_ABI
string
Target ABIs to build for. Can specify multiple ABIs or use all for all supported ABIs.
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
# Or build for all ABIs
APP_ABI := all
Common ABI values: armeabi-v7a, arm64-v8a, x86, x86_64. The armeabi and mips ABIs are deprecated.
APP_PLATFORM
string
Android API level to target. Higher API levels provide more functionality but reduce compatibility.
APP_PLATFORM := android-21

Build configuration

APP_OPTIM
string
Optimization level: release or debug. Default is release unless APP_DEBUG is true.
APP_OPTIM := release
APP_DEBUG
boolean
Build debuggable binaries with symbols. Set to true or false.
APP_DEBUG := false
APP_CFLAGS
string
C/C++ compiler flags for all modules.
APP_CFLAGS := -Wall -Werror
APP_CPPFLAGS
string
C++ compiler flags for all modules.
APP_CPPFLAGS := -std=c++17 -frtti -fexceptions
APP_LDFLAGS
string
Linker flags for all modules.
APP_LDFLAGS := -Wl,--build-id

STL configuration

APP_STL
string
C++ Standard Library to use. Options include c++_shared, c++_static, none, or system.
APP_STL := c++_shared
STL OptionDescription
c++_sharedLLVM libc++ as shared library (recommended)
c++_staticLLVM libc++ as static library
noneNo C++ standard library
systemSystem C++ runtime (minimal, deprecated)
Use c++_shared for most applications. If you use c++_static, ensure all shared libraries use the same STL to avoid ODR violations.

Module configuration

APP_MODULES
list
Explicit list of modules to build. If not specified, all modules are built.
APP_MODULES := native-lib audio-engine
APP_PROJECT_PATH
path
Absolute path to the project root. Default is the parent of the Application.mk directory.
APP_PROJECT_PATH := $(call my-dir)/..
APP_BUILD_SCRIPT
path
Path to the build script. Default is $(APP_PROJECT_PATH)/jni/Android.mk.
APP_BUILD_SCRIPT := $(call my-dir)/custom.mk

Advanced settings

APP_SHORT_COMMANDS
boolean
Use shorter command lines for build commands. Useful on Windows. Default is false.
APP_SHORT_COMMANDS := true
APP_THIN_ARCHIVE
boolean
Use thin archives for static libraries. Reduces build size. Default is false.
APP_THIN_ARCHIVE := true
APP_WRAP_SH
string
Script to wrap build commands. Useful for build analysis tools.
APP_WRAP_SH := wrapper-script.sh

Complete Application.mk example

# Target multiple ABIs
APP_ABI := armeabi-v7a arm64-v8a x86_64

# Target Android 5.0 and higher
APP_PLATFORM := android-21

# Use shared C++ library
APP_STL := c++_shared

# Release build with optimizations
APP_OPTIM := release

# C++ standard and compiler flags
APP_CPPFLAGS := -std=c++17 -frtti -fexceptions
APP_CFLAGS := -Wall -Werror

# Only build specific modules
APP_MODULES := native-lib audio-engine

Build system functions

The ndk-build system provides several helper functions:
FunctionDescription
$(call my-dir)Returns the directory of the current makefile
$(call import-module,<name>)Imports a module by name from NDK_MODULE_PATH
$(call import-add-path,<path>)Adds a path to the module search path

Common build patterns

Building multiple modules

LOCAL_PATH := $(call my-dir)

# First module: shared library
include $(CLEAR_VARS)
LOCAL_MODULE := engine
LOCAL_SRC_FILES := engine.cpp
include $(BUILD_SHARED_LIBRARY)

# Second module: static library
include $(CLEAR_VARS)
LOCAL_MODULE := utils
LOCAL_SRC_FILES := utils.cpp
include $(BUILD_STATIC_LIBRARY)

# Third module: depends on both
include $(CLEAR_VARS)
LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_SHARED_LIBRARIES := engine
LOCAL_STATIC_LIBRARIES := utils
include $(BUILD_SHARED_LIBRARY)

Using prebuilt libraries

LOCAL_PATH := $(call my-dir)

# Define prebuilt library
include $(CLEAR_VARS)
LOCAL_MODULE := third-party
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libthirdparty.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

# Use prebuilt library
include $(CLEAR_VARS)
LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_SHARED_LIBRARIES := third-party
include $(BUILD_SHARED_LIBRARY)

Conditional compilation

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := native-lib.cpp

# Add debug flags for debug builds
ifeq ($(APP_OPTIM),debug)
    LOCAL_CFLAGS += -DDEBUG_MODE -g
else
    LOCAL_CFLAGS += -DNDEBUG -O3
endif

# Architecture-specific sources
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
    LOCAL_SRC_FILES += neon_impl.cpp
    LOCAL_CFLAGS += -mfpu=neon
endif

include $(BUILD_SHARED_LIBRARY)
For new projects, consider using CMake instead of ndk-build. CMake offers better IDE integration and is the recommended build system for Android native development.

Build docs developers (and LLMs) love