UC 之GNU编译工具GCC

mac2024-01-28  39

GCC简介

GCC(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器。它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。GCC原本作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,GCC同样适用于微软的Windows。 GCC是自由软件过程发展中的著名例子,由自由软件基金会以GPL协议发布。 GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理 C语言。GCC 很快地扩展,变得可处理 C++。后来又扩展能够支持更多编程语言,如Fortran、Pascal、Objective-C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)

GCC 编译器在编译一个C语言程序时,过程可以细分为四个阶段: gcc -E : 将C语言源程序预处理,生成.i文件。 gcc -S :预处理后的.i文件编译成为汇编语言,生成.s文件。 gcc -c :将汇编语言文件经过汇编,生成目标文件.o文件。 gcc -o 文件名 :将各个模块的.o文件链接起来生成一个可执行程序文件。-o的作用是指定生成文件的文件名

程序员可以对编译过程进行控制,同时GCC提供了强大的代码优化功能。

gcc -v 查看gcc版本

c程序中的文件后缀名

扩展名说明.h头文件.cC源文件i预处理后的c源文件.s汇编程序文件.o目标文件.a静态链接库.so动态链接库

gcc 其他常用参数:

参数功能-o指定输出文件:: gcc a.c -oa.exe(默认为a.out)-Wall生成尽可能多的警告信息-Werror要求编译器将警告当做错误处理-x指定编译代码类型:-x none根据后缀自动识别-g生成调试信息-O优化:等级分为O0(不优化)、O1(默认)、O2、O3-w不生成任何警告信息。-static禁止使用共享连接。

预处理指令介绍

预编译指示符号说明#define定义宏或者宏函数#if、#ifdef、#ifndef、#elif、#else条件编译#endif结束条件编译#include将指定的文件插入当前位置#include_next与include一样,但从当前目录之后的目录查找#line指定行号#pragma提供额外信息的标准方法,可用来指定平台#undef删除宏#waring创建一个警告#error产生错误,挂起预处理程序##连接操作符号,用于宏内连接两个字符串

示例:

错误和警告

#define VERSION 3 #if (VERSION < 2) #error "版本过低" #else #waring "版本高" #endif

头文件 系统头文件使用:#Include <…> 在系统指定的目录以及I参数目录查找 用户头文件使用:#include “…” 先在当前路径查找后再去系统指定的目录及I参数指定的目录查找。

#pragma #pragma 有一个等价的宏_Pragma #pragma GCC poison int 等于 _Pragma("GCC poison int") #pargma GCC dependency "文件名a ":指定文件a比当前文件新的时候会产生提示警告。 #pargma GCC posion 标识符: 标识符将被定义为毒药,禁止继续使用,否则产生错误。 pragma pack(1) : 可以指定结构的对齐和补齐的字节数。

预定义宏介绍

宏说明__BASE_FILE源代码的完整路径__DATE__日期__FILE__源代码文件名__FUNCTION__当前函数名,同(__func__)__INCLUDE_LEVEL__包含的层数,基本为0__LINE__行数__TIME__时间

宏__cplusplus主要解决C/C++混合编程问题,一般用法如下:

#ifdef __cplusplus extern "C" { #endif … //被extern “C”修饰的变量和函数按照C语言方式编译和链接。 #ifdef __cplusplus } #endif

修改环境变量 Linux终端中执行export PATH=$PATH:. : 当前窗口有效。 cd ~ 后.bashrc文件末尾加上export PATH=$PATH:. 执行 . .bashrc。 编译环境变量 C_INCLUDE_PATH : 查找头文件的目录。c。 CPLUS_INCLUDE_PATH : 查找头文件的目录。C++。 CPATH : 查找头文件,相当于-I选项。与上面重合。 LIBRARY_PATH : 编译时,查找库文件(静态库和共享库),-l选项。 LD_LIBRARY_PATH :运行时定位共享库 程序员自定义头文件的几种查找方法:

用" "中放入路径的方式:"./test/xx.h"把目录配置到环境变量CPATH中。用gcc -I 头文件目录 进行编译连接。

静态库的创建和使用

编译静态库

gcc -c -static test.c : -static为可选项,阻止gcc使用共享库。不使用共享库减少运行时间开销,但文件会变大。ar -r libtest.a test.o ar指令 语法:ar [选项] 归档文件名 目标文件列表 项说明-d从归档文件删除制定目标文件列表-q将指定目标文件快速附加到归档文件末尾。-r将指定目标文件插入文档,如存在则更新。-t显示目标文件列表-x把归档文件展开为目标文件

使用静态库

gcc main.c libtest.agcc main.c -ltest (libtest.a必须在LIBRARY_PATH的指定目录中)gcc main.c -ltest -L(库目录)

共享库的创建和使用

编译共享库 gcc -c -fpic test.c gcc -shard test.o -o libtest.so -fpic不写也可以gcc -fpic -shard test.c -o libtest.s 使用共享库与静态库方式一样 gcc main.c libtest.sogcc main.c -ltest (libtest.so必须在LIBRARY_PATH的指定目录中)gcc main.c -ltest -L(库目录)

编译时依赖LIBRARY_PATH,但共享库运行时依赖LD_LIBRARY_PATH。 ldd命令可以查看应用程序所使用的共享库 系统提供了一套API可以直接打开共享库: #include <dlfcn.h> void * dlopen(const char *filename, int flag);:打开库文件。flag:RTLD_LAZY(符号查找时候才加载),RTLD_NOW(立刻加载)。 void *dlsym(void *handle, const char *symbol); : 从打开的库文件中得到函数 int dlclose(void *handle); : 关闭 char *dlerror(void); : 判断是否出错

最新回复(0)