您尚未登录。

楼主 #1 2018-05-05 19:38:20

xinxiaoci
会员
注册时间: 2018-04-18
已发帖子: 71
积分: 71

GCC常用编译指令及Makefile文件组织编译

《单片机小白转嵌入式Linux学习记录,基于S3C2440----目录》

预处理->编译->汇编->链接

预处理(-E  *.i):处理源码代码中的宏定义,#开头的文件,预处理为 *.i文件
gcc -E -o hello.i hello.c

编译(-S *.S):将预处理后的文件*.i编译为汇编代码文件*.S
gcc -S -o hello.S hello.c

汇编(-c *.o):编译和汇编。将汇编代码问价*.S 汇编为(OBJ) *.o文件
gcc -c -o hello.o hello.S

链接:将*.o文件链接为一个可执行文件
gcc -o hello hello.o

----------------------------------------------------
文件后缀与编译器默认动作关系

.c        c源程序                预处理、编译、汇编
.C        c++源程序            预处理、编译、汇编
.cc        c++源程序            预处理、编译、汇编
.cxx    c++源程序            预处理、编译、汇编
.m        Objective-C源文件    预处理、编译、汇编
.i        预处理后的c文件        编译、汇编
.ii        预处理后的c++文件    编译、汇编
.s        汇编语言源程序        汇编
.S        汇编语言源程序        预处理、汇编
.h        预处理器文件        通常不出现在命令行上
----------------------------------------------------

ldd hello //显示所链接的动态库

gcc -0 -static hello hello.o //静态链接,把库直接链接在程序内,所以程序体积较大

-----------------------------

gnu make 中文手册
https://blog.csdn.net/Sun_Jianhua/article/details/494002

-----------------------------
Makefile

test:a.o b.o
    gcc -o test a.o b.o
a.o:a.c
    gcc -c -o a.o a.c
b.o:b.c
    gcc -c -o b.o b.c
-----------------------------

Makefile 格式

目标文件:依赖文件1 依赖文件2 ...
[TAB]命令
   
编译命令执行条件:
1.当依赖文件比目标文件新
2.依赖文件不存在
   
-----------------------------

特殊符号

test:a.o b.o c.o
    gcc -o test $^
%.o:%c
    gcc -c -o $@ $<

%.o %c : %号表示通配符   
$^ 表示所有的依赖 a.o b.o c.o
$@ 表示目标文件
$< 表示第一个依赖文件

--------------------------
假想目标

clean:
    rm *.o test
   
.PHONY:clean

如果不定义 .PHONY:clean 当编译目录有clean文件名时,make clean 命令将不会被执行
-------------------------
变量:简单变量(即时变量)、延时变量、export

A:=xxx        # A的值在定义时即确定
B = xxx        # B的值用到是才确定

举例
----------------
A :=$(C)
B =$(C)
C =abc

all:
    @echo A=$(A)    # A=
    @echo B=$(B)    # B=abc123456
   
C +=123456
----------------
:=        #即时变量
=        #延时变量
?=        #延时变量,第一次定义才有效,如果前面已有该变量,则不执行
+=        #附加,它是即时变量还是延时变量取决于前面的定义

可以在make时传入变量值

    make a=ssss
---------------------------------------

Makefile 函数
a.    $(foreach var,list,text)

b.    $(filter pattern...,text)            # 在text中提取符合pattern格式的值
    $(filter-out pattern...,text)        # 在text中提取不符合pattern格式的值

c.    $(wildcard pattern)                    # pattern定义了文件名的格式
                                        # wildcard取出其中存在的文件
d.    $(patsubst pattern,replacement,$(var))    # 从列表中取出每一个值

                                            # 如果符合pattern则替换为replacement
例 a>
--------------
A = a b c
B =$(foreach f,$(A),$(f).o)

all:
    @echo B = $(B)   
   
# 执行结果:B = a.o b.o c.o
   
--------------   
例 b>
--------------   
A = a b/ c d/
B =$(filter %/,$(A))        # 匹配的字符串
C =$(filter-out %/,$(A))    # 不匹配的字符串

all:
    @echo B = $(B)
    @echo C = $(C)
# 执行结果:
# B = b/ d/
# C = a c
--------------                                           
例 c>
--------------   

file =$(wildcard *.c)        # 获得当前文件夹下以 .c 结尾的文件

A = b.c c.c e.c d.c

file2 = $(wildcard $(A))    # 以A变量中的值,去匹配所在文件夹下的文件名

all:
    @file = $(file)

# 假设Makefile所在文件夹下有 a.c b.c c.c

# 执行结果:
# file = a.c b.c c.c
# file2 = b.c c.c
--------------                                               
例 d>
--------------   

A = a.c b.x c.c e.c d.c   

rep = $(patsubst %.c,%.o,$(A))

all:
    @echo rep = $(rep)
# 执行结果:
# rep = a.o b.x c.o e.o d.o

--------------   

自动生成依赖
https://blog.csdn.net/qq1452008/article/details/50855810

gcc -M c.c                        # 查看c.c的依赖文件
gcc -M -MF c.d c.c                 # 生成c.c的依赖文件 c.d
gcc -c -o c.o c.c -MD -MF c.d     # 编译同时生成依赖文件 c.d   

---------------------------------------
Makefile综合练习

SRCS = $(wildcard *.c)                    # 获取当前目录下所有的 .c文件名列表
OBJS = $(patsubst %.c,%.o,$(SRCS))        # 生成目标所依赖的 .o文件名列表
DEPS = $(patsubst %,.%.d,$(OBJS))        # 生成依赖文件 .%.d 文件名列表
CFLAGS = -Werror -Iinclude                # 所有警告都当做错误来处理 去./include目录查找头文件
.PHONY:clean                            # 假想目标,防止有clean同名文件而无法执行clean命令
all: main
-include $(DEPS)   # 加载所有依赖.%.d文件 '-'号的作用:加载错误时,会继续执行 make,主要是考虑到首次 make 时,目录中若不存在 '.*.d' 文件时,加载便会产生错误而停止 make 的执行

%.o:%.c
    gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d -MP    # $@ 目标文件 $< 第一个依赖文件.c 并将.c的依赖(头文件)输出到 .*.o.d
   
main: $(OBJS)
    gcc -o $@ $^    #注释:$^:表示所有的依赖文件$(OBJS)  $@:表示目标文件

clean:
    rm -f  *.d *.o main
------------

离线

#2 2018-05-05 20:03:51

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,191
积分: 9197

Re: GCC常用编译指令及Makefile文件组织编译

.C        c++源程序            预处理、编译、汇编

这个坑见识过了,
gcc默认当c++导致链接失败。
当时这个问题找了挺久。

离线

楼主 #3 2018-05-05 20:25:03

xinxiaoci
会员
注册时间: 2018-04-18
已发帖子: 71
积分: 71

Re: GCC常用编译指令及Makefile文件组织编译

晕哥 说:

.C        c++源程序            预处理、编译、汇编

这个坑见识过了,
gcc默认当c++导致链接失败。
当时这个问题找了挺久。

谢谢晕哥提醒!我记下来!

离线

#4 2018-05-05 21:29:00

Lvy
会员
注册时间: 2017-11-25
已发帖子: 103
积分: 97.5

Re: GCC常用编译指令及Makefile文件组织编译

这坑够深的,记下来晕哥!!

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn