GCC编译工具
程序员文章站
2022-07-14 13:09:31
...
GCC编译工具的使用
这两学习了一下Linux程序编译,在这里分享一下。
示例工程
首先需要创建2个头文件、3个C语言源程序文件:
- mian.c (源程序):主程序
- hello.h (头文件) 和 hello.c(源文件):打印信息的功能模块。
- init.h(头文件) 和 init.c(源文件):初始化执行并访问数据的功能模块
main.c的内容
#include <stdio.h>
#include <stdlib.h>
#include "hello.h"
#include "init.h"
void aftermain(void)
{
printf("\n");
printf("<<<<< aftermain >>>>>\n");
printf("<<<<<<<<<<<<<<<<<<<<<\n");
return ;
}
int main(int argc, char* argv[])
{
printf("===== main =====\n");
init(1234);
hello(argc, argv);
atexit(aftermain);
printf("===== exit main====="\n);
return 0;
}
hello.h的内容
//使用宏定义确保不被重复定义
# ifndef __HELLO_H__
# define __HELLO_H__
int hello(int argc, char* argv[]);
#endif
hello.c的内容
#include <stdio.h>
#include "hello.h"
void hello(int argc, char* argv[])
{
int i;
printf("Hello world!\n");
for(i=0;i<argc;i++)
{
printf("argv[%d]=%s\n", i, argv[i]);
}
return 0;
}
init.h的内容
//使用宏定义确保不被重复定义
# ifndef __INIT_H__
# define __INIT_H__
int init(int number);
#endif
init.c的内容
#include <stdio.h>
#include "init.h"
// 全局只读数据
const char ro_data[1024] = {"This is readonly data"};
// 局部读写数据
static char rw_data[1024] = {"This is readwrite data"};
// 局部未初始化数据段
static char bss_data[1024];
void init(int number)
{
printf("input number:%d\n", number);
printf("ro_data:%x, %s\n", (unsigned int)ro_data, ro_data);
printf("rw_data:%x, %s\n", (unsigned int)rw_data, rw_data);
printf("bss_data:%x, %s\n", (unsigned int)bss_data, bss_data);
return number;
}
将以上文件编译成可执行程序,执行过程如下所示:
$ ./test abc 123
===== main =====
input number:1234
ro_data:8048652, This is readonly data
rw_data:8048031, his is readwrite data
bss_data:804953,
Hello world!
argv[0]=./test
argv[1]=abc
argv[2]=123
===== exit main =====<<<<< aftermain >>>>>
<<<<<<<<<<<<<<<<<<<<<
编译、汇编和连接
单个源文件编译
默认存储为a.out
$ <prefix>-gcc main.c
存储为指定文件名称
$ <prefix>-gcc main.c -o main.o
多个源文件编译
$ <prefix>-gcc main.c hello.c init.c -o test
生成目标文件
$ <prefix>-gcc -pipe -g -Wall -I -c -o main.o mian.c
- -pipe表示使用管道替换临时文件
- -表示包含当前目录作为搜索路径
- -g 表示包含调试信息
- -Wall 表示输出所有的警告
- -o 指定目标文件的名称
- 连接3个目标文件
$ <prefix>-gcc -Wall -g hello.o init.o main.o -o test
ELF格式文件信息读取(readelf)
readelf工具使用方式
readelf [options] file
例如使用-h参数读取目标文件hello.o的ELF头
$ <prefix>-readeld -h hello.o
符号信息工具(nm)
nm工具查看3个目标文件的符号
$ <prefix>-nm main.o hello.o init.o
字符串工具(strings)
string工具使用方式
strings [option(s)] [file(s)]
- -a/-all:扫描整个文件,而不是数据段
- -f:在字符串前面打印文件的名字
- -n --bytes=[number]:定位和打印任何以NULL为结束的序列,至少number个字符
- -t --radix={o, x, d}:基于八、十、十六进制打印字符串
- -o:相当于–radix=o
- -T:指定二进制文件格式
- -h/–help:显示strings的所有选项,然后退出
- -v/–version :显示strings的版本号,然后退出
使用strings查看main.o文件中的字符串
$ <prefix>-strings main.o
去除符号(strip)
使用strip去除可执行程序test中的符号信息
$ <prefix>-strip test -o test_stripped
去除符号信息后使用nm查看文件符号
$ <prefix>-nm test_stripped
nm:test_stripped:no symbols
上一篇: mongodb c driver
下一篇: ActiveMQ vs JbossMQ