Makefile入门教程(结合Android源码编译用例)
一、引言
Makefile是用于自动化构建项目的工具,尤其在Android源码编译中扮演着至关重要的角色。Makefile文件包含了构建过程中所需的各种规则、依赖关系和命令。通过Makefile,我们可以方便地编译、链接和安装项目。
二、Makefile基础
1. 目标和依赖
Makefile的基本单位是规则,每条规则由目标、冒号和依赖列表组成。目标是要生成的文件,依赖是生成目标所需的文件或条件。
例如,一个简单的Makefile规则可能如下:
hello: hello.c
gcc hello.c -o hello
在这个例子中,hello
是目标,hello.c
是依赖。当执行make hello
时,如果hello.c
存在且hello
不存在或hello
比hello.c
旧,则会执行gcc hello.c -o hello
命令来生成hello
。
2. 变量
Makefile支持变量,可以方便地替换命令中的重复部分。
CC = gcc
CFLAGS = -Wall
hello: hello.c
$(CC) $(CFLAGS) hello.c -o hello
3. 通配符和模式规则
Makefile支持使用通配符和模式规则来匹配多个文件。
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
这条规则表示将所有的.c
文件编译成对应的.o
文件。$<
代表依赖列表中的第一个依赖(即.c
文件),$@
代表目标(即.o
文件)。
三、Android源码编译中的Makefile
Android源码编译是一个复杂的构建过程,涉及大量的Makefile文件。下面以Android源码中的某个模块为例,介绍Makefile的用法。
假设我们有一个简单的Android模块,其目录结构如下:
my_module/
Android.mk
src/
main.c
1. Android.mk文件
在Android源码中,每个模块通常包含一个Android.mk
文件,用于描述模块的构建规则。
# 定义LOCAL_PATH为当前目录路径
LOCAL_PATH := $(call my-dir)
# 清除之前定义的变量
include $(CLEAR_VARS)
# 定义模块信息
LOCAL_MODULE := my_module
LOCAL_SRC_FILES := src/main.c
# 包含需要的库文件
LOCAL_SHARED_LIBRARIES := \
libutils \
libcutils
# 定义编译类型
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH
:指定当前模块的路径。include $(CLEAR_VARS)
:清除之前定义的变量,确保每个模块都有自己的独立环境。LOCAL_MODULE
:定义模块的名称。LOCAL_SRC_FILES
:指定模块的源文件列表。LOCAL_SHARED_LIBRARIES
:指定模块依赖的共享库。include $(BUILD_SHARED_LIBRARY)
:指定编译类型,这里是生成共享库。
2. 构建模块
在Android源码根目录下执行以下命令来构建模块:
source build/envsetup.sh
lunch <target_product>-<target_build_variant>
mmm my_module/
source build/envsetup.sh
:初始化构建环境。lunch <target_product>-<target_build_variant>
:选择构建目标和变体。mmm my_module/
:只构建my_module
模块。
四、常用指令和函数
1. 条件判断
Makefile支持条件判断,