300 likes | 429 Views
GNU 编译工具链使用简介. 张吉豫 zhangjiyu@mprc.pku.edu.cn 2005-03-12. 内容. GNU 编译工具链的基本组成与工作流程 工具链的常用工具和选项 Unicore 工具链与交叉编译. hello.i (text). hello.s (text). hello.o (binary). hello (binary). hello.c (text). Pre-processor (cpp / Gcc -E). Compiler (cc1 / Gcc -S). Assembler (as / Gcc -c).
E N D
GNU编译工具链使用简介 张吉豫 zhangjiyu@mprc.pku.edu.cn 2005-03-12
内容 • GNU编译工具链的基本组成与工作流程 • 工具链的常用工具和选项 • Unicore工具链与交叉编译
hello.i(text) hello.s(text) hello.o(binary) hello(binary) hello.c(text) Pre-processor(cpp / Gcc -E) Compiler (cc1 / Gcc -S) Assembler (as / Gcc -c) Linker (ld) printf.o(binary) 编译工具链的基本工作流程 一个“hello world”程序的演变历程
GNU工具链的组成 • GCC——GNU Compiler Collection • Binutils——GNU binary utilities • Glibc——GNU C Library ——软件开发的基本工具集合
GCC • 功能: • 高级语言(.c、.cpp、.F)->汇编语言(.s) • 用户界面,驱动各工具的执行 • 组成:一组可执行程序 + 一组库 • cpp、gcc、g++、g77 …… • cpp0、cc1、cc1plus、f771 …… • libgcc.a、crtbegin.o、crtend.o …… • 支持多种语言和目标机
Binutils • 功能: • 汇编语言(.s)->目标文件->可执行程序 • 查看二进制文件信息 • 组成:一组可执行程序 • as、ld • objdump、readelf、ar …… • 支持多种目标机
Glibc • 功能: • 提供语言和操作系统的标准库函数 • 组成:若干可执行程序 + 大量库 • ldd、iconv、locale…… • ISO C、POSIX、UNIX、GNU • 绝大部分与目标机无关
GNU工具链的工作流程 • 扩展名的默认含义 • 需要预处理的源代码:.c、.cc、.F …… • 不需预处理的源代码:.i、.ii、.f …… • 需要预处理的汇编代码:.S • 不需预处理的汇编代码:.s • 目标文件:.o • 静态库:.a • 动态库:.so
.c、.cc、.F .i、.ii、.f .s、.o cpp0 … .c、.cc、.F .i、.ii、.f cc1、cc1plus、f771 … gcc g++ g77 …… .i、.ii、.f .s .s as libgcc.a …… .o .o ld、ar…… glibc 可执行程序或库
常用工具和选项 • 编译: • gcc/g++/g77 • 汇编和连接: • as、ld • 二进制工具: • objdump、readelf、strip、ar、nm、ldd • gprof、gcov
帮助选项 • --help • --target-help • 显示与目标机有关的帮助信息,比如目标机的一些特殊选项
编译(1) • gcc/g++/g77 [options] file... • -Wall • 打印警告信息 • -g • 添加调试信息到输出文件 • -O -O0 -O1 -O2 -O3 -Os • 优化选项,若有多个则最后一个有效 • -D -U • 定义和取消宏定义 • -msoft-float • 使用软件库(libgcc.a)模拟硬件浮点指令
编译(2) • -I • 指定头文件搜索路径,若有多个则从前往后搜索 • -L • 指定库搜索路径,若有多个则从前往后搜索 • -l • 指定引用的库,从当前位置向后搜索 • -static -shared • 使用静态连接或动态连接 • -pg -fprofile-arcs -ftest-coverage • 添加额外的统计代码用于profile,与gprof和gcov配合使用
编译(3) • -E • 输出预处理后的文件(.i、.ii、.f 等) • -S • 输出编译生成的汇编文件(.s) • -c • 输出汇编生成的目标文件(.o) • -o • 指定输出文件名 • -v • 输出编译过程的详细信息,包括编译过程中以哪些参数调用了哪些程序。
编译(4) • 基于profiling的优化编译 • 根据程序执行反馈的信息指导编译优化以产生出更好的代码。 • 使用方法 • 编译:添加-fprofile-arcs选项和其他优化选项进行编译,生成可执行程序 • 执行:执行程序,对每个源程序sourcefile生成sourcefile.da,其中保存了统计信息 • 重新编译:添加-fbranch-probabilities选项和其他相同的优化选项重新编译,生成质量更高的代码
汇编和连接 • as [option...] [asmfile...] • 汇编器,可由gcc -c代替 • ld [options] file... • 连接器,可由gcc代替 • 通常由gcc调用,一般不直接使用
二进制工具 • objdump • readelf • strip • ar • nm • ldd • gprof • gcov
ELF可重定位目标文件示例 sections
二进制工具(1) • objdump [option(s)] [file(s)] • 反汇编各种格式的目标文件和可执行程序 • 常用选项: • -d • 只反汇编代码段 • -D • 反汇编代码段和数据段 • -S • 混合输出源代码和汇编代码,编译时必须加-g选项
二进制工具(2) • readelf [option(s)] elf-file(s) • 显示ELF格式文件信息 • 常用选项: • -e • 显示头信息,包括ELF file header、section header、program header • -s • 显示符号表信息 • -r • 显示重定位信息 • -a • 显示所有信息
二进制工具(3) • strip [option(s)] in-file(s) • 删除输入文件的符号表和指定的section • 常用选项: • -o • 指定输出文件名
二进制工具(4) • ar • 管理归档文件(*.a) • 常用命令: • d m q r t x • 分别用于删除、移动、添加、替换、显示、取出归档文件的内容 • 举例 • ar x /usr/lib/libc.a • 取出libc.a中的所有目标文件(*.o)到当前目录 • ar q libmy.a obj1.o obj2.o • 将obj1.o和obj2.o加入到libmy.a中
二进制工具(5) • nm [option(s)] [file(s)] • 显示文件的符号信息,可用于各种目标文件、可执行程序和归档文件(.a) • 举例 • nm /usr/lib/libc.a > symbol …… printf.o: 00000000 T _IO_printf 00000000 T printf U stdout U vfprintf ……
二进制工具(6) • ldd [OPTION]... FILE... • 输出动态连接程序的共享库依赖关系 • 举例 [njt@Aquarius temp]$ ldd /bin/ls libtermcap.so.2 => /lib/libtermcap.so.2 (0x40028000) libacl.so.1 => /lib/libacl.so.1 (0x4002d000) libc.so.6 => /lib/i686/libc.so.6 (0x42000000) libattr.so.1 => /lib/libattr.so.1 (0x40033000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) [njt@Aquarius temp]$
二进制工具(7) • gprof • 根据程序执行产生的数据(gmon.out)输出profile信息,包括每个函数执行时间、所占比例、调用关系等。 • 可用于分析程序的关键代码,指导程序员进行优化 • 使用方法 • 编译:加-pg选项 • 执行:产生gmon.out(二进制数据) • 显示:gprof program_name > output
二进制工具(8) • gcov • 另一个profiling工具,可以分析程序一次执行过程中每行源代码的执行数量、branch跳转情况等。 • 可用于分析程序的关键代码和构造testsuite • 源代码在gcc的包中,不属于binutils • 使用方法 • 编译:加-fprofile-arcs -ftest-coverage选项,最好不加优化选项 • 执行:针对每个sourcefile产生sourcefile.bb、sourcefile.bbg、sourcefile.da(二进制数据) • 显示:gcov sourcefile.c 生成sourcefile.gcov
Unicore工具链 • 移植GNU工具链到unicore系统 • 两套版本 • uc1 • gcc-2.95.3 + glibc-2.1.3 + binutils-2.10.1 • uc2 • gcc-3.2.1 + glibc-2.3.1 + binutils-2.13.2
Unicore工具链 • 使用方法 • 本地: • 与在x86上的本地工具链几乎没有什么区别 • 交叉编译: • 命令前都加上前缀unicore32-linux-, 如unicore32-linux-gcc • 路径:.19:/usr/unicore/gnu-toolchain-unicore/uc2-0.3-hardfloat-glibc/bin • make CC= CXX= F77=
如何学习 • 今天的报告 • 亲自使用 • 互相学习 • info/man • info gcc、info binutils、info libc …… • ……