Android实战技巧之三十六:Makefile快速入门

目标

通过一篇文章的介绍达到能够编写简单Makefile以及能够看懂普通的Makefile之目的。

make简介

make是一个老牌的构建(build)工具,1970年问世以来已经度过了45年的时光而魅力不减,这在技术发展日新月异的今天是不可思议的。make在大型的软件项目中发挥着巨大作用。我是在学习Linux kernel时才第一次接触它,Android系统也是用make和python等脚本一起构建系统,所以掌握make知识是你迈进这些系统的第一道坎。你一定要给予make足够的重视,不要以为掌握了C/C++、Java这些主力编程语言就可以掌控世界,当你迷失在海量的Makefile以及各种*.py,*.sh时,没有构建系统的知识是令人抓狂的。

make的优点是你可以把程序中各元素之间的关系告诉make,之后make会根据这些关系和时间戳去判断应该重新编译哪些步骤以产生你需要的程序。这就是我们常说的增量编译。

一个最简单的Makefile

通常make是根据Makefile/makefile执行工作的,Makefile中包含了一组用来编译程序的规则。一项规则可分为三个部分:目标(target)、必要条件(prereq)以及所要执行的命令(command)。

target: prereq1 prereq2
    commands

C文件只有一个main.c

#include <stdio.h>

int main(int argc, char** argv) {
        printf("hello, makefile!\n");
}

第一个Makefile

#first makefile
hello-makefile: main.c
       gcc -o hello-makefile main.c

解读如下:

这个Makefile是由一项任务(规则)组成,目标是一个叫作hello-makefile的可执行文件,必要条件是main.c文件,而命令是一个gcc的编译命令。

执行结果如下:

$ make
gcc -o hello-makefile main.c

第二个Makefile

#final target
hello-makefile: main.o
        gcc -o hello-makefile main.o
#main.o
main.o: main.c
        gcc -c main.c

解读如下:

将上述步骤分解成两步,为了生成hello-makefile需要依赖一个条件是main.o,而接着将main.o作为目标再写一条规则。通常一个Makefile就是由这样多个不同的规则组合而成。

执行结果如下:

$ make
gcc -c main.c
gcc -o hello-makefile main.o

Makefile基本语法

从上而下的结构

就像上面的Makefile那样,默认从最上层的工作目标(通常称为all)开始工作,把有些工作目标如clean工作放在文件的最底部。

特殊符号

