首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Linux上开发环境(gcc/g++/makefile/gdb)

2012-08-26 
Linux下开发环境(gcc/g++/makefile/gdb)?1. gcc与g++编译流程:预处理preprocessing -- 编译compilation -

Linux下开发环境(gcc/g++/makefile/gdb)

?

1. gcc与g++编译流程:

预处理preprocessing --> 编译compilation --> 汇编assembly --> 链接linking

举例:

[hadoop@sam1 testGCC]$ cat hello.c

?

#include<stdio.h>int main(){printf("in C");return 0;}
?

?

?

(0)一步到位的编译:

?

[hadoop@sam1 testGCC]$ ls

hello.c

[hadoop@sam1 testGCC]$ gcc hello.c -o hello

[hadoop@sam1 testGCC]$ ./hello

in C

?

可以使用-O选项告诉GCC对源代码进行基本优化,使程序执行更快,可以替换使用如下命令:

gcc hello.c -o hello -O0 ? ? ? ? ?//没有优化

gcc hello.c -o hello -O1 ? ? ? ? ?//缺省,主要进行跳转和延迟退栈两种优化

gcc hello.c -o hello -O2 ? ? ? ? ?//除了完成-O1 的优化之外,还进行一些额外的指令调整工作

gcc hello.c -o hello -O3 ? ? ? ? ?//除了完成-O2 的优化之外,还进行包括循环展开和其他一些与处理特性相关的优化工作

?

?

(1)预处理:源文件hello.c --> 预处理文件hello.i。只激活预处理,不生成文件,需要把它重定向到一个输出文件(预处理器的输出默认被送到标准输出,而非文件中)。

[hadoop@sam1 testGCC]$ ls

hello.c

[hadoop@sam1 testGCC]$ gcc -E hello.c -o hello.i


注:

hello.c后缀为c表示: ?

?? ? ? ? C source code which must be preprocessed.


-E ?Stop after the preprocessing stage; do not run the compiler proper.?The output is in the form of preprocessed source code, which is?sent to the standard output.

?? ? Input files which don't require preprocessing are ignored.


(2)编译:预处理文件hello.i --> 汇编文件hello.s。激活预处理,编译,把文件编译成汇编代码。

?

[hadoop@sam1 testGCC]$ ls

hello.c ?hello.i

[hadoop@sam1 testGCC]$ gcc -S hello.i -o hello.s


注:

hello.s:

Assembler code. 经过编译后产生了汇编代码

长这个样子:

.file"hello.c".section.rodata.LC0:.string"in C".text.globl main.typemain, @functionmain:pushl%ebpmovl%esp, %ebpandl$-16, %espsubl$16, %espmovl$.LC0, %eaxmovl%eax, (%esp)callprintfmovl$0, %eaxleaveret.sizemain, .-main.ident"GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)".section.note.GNU-stack,"",@progbits
??

-S ?Stop after the stage of compilation proper; do not assemble. ?The?output is in the form of an assembler code file for each non-assembler input file specified.

?? ? By default, the assembler file name for a source file is made by?replacing the suffix .c, .i, etc., with .s.


(3)汇编:汇编文件hello.s -->?.o的汇编文件。激活预处理,编译和汇编,把程序做成obj文件。

?

[hadoop@sam1 testGCC]$ ls

hello.c ?hello.i ?hello.s

[hadoop@sam1 testGCC]$ gcc -c hello.s -o hello.o


注:

-c ?Compile or assemble the source files, but do not link. ?The linking?stage simply is not done. ?The ultimate output is in the form of an?object file for each source file.

?? ? By default, the object file name for a source file is made by?replacing the suffix .c, .i, .s, etc., with .o.

?? ? Unrecognized input files, not requiring compilation or assembly,?are ignored.


(4)链接:.o的汇编文件 -->?最终的可执行文件hello。

[hadoop@sam1 testGCC]$ ls

hello.c ?hello.i ?hello.o ?hello.s

[hadoop@sam1 testGCC]$ gcc hello.o -o hello

[hadoop@sam1 testGCC]$ ./hello

in C

?

注:

以上几个参数实际上指定编译在哪个stage退出,不在乎开始指定的文件是什么形式

-E ? ? ? ? ? ? ? ? ? ? ?截止到预编译完成。

-S??? ? ? ? ? ? ? ? ? ??截止到产生汇编文件。

-c??? ? ? ? ? ? ? ? ? ? ?截止到产生目标文件,不链接。

不带参数 ? ? ? ? ?截止到最终产生链接好的可执行文件。

?

2. 一个简单工程的编译——makefile(3 个.cpp 文件,2 个.h 文件)

?

main.cpp

#include<iostream>#include "printf1.h"#include "printf2.h"int main(){printf1();printf2();}

?

?

printf1.h

void printf1();

?

?

printf1.cpp

#include <iostream>#include "printf1.h"using namespace std;void printf1(){cout<<"printf1"<<endl;}
?

?

printf2.h

void printf2();
?

?

printf2.cpp

#include <iostream>#include "printf2.h"using namespace std;void printf2(){cout<<"printf2"<<endl;}
?

?

常规编译:

[hadoop@sam1 testGCC]$ lsmain.cpp  printf1.cpp  printf1.h  printf2.cpp  printf2.h[hadoop@sam1 testGCC]$ g++ -c printf1.cpp                   ==> 截止到生成(未链接的)目标文件printf1.o[hadoop@sam1 testGCC]$ g++ -c printf2.cpp                   ==> 截止到生成(未链接的)目标文件printf2.o[hadoop@sam1 testGCC]$ g++ -c main.cpp                     ==> 截止到生成(未链接的)目标文件main.o[hadoop@sam1 testGCC]$ lsmain.cpp  printf1.cpp  printf1.o    printf2.hmain.o    printf1.h    printf2.cpp  printf2.o[hadoop@sam1 testGCC]$ g++ printf1.o printf2.o main.o -o out       ==>将3个obj文件链接到一个可执行文件上[hadoop@sam1 testGCC]$ ./outprintf1printf2
?

makefile编译:

?

[hadoop@sam1 testGCC]$ lsmain.cpp  printf1.cpp  printf1.h  printf2.cpp  printf2.h[hadoop@sam1 testGCC]$ vim makefile==>见下面makefile文件内容[hadoop@sam1 testGCC]$ makeg++ -c main.cpp#默认生成main.og++ -c printf1.cppg++ -c printf2.cppg++ main.o printf1.o printf2.o -o out[hadoop@sam1 testGCC]$ lsmain.cpp  makefile  printf1.cpp  printf1.o    printf2.hmain.o    out       printf1.h    printf2.cpp  printf2.o[hadoop@sam1 testGCC]$ ./outprintf1printf2[hadoop@sam1 testGCC]$ make cleanrm -rf *.o out[hadoop@sam1 testGCC]$ lsmain.cpp  makefile  printf1.cpp  printf1.h  printf2.cpp  printf2.h

?makefile文件:

?

out: main.o printf1.o printf2.o#生成out需要依赖的文件g++ main.o printf1.o printf2.o -o outmain.o:main.cpp printf1.h printf2.h#生成main.o需要依赖的文件g++ -c main.cpp#默认生成main.oprintf1.o:printf1.h printf1.cppg++ -c printf1.cppprintf2.o:printf2.h printf2.cppg++ -c printf2.cppclean:rm -rf *.o out
?

3. 用gdb调试

资料:?http://www.ibm.com/developerworks/cn/linux/sdk/gdb/

见本博客《(第一章 1)通用双向链表》(系统程序员-成长计划)

?

?

?

?

热点排行