欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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
相关标签: linux