先决条件
gcc 这是c语言的编译器
从前,我写了一个Linux多线程到程序Main.c,使用gcc -g Main.c -lpthread -o Main编译,就出现来未安装gcc的提示,我按照提示输入来几个y,然后就把gcc装好了。但是,其实,在Red Hat Enterprise Linux 6上,默认已经安装好gcc,可以编译C语言程序了。
gcc-c++ 扩展为c++编译器
This package adds C++ support to the GNU C compiler. It includes support for most of the current C++ specification, including templates and exception handling. It does not include the standard C++ library.
libstdc++-v3 The GNU Standard C++ Library v3
libstdc++-v3 is developed and released as part of GCC, separate snapshots are no longer made available. The libstdc++-v3 sources are included with the GCC sources and can be downloaded from the GCC FTP area or from any of the GCC mirror sites.
一、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 .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC0, %eax movl %eax, (%esp) call printf movl $0, %eax leave ret .size main, .-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 截止到产生目标文件,不链接。
不带参数 截止到最终产生链接好的可执行文件。
另外,gcc -g 这个参数让编译器在目标文件中加上了调试信息,具体表现为ELF格式目标文件中多出了很多debug段,通过readelf -S ***.o查看,多出了诸如如下的这些调试段:
[27] .debug_aranges PROGBITS 00000000 0006e4 000020 00 0 0 1
[28] .debug_pubnames PROGBITS 00000000 000704 00004f 00 0 0 1
[29] .debug_info PROGBITS 00000000 000753 0000cb 00 0 0 1
[30] .debug_abbrev PROGBITS 00000000 00081e 00008d 00 0 0 1
[31] .debug_line PROGBITS 00000000 0008ab 000046 00 0 0 1
[32] .debug_frame PROGBITS 00000000 0008f4 000054 00 0 0 4
[33] .debug_str PROGBITS 00000000 000948 000095 01 MS 0 0 1
二、一个简单工程的编译——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]$ ls main.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]$ ls main.cpp printf1.cpp printf1.o printf2.h main.o printf1.h printf2.cpp printf2.o [hadoop@sam1 testGCC]$ g++ printf1.o printf2.o main.o -o out ==>将3个obj文件链接到一个可执行文件上 [hadoop@sam1 testGCC]$ ./out printf1 printf2
makefile编译:
[hadoop@sam1 testGCC]$ ls main.cpp printf1.cpp printf1.h printf2.cpp printf2.h [hadoop@sam1 testGCC]$ vim makefile ==>见下面makefile文件内容 [hadoop@sam1 testGCC]$ make g++ -c main.cpp #默认生成main.o g++ -c printf1.cpp g++ -c printf2.cpp g++ main.o printf1.o printf2.o -o out [hadoop@sam1 testGCC]$ ls main.cpp makefile printf1.cpp printf1.o printf2.h main.o out printf1.h printf2.cpp printf2.o [hadoop@sam1 testGCC]$ ./out printf1 printf2 [hadoop@sam1 testGCC]$ make clean rm -rf *.o out [hadoop@sam1 testGCC]$ ls main.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 out main.o: main.cpp printf1.h printf2.h #生成main.o需要依赖的文件 g++ -c main.cpp #默认生成main.o printf1.o: printf1.h printf1.cpp g++ -c printf1.cpp printf2.o: printf2.h printf2.cpp g++ -c printf2.cpp clean: rm -rf *.o out
三、用gdb调试
资料:使用 GDB 调试 Linux 软件,David SeagerCICS/390 开发部,IBM Hursley: http://www.ibm.com/developerworks/cn/linux/sdk/gdb/
资料:LINUX GDB调试实例: http://blog.csdn.net/wangjiannuaa/article/details/6584750
另见本博客《(第一章 1)通用双向链表》(系统程序员-成长计划)
下面一个例子说明如何用gdb查看 “缓冲区溢出程序”的运行时堆栈情形——
#include<stdio.h> voidwhy_here(void){ printf("whyuhere?!\n"); _exit(0); } intmain(intargc,char*argv[]){ intbuff[1]; buff[2]=(int)why_here; return0; }
#gcc -g buf.c -o buf
启动gdb调试buf
在程序开始处设置断点(Sam:这里实际上只设置了一个断点,因为定义变量不会在指令序列中出现)
程序跑起来(直到遇到断点 )
查看main函数栈信息
如果遇到函数:
单步跳入是step
单步跳过是next
非常好的文档:
http://www.seas.upenn.edu/cets/answers/gcc.html
http://baike.baidu.com/link?url=uU1zNRtDxA6rGdGQWqsjlM_0q8M_0iGbQD43Z9DbPr9e3dVFE4vSWcebSuwIWpis
相关推荐
在编程世界中,GDB、GCC、G++、AUTOMAKE和MAKEFILE是构建和调试C/C++程序的重要工具。这个“打包GDB&GCC&G++&AUTOMAKE&MAKEFILE教程”提供了全面的学习资源,帮助开发者一站式掌握这些核心技术。 1. **GDB**(GNU ...
1.GCC 中文手册 2.gdb手册(debuging_with_gdb)(中文) 3.GDB用户手册(英文)4.GNU+make中文手册 5.Vim用户手册中文版7.2 6.跟我一起写 Makefile 本着开源分享的精神,从网络搜索而来,仅供参考,版权归原作者所有。...
Make是Linux下用于自动化构建项目的工具,基于Makefile来决定哪些文件需要重新编译。`make.pdf`手册可能涉及: 1. Makefile的结构和规则,包括目标、依赖项和命令 2. 变量和函数的使用,如 `$@` 和 `$ 3. 目标规则的...
Linux系统下采用VSCode+CMake+GCC+GDB进行开发实例需要了解Linux系统的基本概念、基本命令、文件编辑、开发环境搭建、GCC编译器、CMake工具、VSCode集成开发环境和GDB调试器。通过学习这些知识点,可以快速掌握Linux...
在内网环境中,Linux系统上的开发工作经常需要安装GCC(GNU Compiler Collection)和G++编译器,以便能够编译C语言和C++语言的程序。GCC是开源的,提供了对多种编程语言的支持,而G++是GCC的一部分,专门用于C++的...
总结,`makefile`、`GCC`和`GDB`是Linux下C++开发的三大基石,它们各自承担着构建、编译和调试的重要任务。掌握这三个工具的使用,能够极大地提升开发效率,让C++开发变得更轻松、更高效。对于任何想要在Linux环境下...
总的来说,"Windows下的make 3.81"是关于在Windows环境中使用GNU Make 3.81版本进行C/C++程序的构建流程,结合GCC/G++编译器和GDB调试器,以及使用像gVim、SublimeText这样的编辑工具提升开发效率。通过编写和执行...
GDB是Linux下常用的调试工具,用于帮助开发者检查和调试程序。它提供了设置断点、单步执行、查看内存状态、追踪变量值等功能。例如,用`gdb program`启动GDB并加载程序,然后用`break`命令设定断点,`run`命令启动...
Linux程序设计:vi_gcc_gdb_makefele 目标: (1)构建Linux编程环境 (2)掌握vi编辑器编写C/C++程序 (3)掌握使用gcc/g++编译C/C++程序 (4)掌握make工具编写Makefile文件 (5)掌握gdb调试工具
在Linux环境下进行软件开发,GCC、GDB和Makefile是三个至关重要的工具。这份压缩包包含的资源将帮助初学者全面了解和掌握这些工具的使用。 1. GCC(GNU Compiler Collection):GCC 是一个开源的编译器套件,它支持...
在Linux环境下进行C/C++开发,`makefile`和`gdb`是两个不可或缺的工具。`makefile`用于自动化编译过程,提高效率;`gdb`则用于程序调试,帮助开发者查找并修复错误。这里我们将深入探讨这两个工具的使用。 首先,`...
GDB(GNU Debugger)是Linux下强大的调试工具,允许程序员在程序运行时查看其内部状态,包括: - 运行程序并控制其运行条件。 - 设置断点,让程序在特定位置暂停。 - 查看程序执行时的内存和变量状态。 - 修改程序以...
在Linux环境下,GCC和G++是开发者最常使用的工具,用于将源代码转换成可执行程序。本文将深入探讨GCC/G++的常用命令及其应用。 1. **编译基本命令:**`gcc [选项] [源文件] -o [目标文件]` - `gcc`或`g++`是启动...
Linux系统编程实验二:gcc、gdb的使用以及Makefile文件的编写 本实验的目的是让学生熟悉使用gcc编译器、gdb...本实验旨在让学生熟悉使用gcc编译器、gdb调试器和Makefile文件的编写,掌握 Linux系统下的程序开发技术。
①Linux基础学习:文件类命令、压缩命令、进程命令、服务器搭建、用户管理、vim学习、gcc/g++编译、linux静态库/动态库、gdb学习、makefile基础学习、C语言文件操作类函数、C语言目录操作函数等; ②linux系统编程...
在Linux环境中进行程序开发,掌握gcc,gdb和makefile的使用是至关重要的。这些工具是Linux开发的基础,能够帮助开发者高效地编写、编译、调试和管理项目。 **一、VIM编辑器** VIM(Vi Improved)是一款强大的文本...
gcc/g++是Linux下广泛使用的编译器,用于将源代码转换成可执行程序。gcc主要处理C语言的源文件,而g++则用于C++。对于`.c`格式的C文件,可以直接使用gcc进行编译;对于`.cc`、`.cpp`格式的C++文件,应使用g++。 ###...
autoconf automake实例gcc编译java方法.txt,gcc的组件和软件工具 .txt,gcc库.txt,gdb自己总结.txt,linux 下gcc 编程.ppt,linux下JAVA环境设置.pdf,Vi指令大全.htm,跟我一起写 Makefile.pdf
在Linux下,使用GCC编译C语言源程序非常简单。以一个简单的`hello.c`程序为例: ```c int main(int argc, char **argv) { printf("Hello Linux\n"); } ``` 编译这个程序,只需在终端运行: ``` gcc -o ...