NDK series [13] Makefile Android.mk Application.mk Comments


When we use third-party libraries, many of which are provided makefile, we need to understand them and their appropriate modifications, although another google now recommended cmake, but if you meet Android.mk still need to be able to read.

1. What is the Makefile

Whether it is c, c ++ source files should first be compiled into intermediate code file in Windows is .obj files, .o files under UNIX is that Object File, this action is called 编译(compile), and then perform a large number of synthetic Object File static or dynamic library files, this action is called 链接(link).

A source file project does not count, according to its type, function modules were placed in several directories, makefile defines a set of rules to specify which files need to be compiled, which files need compiled, how links and other operations.

makefile is "automatic compilation", tells how to make command to compile and link that configuration scripts make tools.

By default, gun make command in order to find the file in the current directory

"GNUmakefile”、“makefile”、“Makefile”
Best not to use "GNUmakefile", this document is make recognizes the GNU (Windows Nmake not identify)

Of course, you can also use another file name to write Makefile, such as: "Make.Linux", "Make.android". So when you need to usemake -f XX 或者 make --file XX。

2. Makefile rules

Basic Usage

Command in the Makefile, you must start with [Tab] key.

在Makefile中的命令,必须要以[Tab]键开始。

target : prerequisites ...(预备知识,先决条件)
	command(指令)
-----------------------------------------------------------------------------------------
      target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签。
      prerequisites 要生成那个target所需要的文件或是其他target。
      command也就是make需要执行的命令。(任意的Shell命令)

The following example

# g++ -o  指定生成可执行文件的名称
# 下面的方法就是将main.o和test.o编译成test可执行程序test
test:main.o test1.o
	g++ -o test main.o test1.o

Of course, you can also directly compile cpp

# \ 是换行连接符 便于Makefile的易读,不用都挤在一行
test2:
	g++ -o test2 main.cpp \
test1.cpp

clean

clean:
	rm test main.o test.o

Print data

print:
	echo "hello world"

variable

If more complex cases, such as document number, target goal more, if we modify, such as adding a .cpp file,

It may be necessary in many places to write about, but also prone to error. For ease of maintenance, you can use variables in the makefile.

#声明变量
objects=main.o T1.o
#mac上自动编译 main.o
test:${objects}
	g++ -o test ${objects}

clean:
	rm test ${objects}
	
#======================================
# *.c 表示所有后缀为c的文件。
# 让通配符在变量中(当前目录下所有 .c 文件)
objects = $(wildcard *.c)
test : ${objects}
        gcc -o test ${objects}
clean :
        rm test ${obects}

include

include make.clean

#或者

mk=make.clean
include ${mk}

File Search

In some large projects, a large number of source files stored in different directories, the best way to tell is to make a path, let go to make automatic.
Makefile file the special variable VPATHis to complete this function

#默认先查找当前目录再查找当前目录下的a、b、c目录
VPATH = a:b:c
OBJ=a.o b.o c.o main.o

test : $(OBJ)
        gcc -o  test  $(OBJ)
clean :
        rm test $(OBJ)

Predefined variables

Command variable meaning
WITH Library packaged program, the default is "ar"
AS Assembly language compiler, the default is "as"
CC C language compiler, the default command is "cc"
CXX C ++ language compiler, the default command is "g ++"
RM Delete the file name of the program, the default value rm -f
ARFLAGS Library file maintenance options for the program, with no default
ASFLAGS Options assembly program, with no default
CFLAGS C compiler options, with no default
CPPFLAGS C pre-compiler option, no default
CXXFLAGS C ++ compiler options, with no default

Automatic variables

$@ target的名字

main.o:main.c
	gcc -c main.c -o main.o
#使用 $@ 代替 main.o
main.o:main.c
	gcc -c main.c -o $@

$< target依赖的第一个依赖文件名

main.o:main.c a.h b.h
	gcc -c main.c -o main.o
#使用 $< 代替 main.c
main.o:main.c a.h b.h
	gcc -c $< -o main.o
variable Explanation
$* target file name does not include an extension of
$+ All dependent files, separated by spaces, and to have appeared for the order, dependent files may contain duplicate
$? All timestamps later than the target file dependency files, and separated by spaces
$^ All non-repetition of the dependent files, separated by spaces

Conditional statements


ifeq ($(CC),gcc)
        $(CC) -o foo $(objects) $(libs_for_gcc)
else
        $(CC) -o foo $(objects) $(normal_libs)
endif

Output

AAA=123456
#输出变量AAA
$(warning $(AAA))
$(info $(AAA))

3. Android.mk

GNU makefile tiny fragments.

Source files grouped into modules . Module is a static library, shared library or stand-alone executable file. May each Android.mkdefine one or more modules files may also be used with a plurality of modules in a source file.

#源文件在的位置。宏函数 my-dir 返回当前目录
LOCAL_PATH := $(call my-dir)
#可为您清除变量
#不会清理 LOCAL_PATH 变量
include $(CLEAR_VARS)
#存储您要构建的模块的名称 每个模块名称必须唯一,且不含任何空格
#如果模块名称的开头已是 lib,则构建系统不会附加额外的前缀 lib;而是按原样采用模块名称,并添加 .so 扩展名。
LOCAL_MODULE := hello-jni
#包含要构建到模块中的 C 和/或 C++ 源文件列表 以空格分开
LOCAL_SRC_FILES := hello-jni.c
#构建动态库
include $(BUILD_SHARED_LIBRARY)

Variables and macros

