IDE隐藏的细节在这里得以显示,为什么交叉编译后,就可以在不同的平台运行?而不同平台的运行,才真正的进入到嵌入式开发的大门。
gcc编译过程参数:记忆用英文去记
-c:只编译不链接,生成目标文件.o compare
-S:生成汇编文件 assemble
-E:只预编译 presses
-g:包含调试信息。GDB
-o file:指定目标输出文件 OUTPUT
-l dir:搜索头文件路径 include
linux下静态链接库和动态链接库的格式:
.a[filename a]//静态库
.so[filename so+主版本号、次版本号、发行号]//动态库
-static 静态编译
-shared 1、生成动态库文件2、进行动态编译 默认的
-I dir 库文件搜索中添加路径
-fPIC 生成使用相对位置无关的目标代码(Position Indepedent code),用于static选项从PIC目标文件生成动态库文件
编译静态链接库:
1、先生成目标文件.o
2 ar crv[*.a][*.o] #打包为 .a 的静态链接库文件
调用静态链接库:
gcc -o「file]「file.c] -l[file.a]如:gcc cxd.c -o cxd -L /root/desktop/hello.a #调用自己的静态链接库
编译动态链接库:
1、生成与位置无关的目标代码 gcc -fPIC -c [*.c]
2、gcc -shared -o[*.so][*.o]
调用动态链接库:
gcc -o[file][file.c] -l [file.so]
gcc -fPIC -c hello.c #编译成位置无关的 .o 文件
gcc -shared hello.o -o hello.so #生成动态链接库
gcc cxd.c -o cxd -L /root/desktop/hello.so #调用自己的动态链接库
警告信息:
-w:关闭所有警告
-wall:发出gcc所有有用的警告
-pedantic:发出ansi c 的所有的警告。形式化的,比较有用
优化选项:
-o[level]:优化等级,一般为0-3,只在发布时才用。
gdb调试信息设置:
在我们学习使用GDB调试程序之前,我们先看看GDB有哪些命令。
命令 功能
r run, 直接调到断点处,没有设置断点的话直接运行程序
b fun 设置一个断点breakpoint在函数”fun”的最开始
b N 在当前运行源文件的第N行设置断点
b file.c:N 在当前源文件file.c的第N行设置断点
d N 删掉delete第N行的断点
info break 显示所有断点信息
c 继续(continue)运行程序,一直到下一个断点或程序结束
f 运行直到当前函数(function)结束
s 按step调试1行,会进入函数体
s N 按step调试接下来的N行
n 调试1行,与按s命令不同的是此处不进入函数体
p var 输出(print)变量”var”的值
set var=val 设置变量”var”的值
bt 打印调用堆栈(stack trace)
q 退出gdb
GDB使用说明
GDB有如下两种使用方式
1. 调试会崩溃、有逻辑错误的程序
2. 调试程序崩溃时自动生成的coredump
下面说明如何GDB调试
编译并构建程序,加上调试选项-g,e.g. gcc -g main.cpp -o test.out
用GDB来运行程序,gdb test.out
使用GDB命令来分析、调试程序
退出GDB
make文件:经过VI编辑,GCC编译后,要想多个文件的编辑或者叫project 或 make 在.net和deliphe里面都叫make,然后才是安装和发布,安装包的制作过程;linux也是通过makefile文件完后最后两步。
make作用:
1、工程文件组织,编译成复杂的程序。
2、安装及卸载我们的程序。
makefile编写规则:
由若干规则所构成,每个规则又符合这样的结构:targer(目标):prequisities(依赖)\n command(命令)。
用#来代表注释
变量:
1、用户自定义变量:
makefile变量在声明的时候需要对其进行赋值,而在使用该变量时需要在变量名前加上$符号,例如$(VARNAME)。如果用户需要在makefile文件中使用$字符,则用$$来表示,这种应用多出现在对shell变量的使用上。
1.使用“=”操作符,相当于是C中的宏替换。
这种定义变量值的方法有一个潜在的危险就是递归定义。例如:
a = $(b)
b = $(a)
make会检测出这种错误
2.使用“:=”操作符,避免上述危险。
2、预定义变量
AR 归档维护程序的名称,默认值为 ar。
ARFLAGS 归档维护程序的选项。
AS 汇编程序的名称,默认值为 as。
ASFLAGS 汇编程序的选项。
CC C编译器的名称,默认值为 cc。
CCFLAGS C编译器的选项。
CPP C预编译器的名称,默认值为 $(CC) -E。
CPPFLAGS C预编译的选项。
CXX C++编译器的名称,默认值为 g++。
CXXFLAGS C++编译器的选项。
FC FORTRAN编译器的名称,默认值为 f77。
FFLAGS FORTRAN编译器的选项。
3、自动化变量及环境变量
makefile中的自动化变量
自动化变量 | 表示的意义 |
$@ | 表示规则中的目标文件集 |
$% | 仅当目标是函数库文件时,表示规则中的目标成员名。例如,一个目标是foo.a(bar.o),那么,$%就是bar.o,$@就是foo.a。如果目标文件不是函数库文件,其值为空 |
$< | 依赖列表中的第一个依赖的名字 |
$? | 所有比目标新的依赖的合集,以空格分隔 |
$^ | 所有依赖的集合,以空格分隔。如果依赖中有多个重复的,只保留一份 |
$+ | 这个变量很像$^,也是所有依赖的集合,但是它不去除重复的依赖 |
$* | 这个变量表示目标模式中“%”及之前的部分 |
makefile的工作流程:
1、make会在当前目录下寻找Makefile或makefile的文件
2、如果找到,他会找文件中的第一个目标文件(tager)并把这个文件作为最终的目标文件。
3、根据时间戳生成目标文件
4、递归去寻找目标文件的信赖文件,并且递归生成(同样有时间戳问题)。
伪目标:只执行命令的的目标
将一个目标声明为伪目标需要将它作为特殊目标.PHONY
的依赖。如下:
.PHONY: clean
clean:
rm *.o temp//命令行前加@ 符,则此行命令不会输出
引用其他的makefile及makefile嵌套:
包含:
include procmakefile
嵌套:
一般使用一个总控Makefile来指明文件的编译规则
如:
subsystem:
cd subdir && $(MAKE)
其等价于
subsystem:
$(MAKE) -C subdir
这两者表达相同的意思:先进入“subdir”目录中,然后执行make命令;
条件判断:如
ifeq ($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
makefile管理命令:
-C dir//读入指定目录下面的makefile文件 C包含的意思
-f dir//指定file文件为makefile文件
-i//忽略所有命令的执行错误
-I dir//指定makefile被包含在哪个目录下。
昨晚开会,开到快10点,回来就不早了……,今天继续
autotools:生成configurater,makefile的自带工具。
实际工程,会用一些IDE,提高开发效率,但用GNU下的工具开发,才是基础,一些IDE都是执行这些基础。