主要介绍一些linux下常用开发工具:gcc编译器,gdb调试器,make工程管理器
gcc
编译
1:从源文件到可执行文件经历了四个步骤:预处理,编译,汇编.(以hello.c为例)
#include<stdio.h>
#define N 10
int main(void)
{
#ifndef N
printf(“hello world\n”);
#endif
#ifdef N
printf(“N = %d\n”, N);
#end if
return 0;
}
预处理:gcc -E hello.c -o hello.i
主要进行头文件展开,宏替换,条件编译.
用vim打开hello.i
可以看见前面一长串都是头文件stdio.h,拉到最后,可以看见printf里面的N被替换成10,上面不满足条件的hello world也在预处理这一步完成。
2编译:进行语法检查,生成汇编文件
编译:gcc -S hello.c
生成.s汇编文件
3汇编: 生成目标文件
gcc -c hello.c
生成hello.o文件
4链接
将目标文件的符号建立符号表,生成可执行文件
交叉编译
定义:在当前cpu平台编译出在其他平台上能运行的代码。
打开刚才生成的hello.s汇编文件会看到汇编语言,而不同cpu能运行的汇编语言不同,这个是针对x86平台生成的汇编语言,如果移植到其他系统,就不能运行生成的可执行文件。
所以实现交叉编译,就是在当前平台下生成其他平台运行的代码,可以通过安装交叉编译器来生成其他平台适用的汇编文件。
为什么不直接在其他平台上编写代码呢?
一种开发模式:宿主机开发,目标机运行。目标机往往是一些开发板上的系统,显然在其上开发难度比在pc端开发难。
gcc -l
链接库,如需要用到math.h在编译时候加上后缀-lm
gcc -O123
编译优化,分为123级别的优化
gcc -L 目录
在这个目录下寻找库文件
gcc -o 给可执行文件重命名
gcc -w 关闭警告
gcc -Wall 开启警告
gcc -D
外部定义宏
例如hello.c
#include<stdio.h>
int main()
{
#ifdef DEBUG
printf(“出现错误\n”);
#endif
printf(“hello world\n”);
return 0;
}
执行:gcc hello.c -o hello -DEBUG
运行:./hello
结果:出现错误
hello world
执行:gcc hello.c -o hello
运行:./hello
结果:hello world
为什么要用-D选项?
在调试程序时候最简单方法在要调试程序下面加一行printf 调试完成后不希望出现调试信息,把调试信息注释掉。用-D比较方便调试。
gdb简介
功能:1运行程序
2:设置断点
3:查看变量值
在编译时候加上-g选项
如gcc hello.c -g -o hello
如何启动gdb? gdb hello
相关命令
l(list) 每10行列出源码
r (run) 运行程序
b(breakpoint)设置断点
b 7 在第七行设置断点
b 函数 在函数处设置断点
查看断点:info b
删除断点:d(delete)
继续运行:c(continue)
单步执行:n不进入子程序单步执行
s进入子程序单步执行
查看变量值:p(print)
工程管理器make
一个.c用gcc很方便,那多个源文件编译呢?
工程?
多个源文件,头文件,资源文件构成的项目代码
功能
按照makefile里面规定的过程进行自动编译
makefile
是一个脚本文件,进行批处理
makefile语法
目标:依赖
命令
根据依赖的文件执行命令生成目标例如:
hello :hello.o
gcc hello.o -o hello
用make 启动makefile
如果单单是make从第一个目标开始执行
如果make 目标 从指定目标开始执行makefile里的命令,,且一般指定的目标是伪目标.PHONY
makefile基本语法,函数
(举例的形式说明,一般复杂点的能看懂就行)
1:
obj = 1.o 2.o
target = 可执行文件名
gcc $(obj) -o
(
t
a
r
g
e
t
)
遇
到
(target) 遇到
(target)遇到()就用里面的替换
2:@隐藏命令
3:
(
M
A
K
E
)
−
c
子
目
录
进
入
子
目
录
,
找
到
子
目
录
的
m
a
k
e
f
i
l
e
执
行
m
a
k
e
4
:
函
数
p
a
t
s
u
b
s
e
t
模
式
参
数
,
参
数
1
,
参
数
2
功
能
:
把
参
数
2
符
合
模
式
参
数
的
,
替
换
成
参
数
1
返
回
:
被
替
换
的
参
数
2
w
i
l
d
c
a
r
d
模
式
参
数
功
能
:
列
出
当
前
目
录
所
有
符
合
模
式
参
数
的
文
件
返
回
:
所
有
符
合
参
数
的
文
件
名
a
d
d
s
u
f
f
i
x
参
数
1
,
参
数
2
功
能
:
为
参
数
2
加
上
参
数
1
后
缀
返
回
:
加
上
后
缀
的
参
数
2
f
o
r
e
a
c
h
变
量
参
数
,
参
数
1
,
表
达
式
功
能
:
循
环
把
1
给
变
量
参
数
然
后
运
行
表
达
式
返
回
:
表
达
式
运
行
结
果
c
a
l
l
变
量
参
数
,
参
数
功
能
:
循
环
把
参
数
依
次
赋
值
给
变
量
参
数
中
的
(MAKE)-c 子目录 进入子目录,找到子目录的makefile执行make 4:函数 patsubset 模式参数,参数1,参数2 功能:把参数2符合模式参数的,替换成参数1 返回:被替换的参数2 wildcard 模式参数 功能:列出当前目录所有符合模式参数的文件 返回:所有符合参数的文件名 addsuffix 参数1,参数2 功能:为参数2加上参数1后缀 返回:加上后缀的参数2 foreach 变量参数,参数1,表达式 功能:循环把1给变量参数然后运行表达式 返回:表达式运行结果 call 变量参数,参数 功能:循环把参数依次赋值给变量参数中的
(MAKE)−c子目录进入子目录,找到子目录的makefile执行make4:函数patsubset模式参数,参数1,参数2功能:把参数2符合模式参数的,替换成参数1返回:被替换的参数2wildcard模式参数功能:列出当前目录所有符合模式参数的文件返回:所有符合参数的文件名addsuffix参数1,参数2功能:为参数2加上参数1后缀返回:加上后缀的参数2foreach变量参数,参数1,表达式功能:循环把1给变量参数然后运行表达式返回:表达式运行结果call变量参数,参数功能:循环把参数依次赋值给变量参数中的(1)、$(2)…
返回:赋值后的变量值
企业级makefile编写
1:总控makefile
功能:进入子目录执行make,将所有.o文件链接成可执行文件
2:功能目录makefile
功能:将功能目录下的.c变成.o
3:脚本目录scripts的makefile
功能:定义其他makefile文件所用到的变量
怎么阅读呢?
顺序:312
大方向:
目标:依赖
命令 (命令前面是一个tab键)