最近一直在和Linux C开发打交道,开发过程中会用到交叉编译和Makefile相关知识,但是对这块真的是没有了解,所以在网上搜索,找到一篇不错的博客。本文大部分摘抄自该博客写给安卓程序员的C/C++编译入门(作者:嘉伟咯)。如有侵权请联系删除。
为什么要学C/C++编译
很多的安卓程序员可能都会用Android Studio写一些简单的C/C++代码,然后通过jni去调用,但是对C/C++是如何编译的其实并没有什么概念.有人可能会问,为什么安卓程序员会需要了解C/C++是如何编译的呢?
我一直都认为,要成为一个真正的高级安卓应用开发工程师,安卓源码和C/C++是两座绕不过的大山.安卓源码自然不必多说,而C/C++流行了几十年,存在着许多优秀的开源项目,我们在处理一些特定的需求的时候,可能会需要使用到它们.如脚本语言Lua,计算机视觉库OpenCV,音视频编解码库ffmpeg,谷歌的gRPC,国产游戏引擎Cocos2dx...有些库提供了完整的安卓接口,有些提供了部分安卓接口,有些则没有.在做一些高级功能时,我们常常需要使用源码,通过裁剪和交叉编译,才能编译出可以在安卓上使用的so库.总之,安卓做深做精总避不开C/C++交叉编译。
C/C++编译器
类似java编译器javac可以将java代码编译成class文件,C/C++也有gcc、g++、clang等多种编译器可以用于编译C/C++代码.这里我们用gcc来举例。
gcc原名为GNU C 语言编译器(GNU C Compiler),因为它原本只能处理C语言.但GCC很快地扩展,变得可处理C++。后来又扩展能够支持更多编程语言,如Fortran、Pascal、Objective-C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。
使用gcc其实只需要一个命令就能将一个c文件编译成可运行程序了:
gcc test.c -o test
通过上面这条命令可以将test.c编译成可运行程序test.但是其实C/C++的编译是经过了好几个步骤的,我这边先给大家大概的讲一讲。
C/C++的编译流程
C/C++的编译可以分为下面几个步骤:
预处理
相信学过C/C++的同学都知道"宏"这个东西,它在编译的时候会被展开替换成实际的代码,这个展开的步骤就是在预处理的时候进行的.当然,预处理并不仅仅只是做宏的展开,它还做了类似头文件插入、删除注释等操作.
预处理之后的产品依然还是C/C++代码,它在代码的逻辑上和输入的C/C++源代码是完全一样的.
我们来举一个简单的例子,写一个test.h文件和一个test.c文件:
//test.h
#ifndef TEST_H
#define TEST_H
#define A 1
#define B 2
/**
* add 方法的声明
*/
int add(int a, int b);
#endif
//test.c
#include "test.h"
/**
* add 方法定义
*/
int add(i