Linux编译工具:gcc入门
1. 什么是gcc
gcc的全称是GNU Compiler Collection,它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器(GNU C Compiler),现在除了c语言,还支持C++、java、Pascal等语言。gcc支持多种硬件平台。
2. gcc的特点
- gcc是一个可移植的编译器,支持多种硬件平台。例如ARM、X86等等。
- gcc不仅是个本地编译器,它还能跨平台交叉编译。所谓的本地编译器,是指编译出来的程序只能够在本地环境进行运行。而gcc编译出来的程序能够在其他平台进行运行。例如嵌入式程序可在x86上编译,然后在arm上运行。
- gcc有多种语言前端,用于解析不同的语言。
- gcc是按模块化设计的,可以加入新语言和新CPU架构的支持。
- gcc是自由软件。任何人都可以使用或更改这个软件。
3. gcc编译程序的过程
gcc编译程序主要经过四个过程:
- 预处理(Pre-Processing)
- 编译 (Compiling)
- 汇编 (Assembling)
- 链接 (Linking)

预处理实际上是将头文件、宏进行展开。编译阶段,gcc调用不同语言的编译器,例如c语言调用编译器ccl。gcc实际上是个工具链,在编译程序的过程中调用不同的工具。汇编阶段,gcc调用汇编器进行汇编。链接过程会将程序所需要的目标文件进行链接成可执行文件。汇编器生成的是可重定位的目标文件,学过操作系统,我们知道,在源程序中地址是从0开始的,这是一个相对地址,而程序真正在内存中运行时的地址肯定不是从0开始的,而且在编写源代码的时候也不能知道程序的绝对地址,所以重定位能够将源代码的代码、变量等定位为内存具体地址。下面以一张图来表示这个过程,注意过程中文件的后缀变化,编译选项和这些后缀有关。
这是GCC编译的四个步骤。
4. gcc常用选项
来看一下gcc常用选项
| 选项名 | 作用 |
|---|---|
| -o | 产生目标(.i、.s、.o、可执行文件等) |
| -E | 只运行C预编译器 |
| -S | 告诉编译器产生汇编程序文件后停止编译,产生的汇编语言文件拓展名为.s |
| -c | 通知gcc取消连接步骤,即编译源码,并在最后生成目标文件 |
| -Wall | 使gcc对源文件的代码有问题的地方发出警告 |
| -Idir | 将dir目录加入搜索头文件的目录路径 |
| -Ldir | 将dir目录加入搜索库的目录路径 |
| -llib | 连接lib库 |
| -g | 在目标文件中嵌入调试信息,以便gdb之类的调试程序调试 |
现在我们有源文件hello.c,下面是一些gcc的使用示例:
gcc -E hello.c -o hello.i 对hello.c文件进行预处理,生成了hello.i 文件
gcc -S hello.i -o hello.s 对预处理文件进行编译,生成了汇编文件
gcc -c hello.s -o hello.o 对汇编文件进行编译,生成了目标文件
gcc hello.o -o hello 对目标文件进行链接,生成可执行文件
gcc hello.c -o hello 直接编译链接成可执行目标文件
gcc -c hello.c 或 gcc -c hello.c -o hello.o 编译生成可重定位目标文件
使用gcc时可以加上-Wall选项。下面这个例子如果不加上-Wall选项,编译器不会报出任何错误或警告,但是程序的结果却不是预期的:
//bad.c
#include<stdio.h>
int main()
{
printf("the number is %f ",5); //程序输出了the number is 0.000000,结果错误
return 0;
}
使用-Wall选项:
gcc -Wall bad.c -o bad
gcc将输出警告信息:
warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
printf("the number is %f\n",5);
5. gcc编译多个文件
假设现在有三个文件:hello.c hello.h main.c ,三个文件的内容如下:
// hello.c
#include<stdio.h>
#include"hello.h"
void printHello()
{
printf("hello world!\n");
}
//main.c
#include<stdio.h>
#include"hello.h"
int main()
{
printHello();
return 0;
}
//hello.h
//仅包含函数声明
#ifndef _HELLO_
#define _HELLO_
void printHello();
#endif
编译这三个文件,可以一次编译:
gcc hello.c main.c -o main 生成可执行文件main
也可以独立编译:
gcc -Wall -c main.c -o main.o
gcc -Wall -c hello.c -o hello.o
gcc -Wall main.o hello.o -o main
独立编译的好处是,当其中某个模块发送改变时,只需要编译该模块就行,不必重新编译所有文件,这样可以节省编译时间。
6. 使用外部库
在使用C语言和其他语言进行程序设计的时候,我们需要头文件来提供对常数的定义和对系统及库函数调用的声明。库文件是一些预先编译好的函数集合,那些函数都是按照可重用原则编写的。它们通常由一组互相关联的可重用原则编写的,它们通常由一组互相关联的用来完成某项常见工作的函数构成。使用库的优点在于:
- 模块化的开发
- 可重用性
- 可维护性
库又可以分为静态库与动态库:
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。静态库比较占用磁盘空间,而且程序不可以共享静态库。运行时也是比较占内存的,因为每个程序都包含了一份静态库。
动态库(.so或.sa):程序在运行的时候才去链接共享库的代码,多个程序共享使用库的代码,这样就减少了程序的体积。
一般头文件或库文件的位置在:
- /usr/include及其子目录底下的include文件夹
- /usr/local/include及其子目录底下的include文件夹
- /usr/lib
- /usr/local/lib
- /lib
7. 生成静态库
为了生成.a文件,我们需要先生成.o文件。下面这行命令将我们的hello.o打包成静态库libhello.a:
ar rcs libhello.a hello.o
ar是gun归档工具,rcs表示replace and create,如果libhello之前存在,将创建新的libhello.a并将其替换。
然后就可以这样来使用静态库libhello.a
gcc -Wall main.c libhello.a -o main
还有另外一种使用方式:
gcc -Wall -L. main.c -o main -lhello 【lhello 是 libhello的缩写】
其中 -L.表示库文件的位置在当前目录下,由于libhello.a是我们自己生成的,并存放在当前录下下,所以需要加上-L.选项。默认库文件是在系统的目录下进行搜索。同样的,-I.选项用于头文件的搜索。
8. 生成共享库
生成一个共享库,名称的规则是libxxx.so。将刚才hello.o生成libhello.so的命令为:
gcc -shared -fPIC hello.o -o libhello.so
生成了共享库之后,可以这样来使用共享库:
gcc -Wall main.o -o main -L. -lhello
该命令与使用静态库的命令相同,但是在共享库与静态库共存的情况下,优先使用共享库。
共享库有时候并不不在当前的目录下,为了让gcc能够找得到共享库,有下面几种方法:
- 拷贝.so文件到系统共享库路径下,一般指/usr/lib
- 在~/.bash_profile文件中,配置LD_LIBRARY_PATH变量
- 配置/etc/ld.so.conf,配置完成后调用ldconfig更新ld.so.cache
其中,shared选项表示生成共享库格式。fPIC表示产生位置无关码(position independent code),位置无关码表示它的运行、加载与内存位置无关,可以在任何内存地址进行加载。
9. 库的搜索路径
库的搜索路径遵循几个搜索原则:从左到右搜索-I -l指定的目录,如果在这些目录中找不到,那么gcc会从由环境 变量指定的目录进行查找。头文件的环境变量是C_INCLUDE_PATH,库的环境变量是LIBRARY_PATH.如果还是找不到,那么会从系统指定指定的目录进行搜索。
文章链接:http://www.cnblogs.com/QG-whz/p/5456720.html
Linux编译工具:gcc入门的更多相关文章
- Linux 编译工具 gcc/g++、Make/Makefile、CMake/CMakeLists.txt、qmake
前言 编译器的主要工作流程: 源码(Source Code)>> 预处理器(Preprocessor)>> 编译器(Compiler)>> 汇编程序(Assembl ...
- 解决安装编译工具gcc后无法连接mysql
在安装编译工具gcc后: yum -y install make gcc g++ gcc-c++ libtool autoconf automake imake mysql-devel libxml2 ...
- suse linux编译安装GCC报错
gcc编译安装过程 1.先安装三个库 gmp mprc mpc 这三个库的源码要到官网去下载 1)安装gmp:首先建立源码同级目录 gmp-build,输入命令,第一次编译不通过,发现缺少一个叫m4的 ...
- Linux编译安装GCC
1. 下载gcc安装包 网址:http://ftp.gnu.org/gnu/gcc/ ,下载对应的安装包,我选择gcc-5.5.0.tar.gz 2. 下载依赖库 一个是mpc,一个是gmp,一个是m ...
- 二、linux编译环境的搭建
1.linux编译工具安装 vim安装:apt-get install vim 注意:使用C语言源代码语法加亮功能,需要配置文件/etc/vim/vimrc,加入代码syntaxon.文件后缀必须为. ...
- Linux开发工具之gcc
一.gcc入门(上) 1.gcc相关概念 gcc(GNU C Compiler)编译器,最初支持C语言,现已支持C.C++.Java.Pascal.Ada.COBOL语言等:支持多种硬件平台: ...
- 用C写一个web服务器(三) Linux下用GCC进行项目编译
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
- gcc编译工具生成动态库和静态库之一----介绍
1.库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. ...
- 版本控制工具Git工具快速入门-Linux篇
版本控制工具Git工具快速入门-Linux篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.版本管理系统的介绍 1>.版本管理系统的特点 1.1>.自动生成备份: ...
随机推荐
- 高效 Java Web 开发框架 JessMA v3.4.1
JessMA 是功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hibernate.MyBatis 与 J ...
- SQLSERVER常见系统函数之字符串函数(一)
好久没有写博客了,这段时间准备写一下字符串函数 QQ群: 499092562:欢迎交流 字符串函数: 1.LEN(需要获取长度的字符串) 返回:字符串的长度 示例: SELECT LEN('小搬运工很 ...
- asp.net mvc 之旅 —— 第五站 从源码中分析asp.net mvc 中的TempData
在mvc的controller中,我们知道有很多的临时变量存放数据,比如说viewData,viewBag,还有一个比较特殊的tempData,关于前两个或许大家都明白, 基本上是一个东西,就是各自的 ...
- java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。
JNA 调用 dll 库时,保错: ///////////////// 通过 JNA 引入 DLL 库 //////////// /** * ID_FprCap.dll 负责指纹的采集, 指纹仪的初始 ...
- 基于面向对象的图片轮播(js原生代码)
无论你想走多远,你都需要不断地走下去.前端最精华的便是原生的js,这也是我们前端工程师的技术分层的重要指标,也提现这你的代码能力,开发的水平.废话不多说,进入今天的主要分享————基于面向对象思想的图 ...
- 最新win7系统64位和32位系统Ghost装机稳定版下载
系统来自转载:系统妈 一.主要更新:========================== * 更新了系统补丁和Office2007 SP2所有补丁 通过微软漏洞扫描* 更新QQ至7.1 官方正式版* ...
- monkeyrunner之控件ID不存在或重复
我们在用monkeyrunner进行Android自动化时,通过获取坐标点或控件ID进行一系列操作.由于使用坐标点时,屏幕分辨率一旦更改,则代码中用到坐标的地方都要修改,这样导致代码的复用率较低.因此 ...
- 用ORM的思想操作XML文档,一个对象就搞定不要太简单。滚蛋吧!XmlDocument、XmlNode、Xml***……
大家有没有这样的感受,一涉及XML文档操作就得百度一遍.是不是非!常!烦!.各种类型,各种方法,更别提为了找到一个节点多费劲.本来想写个XML操作的工具方法,写了两行一想既然XML文档是有规律的,如果 ...
- 【原】移动web滑屏框架分享
本月26号参加webrebuild深圳站,会上听了彪叔的对初心的讲解,“工匠精神”这个词又一次被提出,也再次引起了我对它的思考.专注一个项目并把它做得好,很好,更好...现实工作中,忙忙碌碌,抱着完成 ...
- 【repost】JavaScript 事件模型 事件处理机制
什么是事件? 事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水.当我们与浏览器中 Web 页面进行某些类型的交互时,事件就发生了.事件可能是用户在某些内容上的点击 ...