一个C文件要变成可执行的文件,须要通过四个过程:linux
主要用到的工具叫作arm-linux-gcc,arm-linux-ld,本次学习的是gcc工具。编程
几条经常使用命令选项:bash
-E:预处理后即中止dom
-S:编译后不汇编编程语言
-c:预处理+编译+汇编,但不链接函数
-o:指定输出文件为file。不管哪一个环节,这个选项均可以使用工具
编译单个文件的语句,只须要一句话便可学习
gcc -o hello hello.c
这条指令,即直接将C文件生成成可执行文件"hello"优化
虽然这里是一条指令,但已经包含了几个步骤了。spa
gcc -E -o hello.i hello.c //对C文件作预处理 gcc -S -o hello.s hello.i //进行编译,生成汇编文件 gcc -c -o hello.o hello.s //对汇编代码编译成目标文件 gcc -o hello hello.o //生成可执行程序hello
对于多个文件,须要进行逐个编译,再作最后的链接。
gcc -c -o mian.o mian.c gcc -c -o sub.o sub.c gcc -o test mian.o sub.o
也能够直接链接编译生成
gcc -o test mian.c sub.c
基本格式:gcc [options] file1 file2... //若不加入参数,则按默认参数依次执行编译、汇编和链接操做,生成的可执行文件名为 a.out 经常使用参数:-E //只执行预处理操做 -S //只执行到编译操做完成,不进行汇编操做,生成的是汇编文件(.s 或 .asm),内容为汇编语言 -c //执行编译和汇编,但不进行连接,即只生成可重定位目标文件(.o),为二进制文件,不生成完整的可执行文件 -o filename //将操做后的内容输出到filename指定的文件中 -static //对于支持动态连接的系统,使用静态连接而不是动态连接进行连接操做 -g //编译时生成debug有关的程序信息(供gdb使用) --save-temps //生成编译过程的中间结果文件(包括预处理文件(x.ii)、汇编代码(x.s)、目标文件(x.o)和最终的可执行文件) -I PATH //在PATH指定的目录下寻找相关的include文件 -lxx //其中xx为指定函数库,对于Linux环境下的函数库,静态库后缀为.a,动态库后缀为.so,通常库名为libxx.a或libxx.so,如加入libm.so库,则使用参数-lm(去除lib和后缀.a\so) -L PATH //在PATH指定的目录下寻找相关的库文件,即-lxx指定待连接的库,-L指定寻找该库的路径。不指定时搜索默认的库函数路径。 -std=xx //指定编译使用的语言标准 -x language //指定待编译文件的语言,而不是由编译器根据文件后缀自行判断。即默认状况下gcc根据文件后缀判断使用的编程语言。例如使用文件名hello做为源文件名是不合适的,应使用hello.c -Wall //输出一些简单的错误以及一些可能存在问题的警告 -Wextra //输出-Wall不包含的警告等 -Werror //将警告视为错误输出 -D name=definition //加入宏定义,若不指定def,则默认为1 -O一、-O2 //规定编译器的优化等级,优化级数越高执行效率通常越好,可是优化会改变原有程序结构,使得其汇编不易理解 //一些进行缓冲区溢出实验时可能须要的选项 -fstack-protector\-fno-stack-protector //是否开启堆栈保护,这里的保护是在返回地址以前加入一个验证值来确保返回地址不被破坏 -z execstack //启用可执行栈,默认是禁用的 //(echo 0 >/proc/sys/kernel/randomize_va_space 关闭地址随机化,这是一个单独的命令,操做须要root权限)
gcc -static hello.o world.o -lm -L /usr/lib //以静态连接的方式,将hello.o、world.o以及libm.a库中的相关目标文件连接,在/usr/lib文件夹下寻找目标库