井号(#)用来表示注释

反斜杠(\)当作续行符

通配符

与常用shell通配符一致。

星号(*)代表任意数量的任意字符,问号(?)代表一个任意字符。

.PHONY

假想工作目标,并且可以避免名字冲突。出现在如下场合:

.PHONY: clean
clean:
        rm -f *.o

常用的.PHONY如下:

all        执行编译应用程序的所有工作
install    从已编译的二进制文件进行程序的安装
clean      清楚生成的二进制文件
distclean  清楚所有生成的文件
TAGS       建立可供编辑器使用的标记表
check      执行与程序相关的任何测试

变量

$(variable)
${}

变量名称是单一字符的就不用括号了。

VPATH

告诉make如果在当前目录没有找到,就去指定的目录找。比如:

VPATH = src include

C++标示

有时需要输入一些参数告诉gcc做一些事,比如加入-I选项告知启动隐含编译规则:

CPPFLAGS = -I include

include关键字

有时需要调用其他的makefile,只需要用include将其加入就可以了:

include /home/linc/workspace/lab/OpenCV-android-sdk-2.4.11/sdk/native/jni/OpenCV.mk

接下来

读读《GNU Make项目管理》吧,更深入的知识和经验都可以在书中找到。

时间: 2024-10-10 09:38:33

Android实战技巧之三十六:Makefile快速入门的相关文章

Android实战技巧之三十:人脸检测-静态

最近微软的how-old.net把人脸识别技术又大大的火了一把.通过大数据和复杂的算法,能够神奇的预测出照片中人物的性别和年龄.虽然错误率也不低,但是大家都抱着玩一玩乐一乐的心态把照片传上去让机器来鉴定一下自己的颜龄. 人脸识别算法是高深复杂的,面对着计算机视觉的种种数学公式,我就已经投降了.先来简单的玩玩人脸检测吧.Android早已提供了FaceDetector类,今天就来看看如何使用这个类人脸检测吧. 流程: 1.打开文件夹选择照片 2.将照片加载到bitmap中并缩放到设置的宽高 3.用

Android实战技巧之三十二:Android Studio中的源代码管理

Android Studio最近经过了两次升级到了Android Studio 1.2.1.1, 用起来是越来越顺手了.AS中加入了主流的源码管理工具,让开发者不用离开AS就可以提交和管理代码. 下面就演示一下在AS中使用git管理代码. 选择要提交的代码 右键->commit 编写commit message 可以选择commit and push一起完成提交的动作 确认后push 查看提交历史和对比文件 总结: 玩git的都知道在命令行下有些版本历史信息的显示是不方便的,我们需要借助gitk

Android实战技巧之三十五:了解native activity

1.native activity的意义 很多人觉得Android的Fwk提供的支持足够好了,既然Google不推荐用Ndk开发为什么又放宽Ndk的限制而推出可以无Java开发Android App呢?我的理解是不同的技术实现会有其适合的场景. Ndk的适用场景官方给出三点:1.平台间的App移植 2.复用现有库 3.对软件性能要求较高的场合比如游戏等.那么native activity在十分适合游戏领域,比如cocos-2dx对其的使用. 2.初步了解native activity 借助SDK

Android实战技巧之三十八:Handler使用中可能引发的内存泄漏

问题描写叙述 曾几何时,我们用原来的办法使用Handler时会有以下一段温馨的提示: This Handler class should be static or leaks might occur 以下是更具体的说明(Android Studio上的警告,不知道Eclipse上是否同样) Since this Handler is declared as an inner class, it may prevent the outer class from being garbage coll

Android实战技巧之十六:getprop与dumpsys命令

Android设备连接PC后,我们可以通过adb命令完成绝大多数工作.下面借助getprop.dumpsys来了解一些系统相关信息. 一.getprop 此命令的原理很简单,就是从系统的各种配置文件中读取信息.那么这些文件在你用adb shell进入设备内部后很容易找到,它们是: init.rc default.prop /system/build.prop 此时直接使用cat命令也是可以把这些信息显示出来的. 下面列出比较常用的信息 1.获得IP $ adb shell getprop dhc

Android实战技巧之四十四:Hello,Native!

在Android上运行C程序对于做上层App的童鞋来说有些陌生,因为目前的Android应用开发怎么还是绕不过Java. 但对于底层驱动开发者,这就是家常便饭一样,因为Android是Linux分支,底层是C/C++的世界. 有时为了测试一些功能,我们也会编写直接运行在Android终端下的C程序.前提是有Android交叉编译器以及Android系统的root权限. 交叉编译工具 ndk为我们开发native程序做了很多工作,下面我们将Android交叉编译工具从ndk中分离出来. 我的系统是

Android实战技巧之四十九:Usb通信之USB Host

零 USB背景知识 USB是一种数据通信方式,也是一种数据总线,而且是最复杂的总线之一. 硬件上,它是用插头连接.一边是公头(plug),一边是母头(receptacle).例如,PC上的插座就是母头,USB设备使用公头与PC连接. 目前USB硬件接口分三种,普通PC上使用的叫Type:原来诺基亚功能机时代的接口为Mini USB:目前Android手机使用的Micro USB. Host USB是由Host端控制整个总线的数据传输的.单个USB总线上,只能有一个Host. OTG On The

【转】Android实战技巧之四十九:Usb通信之USB Host

零 USB背景知识 USB是一种数据通信方式,也是一种数据总线,而且是最复杂的总线之一. 硬件上,它是用插头连接.一边是公头(plug),一边是母头(receptacle).例如,PC上的插座就是母头,USB设备使用公头与PC连接. 目前USB硬件接口分三种,普通PC上使用的叫Type:原来诺基亚功能机时代的接口为Mini USB:目前Android手机使用的Micro USB. Host USB是由Host端控制整个总线的数据传输的.单个USB总线上,只能有一个Host. OTG On The

Android实战技巧之十二:Android Studio导入第三方类库、jar包和so库

第三方类库源码 将一网友的XMPP代码从ADT转到AS时,发现其使用了第三方类库,源码放在了lib下,直接在AS中Import project,第三方类库并没有自动导入进来,看来需要自己动手了. 项目的目录结构如下: XMPP$ ls app build.gradle gradlew import-summary.txt XMPP.iml build gradle gradlew.bat local.properties settings.gradle 1 2 3 1 2 3 将第三方源码qqE