ARM之gcc和Makefile

gcc的使用方法:
gcc [选项] 文件名

-v 查看gcc编译器的版本
-o file :指定输出文件名为file,这个file不能跟源文件同名,比如 gcc -o hello  hello.c //file可以为hello,但是不能为hello.c,否则会产生覆盖。
-E :只预编译,不进行编译,汇编和链接
-S:只编译,不会汇编和链接
-c: 负责预编译,编译,汇编,

方式一:
gcc hello.c  输出一个a.out,然后./a.out来执行该应用程序。
gcc -o hello hello.c 输出一个hello.out 然后./hello.out 来执行该应用程序

一个C/C++文件要经过预编译(preprocessing),编译(compilation),汇编(assembly),和链接(linking)4步才能变为可执行文件

hell.c->预处理->hello.i->编译->hello.s->汇编->hello.o(OBJ)->链接->hello

方式二:
gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o(链接)

方式三:
gcc -c -o hello.o hello.c
gcc -o hello hello.o

链接就是将我们写的文件生成的obj文件和系统库的obj文件,库文件链接起来,形成可执行应用程序
ctrl.o ctri.o ctrbegin.o ctrend.o ctrn.o是gcc加入的系统标准启动文件,对于一般的应用程序,这些启动是必需的。
-lc:链接libc库文件,其中libc库文件中就实现了printf等库函数

gcc -v -nostdlib -o hello hello.c 会提示没有链接系统标准启动文件和标准库文件,
-nostdlib选项常用于裸机/bootloader linux内核等程序,因为它们不需要系统标准启动文件,标准库文件
一般应用程序才需要

动态链接使用动态链接库进行链接,生成的程序在执行的时候需要加载所需的动态库才能运行。
动态链接生成的程序体积小。
静态链接使用静态链接库进行链接,生成的程序包含程序运行所需要的全部库,可以直接运行,程序体积大。

gcc -o hello hello.o           //动态链接
gcc -o -static hello hello.o//静态链接

Makefile:
对 gcc -o test A.c B.c//缺点:每次都会执行全部的文件,当A.c被修改后,B.c没有被修改,gcc还是会对B.c进行预编译,汇编,                                   //编译的步骤,这是不必要的。

所以应该分别编译,
gcc -c -o a.c a.o
gcc -c -o b.c b.o
gcc -o test b.c a.c
Makefile通过比较a.c和a.o的生成时间,b .c和b.o的生成时间来查看文件是否被修改

Makefile的规则:1.目标文件:依赖文件 2.TAB 命令
当“依赖文件”比“目标文件”新,执行命令

test:a.o b.o
    gcc -o test a.o b.o//tab键
b.o:b.c
    gcc -o -c b.o b.c
a.o:a.c
    gcc -o -c a.o a.c

写入一个名为Makefile的文件
然后执行指令 make

Makefile的语法:
test:a.o b.o
    gcc -o test a.o b.o //或者 gcc -o test $^(表示所有依赖文件)
%.o:%.c    //%通配符,表示所有(*也是所有)
    gcc -c -o $@ $< //$@表示目标文件,$<表示第一个依赖文件
还可以在Makefile中加上clean
如clean:
  rm *.o test
.PHONY:clean   //PHONY是clean假想的依赖目标,方便clean更新
当执行make clean时就会clean

简单变量,延时变量,export
简单变量(即时变量):
A :=XXX //A的值即刻确定
B=XXX //B是延时变量,使用时才确定

:=  //即时变量
= //延时变量
?=//延时变量,如果是第一次定义才起效
+=//延时变量还是即时变量,取决于

比如 D:=ABC
D?=DEF
@echo$(D)//则打印出ABC,因为在?=前面已经定义过D

Makefile函数:
1.$(foreach var,list,text)  //

A=a b c
B=$(foreach f,$(A),$(f).o )     //用$()来引用函数和变量,foreach变量A中的每个值执行相应的操作,f是临时创建的一个变量,                                               //把a放入f中,然后执行(f).o ,再把b放入f中...

2.$(filter pattern ... text) //从text中取出符合pattern格式的值
3.$(filter-out pattern ... text) //从text中取出不符合pattern格式的值
如B=a b c /d
B=$(filter %/,$(C) )
@echo B=$(B) //打印出来为 /d

4.$(wildcard,pattern) //pattern定义了文件名的格式,wildcard取出其中存在的文件

猜你喜欢

转载自blog.csdn.net/weixin_40288381/article/details/81056160
今日推荐