《单片机小白转嵌入式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
------------
离线
.C c++源程序 预处理、编译、汇编
这个坑见识过了,
gcc默认当c++导致链接失败。
当时这个问题找了挺久。
谢谢晕哥提醒!我记下来!
离线