Define your own arbitrary variables. Please note that the definition of variables, NDK build system will reserve the following variable names:

  • With LOCAL_names that begin, for example LOCAL_MODULE.
  • To PRIVATE_, NDK_or APPnames that begin with. The system uses these variables to build internally.
  • Lowercase names, for example my-dir. Construction of the system is the use of these variables internally.

If you needed in order to facilitate Android.mkthe definition of their variable documents, additional recommendations before the name MY_.

Common built-in variables

variable name meaning Examples
BUILD_STATIC_LIBRARY Makefile script to build the static library include $(BUILD_STATIC_LIBRARY)
PREBUILT_SHARED_LIBRARY Precompiled script Makeifle shared libraries include $(PREBUILT_SHARED_LIBRARY)
PREBUILT_STATIC_LIBRARY Static library of pre-compiled script Makeifle include $(PREBUILT_STATIC_LIBRARY)
TARGET_PLATFORM Android API level number TARGET_PLATFORM := android-22
TARGET_ARCH CUP architecture arm arm64 x86 x86_64
TARGET_ARCH_ABI CPU architecture armeabi armeabi-v7a arm64-v8a

Module Description variables

variable name description Case
LOCAL_MODULE_FILENAME Construction covering system which generates a default name for the file LOCAL_MODULE := foo LOCAL_MODULE_FILENAME := libnewfoo
LOCAL_CPP_FEATURES C ++ specific features Support exception: LOCAL_CPP_FEATURES: = exceptions
LOCAL_C_INCLUDES Header files directory search path LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CFLAGS C building and build parameters of C ++
LOCAL_CPPFLAGS c++
LOCAL_STATIC_LIBRARIES The current module depends static library modules list
LOCAL_SHARED_LIBRARIES
LOCAL_WHOLE_STATIC_LIBRARIES –whole-archive 将未使用的函数符号也加入编译进入这个模块
LOCAL_LDLIBS 依赖 系统库 LOCAL_LDLIBS := -lz

导出给引入模块的模块使用

LOCAL_EXPORT_CFLAGS

LOCAL_EXPORT_CPPFLAGS

LOCAL_EXPORT_C_INCLUDES

LOCAL_EXPORT_LDLIBS

引入其他模块

#将一个新的路径加入NDK_MODULE_PATH变量
#NDK_MODULE_PATH 变量是系统环境变量
$(call import-add-path,$(LOCAL_PATH)/platform/third_party/android/prebuilt)

#包含CocosDenshion/android目录下的mk文件
$(call import-module,CocosDenshion/android)

#这里即为 我需要引入 CocosDenshion/android 下面的Android.mk
#CocosDenshion/android 的路径会从 $(LOCAL_PATH)/platform/third_party/android/prebuilt 去查找

4. Application.mk

配置

同样是GNU Makefile 片段,在Application.mk中定义一些全局(整个项目)的配置

APP_OPTIM

将此可选变量定义为 releasedebug。在构建应用的模块时可使用它来更改优化级别。发行模式是默认模式,可生成高度优化的二进制文件。调试模式会生成未优化的二进制文件,更容易调试。

APP_CFLAGS

为任何模块编译任何 C 或 C++ 源代码时传递到编译器的一组 C 编译器标志

APP_CPPFLAGS

构建 C++ 源文件时传递到编译器的一组 C++ 编译器标志。

APP_ABI

需要生成的cpu架构(ndk r17之上 只支持:armeabi-v7a, arm64-v8a, x86, x86_64)

APP_PLATFORM

此变量包含目标 Android 平台的名称。例如,android-3 指定 Android 1.5 系统映像

APP_STL

默认情况下,NDK 构建系统为 Android 系统提供的最小 C++ 运行时库 (system/lib/libstdc++.so) 提供 C++ 功能。

APP_ABI架构

不同 Android 手机使用不同的 CPU,因此支持不同的指令集。

armeabi

此 ABI 适用于基于 ARM、至少支持 ARMv5TE 指令集的 CPU。此 ABI 不支持硬件辅助的浮点计算。 相反,所有浮点运算都使用编译器 libgcc.a 静态库中的软件帮助程序函数。

armeabi-v7a

armeabi-v7a ABI 使用 -mfloat-abi=softfp 开关强制实施规则,要求编译器在函数调用时必须传递核心寄存器对中的所有双精度值,而不是专用浮点值。 系统可以使用 FP 寄存器执行所有内部计算。 这样可极大地加速计算。

如果要以 armeabi-v7a ABI 为目标,则必须设置下列标志:

CFLAGS= -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16

arm64-v8a

此 ABI 适用于基于 ARMv8、支持 AArch64 的 CPU。它还包含 NEON 和 VFPv4 指令集。

x86

此 ABI 适用于支持通常称为“x86”或“IA-32”的指令集的 CPU。设置的标志如:

-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32

x86_64

-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel

现在手机主要是armeabi-v7a。查看手机cpu:

adb shell cat /proc/cpuinfo
adb shell getprop ro.product.cpu.abi

apk在安装的时候,如果手机是armeabi-v7a的,则会首先查看apk中是否存在armeabi-v7a目录,如果没有就会查找armeabi。

保证cpu目录下so数量一致。

如果目标是armeabi-v7a,但是拥有一个armeabi的,也可以把它放到armeabi-v7a目录下。但是反过来不行
ABI(横 so)/CPU(竖 手机) armeabi armeabi-v7a arm64-v8a x86 x86_64
ARMV5 支持
ARMV7 支持 支持
ARMV8 支持 支持 支持
X86 支持
X86_64 支持 支持

Guess you like

Origin blog.csdn.net/u011077027/article/details/93211565