gcc的几个妙用

GCC 编译时优化某一个或几个函数或者不优化某一个或几个函数 __attribute((optimize(“STRING”)))的例子,fun1函数使用O0优化级别,fun2函数使用O2优化级别。 // 首先用__attribute__声明函数 int fun1(int a, int b) __attribute__((optimize("O0"))); // 然后再定义函数,声明和定义必须分开,否则编译错误 int fun1(int a, int b) { printf("fun1 is (optimize(\"O0\")"); } int f... 阅读详情
gcc的学习在C接触到linux以后就开始不断的学习,也知道了一些基本的用法,但是关于gcc的使用还是有很多值得我们加深的地方。gcc只是一个编译工具而已。也就相当于我们在windows环境下的visual c++等一样,区别是visual c++是基于IDE的,而gcc是这些IDE的基础。学习linux程序设计必然会学习gcc。
 
gcc实质是完成程序的编译和链接,程序的编译是指从一种文件类型转换到另一种文件类型的过程。一个C语言程序转换为可执行程序的基本步骤如下:
1、编写程序(vi,emacs等软件)
2、程序预编译(cpp)
3、编译成汇编程序(cc)
4、汇编程序(as)
5、链接程序(ld)
 
其中的这些过程都已经被gcc包含,我们在实际的编译过程中采用了gcc main.c -o main.exe即可实现一个程序的编译和链接。并不需要一步一步的实现,但是我们在分析的过程中又必须注意一个C语言文件的处理过程以及相应的处理程序。
 
关于gcc的基本含义用法就不再详细的说明了,我觉得最简单的使用方法是通过软件的help学习软件。
[gong@Gong-Computer test]$ gcc --help
Usage: gcc [options] file...
Options:
  -pass-exit-codes         Exit with highest error code from a phase
  --help                   Display this information
  --target-help            Display target specific command line options
  --help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]
                           Display specific types of command line options
  (Use '-v --help' to display command line options of sub-processes)
  --version                Display compiler version information
  -dumpspecs               Display all of the built in spec strings
  -dumpversion             Display the version of the compiler
  -dumpmachine             Display the compiler's target processor
  -print-search-dirs       Display the directories in the compiler's search path
  -print-libgcc-file-name  Display the name of the compiler's companion library
  -print-file-name=<lib>   Display the full path to library <lib>
  -print-prog-name=<prog>  Display the full path to compiler component <prog>
  -print-multi-directory   Display the root directory for versions of libgcc
  -print-multi-lib         Display the mapping between command line options and
                           multiple library search directories
  -print-multi-os-directory Display the relative path to OS libraries
  -print-sysroot           Display the target libraries directory
  -print-sysroot-headers-suffix Display the sysroot suffix used to find headers
  -Wa,<options>            Pass comma-separated <options> on to the assembler
  -Wp,<options>            Pass comma-separated <options> on to the preprocessor
  -Wl,<options>            Pass comma-separated <options> on to the linker
  -Xassembler <arg>        Pass <arg> on to the assembler
  -Xpreprocessor <arg>     Pass <arg> on to the preprocessor
  -Xlinker <arg>           Pass <arg> on to the linker
  -combine                 Pass multiple source files to compiler at once
  -save-temps              Do not delete intermediate files
  -save-temps=<arg>        Do not delete intermediate files
  -no-canonical-prefixes   Do not canonicalize paths when building relative
                           prefixes to other gcc components
  -pipe                    Use pipes rather than intermediate files
  -time                    Time the execution of each subprocess
  -specs=<file>            Override built-in specs with the contents of <file>
  -std=<standard>          Assume that the input sources are for <standard>
  --sysroot=<directory>    Use <directory> as the root directory for headers
                           and libraries
  -B <directory>           Add <directory> to the compiler's search paths
  -b <machine>             Run gcc for target <machine>, if installed
  -V <version>             Run gcc version number <version>, if installed
  -v                       Display the programs invoked by the compiler
  -###                     Like -v but options quoted and commands not executed
  -E                       Preprocess only; do not compile, assemble or link
  -S                       Compile only; do not assemble or link
  -c                       Compile and assemble, but do not link
  -o <file>                Place the output into <file>
  -x <language>            Specify the language of the following input files
                           Permissible languages include: c c++ assembler none
                           'none' means revert to the default behavior of
                           guessing the language based on the file's extension
Options starting with -g, -f, -m, -O, -W, or --param are automatically
 passed on to the various sub-processes invoked by gcc.  In order to pass
 other options on to these processes the -W<letter> options must be used.
For bug reporting instructions, please see:
<http://bugzilla.redhat.com/bugzilla>.
 
从上面的结果可以知道基本的用法。
但是还是有几个需要注意的地方,这也是我们学习gcc时不经常使用,但又非常有用的几个用法。
1、采用gcc实现预编译,预编译可以实现代码的检查,特别是宏定义的检查,通过预编译检查实际的代码是否出错,这是非常有用的检查方式。
由于预编译以后宏定义被扩展了,这时对源码的分析就能找出代码宏定义等是否存在错误,特别时一些不容易发现的错误。
基本的实现形式为:gcc -E file.c > file.pre.c

[gong@Gong-Computer Example]$ vi main.c


采用重定向的方式改变输出流,便于检查错误所在。
[gong@Gong-Computer Example]$ gcc -E main.c > main.pre.c
[gong@Gong-Computer Example]$ vi main.pre.c


从上面的结果可以发现我们的宏已经实现了扩展。通过分析宏的扩展可以分析代码是否正确。
比如我将宏定义max(x,y)改写为max (x,y)就会出现下面的结果。如下图所示。


从856行的结果我们可以知道,上面的代码并不是我们需要的情况,这说明我们的代码存在问题,从而实现了宏定义的检测。这是非常有用的一种检测方式。
 
2、产生镜像文件
基本的实现方法是:注意Wl逗号后面跟着需要传递的参数,逗号后面不能存在空格,否则出现错误。
gcc -Wl,-Map=file.map file.c -o target
关于选项-Wl的使用可以参考help,这是我的一个截图


从上面说明可以知道-Wl用于传递参数给链接器。当然也有传递给汇编器和预编译的选项。
通过上面的选项可以得到一个镜像文件,通过打开镜像文件来程序的结构。
[gong@Gong-Computer Example]$ gcc -Wl,-Map=main.map main.c -o main.exe
[gong@Gong-Computer Example]$ vi main.map



上面只是其中的一部分,还有很多的内容。其中这些内容指出了程序的基本分布情况。
 
3、汇编程序
汇编语言是不可避免要学习的设计语言,但是很多时候并不需要完全手动的编写汇编语言,我们可以采用gcc实现一段程序的汇编形式,只需要选择正确的选项即可。
gcc -S file.c
实现如下:
[gong@Gong-Computer Example]$ gcc -S main.c
[gong@Gong-Computer Example]$ vi main.s

从上面的代码就知道了基本的汇编形式,当然也可以自己设计,但是该选项简化了汇编语言的设计。

4、在gcc中函数库,链接库的调用,这是比较难以掌握和容易出错的地方。
在静态编译的情况下:
gcc file.c -o file -Llibpath -llibname 
 
gcc中-L主要是指明函数库的查找目录,-L后紧跟着目录而不是文件。-l后面紧跟着需要连接的库名,需要主要的是静态库通常是以libfile.a命名,这时-l后的库名只能是file,而不是libfile.a。这是需要注意的。一般情况下总是将-l放在最后。但是需要注意的是各个库之间的依赖关系。依赖关系没有搞清楚也会导致编译出现错误。
下面的代码如下:
foo.c


 #include<stdio.h>

 extern void bar();

 void foo()
 {
 printf("This is foo ().\n");

 bar ();
}


bar.c
 #include<stdio.h>

 void bar()
 {
        printf( " This is bar (). \n");
 }

 main.c
extern void foo();

 int main()
 {
        foo();

       return  0;
 }
~                      
简要的介绍一些静态库的创建方式。
首先需要注意的时静态编译是指将一些库函数编译到程序中,这样会增加程序的大小。动态库则是在运行过程中添加到程序中,这样可以减小程序的大小。两种方式都有各自的优势。
静态库的创建:
gcc -c foo.c -o foo.o
gcc -c bar.c -o bar.o
创建的基本过程就是采用归档函数实现。
ar csr libfoo.a foo.o
ar csr libbar.a bar.o

从上面的程序我们可以知道foo程序依赖bar程序,而main程序则依赖foo程序,所以这样就形成了一定的关系,一般来说只有将依赖的库函数写在最右边才能保证其他的库函数依赖该库函数。
[gong@Gong-Computer test]$ gcc -o main  main.c -L. -lbar -lfoo
./libfoo.a(foo.o): In function `foo':
foo.c:(.text+0x13): undefined reference to `bar'
collect2: ld returned 1 exit status
 
[gong@Gong-Computer test]$ gcc -o main  main.c -L. -lfoo -lbar
以上的两个编译过程只是存在一个差异就是库的摆放顺序存在差别,第一种情况下由于foo依赖bar,而bar库不能被foo调用,因此出错。而第二种则满足foo依赖bar,main依赖foo的关系。其中的-L.表示库函数的搜索目录为当前目录。也可以换成其他的目录。
 
因此在gcc中添加库时,需要注意库名和库的顺序,最好采用一定的依赖关系图分析实现。具体的就要我们在设计程序时自己的考虑各个库函数之间的关系。
 
至于动态库的创建可以采用gcc实现。其中的-shared就是表明了该库是动态库,-fPCI是指支持PCI,file.o是指需要加载到库中的二进制文件。库名就是libname.so
gcc -shared -fPCI -o libname.so file.o

动态库的使用可以将创建好的动态库放在/usr/lib下,然后在函数中即可实现调用。
 
gcc的其他一些用法:
查找系统文件路径:gcc -v main.c
获得程序的依赖关系:gcc -M main.c ,其中包括了所有的依赖关系,在写makefile过程中写依赖关系通常不需要系统头文件,这时可以采用gcc -MM main.c去掉系统头文件的依赖关系。

[gong@Gong-Computer test]$ gcc -M main.c
main.o: main.c /usr/include/stdio.h /usr/include/features.h \
 /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
 /usr/include/gnu/stubs.h /usr/include/gnu/stubs-32.h \
 /usr/lib/gcc/i686-redhat-linux/4.5.1/include/stddef.h \
 /usr/include/bits/types.h /usr/include/bits/typesizes.h \
 /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/i686-redhat-linux/4.5.1/include/stdarg.h \
 /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
[gong@Gong-Computer test]$ gcc -MM main.c
main.o: main.c
[gong@Gong-Computer test]$
从上面的两个结果就可以知道两个选项的差别,这种差别在编写Makefile中的依赖关系时非常的有用。特别是第二种形式是比较重要的方式。
关于gcc的使用还是要多实践才有效果,才能准确的运用。

Linux | GCC 编译器+Makefile >>Makefile功能强大,更多内容添加交流群获取文档。 阅读详情

相关推荐

GCC,G++介绍

GCC工作流程## GCC常用参数 示例 gxy@gxy:~/Linux/lession2$ gcc test.c -E -o test.i gxy@gxy:~/Linux/lession2$ ls test.c test.i gxy@gxy:~/Linux/lession2$ gcc test.c -E -o test.i gxy@gxy:~/Linux/lession2$ ls test.c test.i gxy@gxy:~/Linux/lession2$ gcc test.i -S -o t

qq_24898229的博客 5450

Linux系统下的gcc编译

linux系统下gcc编译一、关于可执行程序被组装的步骤二、用gcc生成静态库和动态库文件 一、关于可执行程序被组装的步骤 通过分享该博主了解可执行程序的组装步骤如下: 1.编辑:也就是编写C/C++程序。 2.预处理:相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同。 3.编译:将预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后,产生相应的汇编代码文件。 4.链接:通过链接

weixin_45830968的博客 841

EMC工程师职业发展:从测试整改到系统设计的进阶之路

电磁兼容(EMC)是确保电子设备在复杂电磁环境中可靠工作的关键技术,其核心在于控制电磁干扰(EMI)并提升抗扰度。其基本原理涉及电磁场理论、噪声耦合路径与滤波屏蔽技术。对于电子产品而言,EMC设计直接关系到能否通过CE、FCC等强制性认证,是产品上市和市场竞争力的关键。在工程实践中,EMC工程师需要从电路设计、PCB布局、元器件选型等源头入手,将EMC要求融入产品开发全流程,实现从后期“整改”到前期“设计预防”的价值跃迁。本文聚焦EMC工程师的核心能力体系构建与职业发展路径,深入探讨了如何从掌握标准测试、电

weixin_30819085的博客 388

linux动态库编译与使用

一. 编译动态库: gcc -shared -fPCI -o libmyhello.so c1.o c2.o -L -L -l -l 二. 解释: 1)c1.o c2.o 是源文件编译出来的目标文件2)DIR1 DIR2是动态库libmyhello.so需要依赖的库文件所在路径 3)hello1 hello2是动态库libmyhello.so需要依赖的库文件(其文件全名应该是libhello1.a

蓝月的职场人生 501

AI风控系统中的实时决策架构:架构师的关键设计

当用户点击「确认支付」时,一场毫秒级的“欺诈攻防战”正在后台悄然打响:系统需要在100ms内完成用户行为特征提取→欺诈模型推理→规则引擎校验→最终决策返回。这就是AI风控实时决策架构的核心——用技术对抗“实时化的欺诈手段”。本文将以「餐厅智能点餐系统」为类比,拆解实时风控架构的每一层逻辑:从“如何快速拿到用户的实时行为特征”(像服务员实时收集顾客的忌口),到“如何让模型和规则协同决策”(像厨师长结合菜谱和经验判断菜能不能做),再到“如何保证系统扛住大促的高并发”(像餐厅加桌子应对客流高峰)。我们会用。

2502_91592937的博客 1472

ArcGIS供地图斑图形及属性入库操作(附练习数据)

已知数据: 供地图斑位置图。 供地图斑表格 成果要求:将供地图斑导入mdb数据库并将供地图斑表格的属性进行挂接。 接下来我们开始操作: 1、 打开arcmap,在目录内连接的文件夹内找到供地图斑位置图。图片 2、 将annotation和polygon添加到arcmap图片 3、 右击文件所在文件夹新建mdb数据库图片 4、 右击数据库新建要素数据集。(要素数据集非常重要,稍后所有操作都在数据集内进行)选择图斑投影方式及代号。图片 5、 右击要素数据集—导入(将图层内的数据导入数据库)图片 6、 数据导入.

qq_43173805的博客 8132

编译器背后的故事(gcc和as)

目录一、用gcc生成 .a静态库和 .so动态库1、编辑生成例子程序 hello.h、hello.c 和 main.c2、将 hello.c 编译成.o 文件3、由.o 文件创建静态库4、在程序中使用静态库5、由.o 文件创建动态库6、在程序中使用动态库 我们通常把一些公用函数制作成函数库,供其它程序使用。 函数库分为静态库和动态库两种。 静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要

qq_45907958的博客 3047

LPDDR5 学习笔记01:功能概述

LPDDR5/LPDDR5X SDRAM设备采用8/16DQ通道架构,支持2Gb-32Gb容量。通过CK命令时钟和更快的WCK数据时钟协同工作,7个CA引脚传输控制信息,支持2:1或4:1的WCK:CK比例。设备提供BG/8B/16B三种存储模式选择,分别支持不同数据速率(最高8.533Gbps)和突发长度。采用0.5V VDDQ电源电压,实现高速双倍数据速率传输,并通过差分WCK时钟完成数据采样。读写采用突发访问机制,需先激活命令再执行读写操作。新型LPDDR5X仅支持BG和16B模式,优化了高速性能。

一只豌豆象的博客 2202

gcc动态库静态库文件生成使用及as汇编编译器使用

提示:本文为学习课程作业,主要记录学习过程,存在很多不足 文章目录一.可执行程序的装载1.用gcc生成静态库和动态库2.静态库.a与.so库文件的生成与使用二.改编第一次作业程序生成静态库和动态库文件并进行比较1.生成静态库文件2.生成动态库文件并比较大小2.读入数据总结 一.可执行程序的装载 预处理:gcc -E -o hello.cpp hello.c -m32,这一步主要是进行一些宏的替换,得到的仍然是一个文本文件 编译:gcc -x cpp-ouput -S -o hello.s hello.c

aiwr_的博客 1754

华为OD机试 新系统真题 【最小代价完成论文评审】

华为OD机试 新系统真题【最小代价完成论文评审】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【最小代价完成论文评审】多语言题解。

qq_45776114的博客 442

如何生成linux动态库

1.gcc -o hello.o hello.c 2.gcc -shared -fPCI -o libtest.so hello.o "-shared": 属性为可共享文件 “-fPCI”:-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code), 则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载...

weixin_33711647的博客 175

R语言 百度坐标转换至WGS84坐标

本文利用R语言封装了百度坐标转换至WGS84坐标的函数,亲测有效,提供了便捷的百度坐标转换方法。

qingchen98的博客 2135

gcc和Linux哪个重要,gcc的几个妙用

gcc的学习在C接触到linux以后就开始不断的学习,也知道了一些基本的用法,但是关于gcc的使用还是有很多值得我们加深的地方。gcc只是一个编译工具而已。也就相当于我们在windows环境下的visual c++等一样,区别是visual c++是基于IDE的,而gcc是这些IDE的基础。学习linux程序设计必然会学习gcc。gcc实质是完成程序的编译和链接,程序的编译是指从一种文件类型转换到...

weixin_31155097的博客 378

python实现DoIP基本通信(收发报文)

python实现DoIP基本通信(收发报文)

天赐好车的博客 896

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

转:gcc的几个妙用

gcc的学习在C接触到linux以后就开始不断的学习,也知道了一些基本的用法,但是关于gcc的使用还是有很多值得我们加深的地方。gcc只是一个编译工具而已。也就相当于我们在windows环境下的visual c++等一样,区别是visual c++是基于IDE的,而gcc是这些IDE的基础。学习linux程序设计必然会学习gcc。 gcc实质是完成程序的编译和链接,程序的编译是指...

akkcy26820的专栏 113

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

MinGW,cygw,GCC,arm-linux-gnueabihf-gcc 这几个有啥区别和联系

问题解决:Windows 默认没有类 Unix 系统的环境(比如 POSIX 标准),而 MinGW 使得开发者可以在 Windows 上使用 GNU 工具链,同时不需要引入 Cygwin 的模拟层,生成的程序不需要额外的环境支持。问题解决:Windows 和 Unix/Linux 系统的差异,Cygwin 通过在 Windows 上提供类似 Unix 的 API,允许原本只能在类 Unix 系统上运行的程序,也能在 Windows 上编译和运行。编译后生成的程序可以直接在 Windows 上运行。

jjjxxxhhh123的博客 1777

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

GCC几个选项学习

Table of Contents 1 -dumpmachine 2 -xc 3 -dM 4 -print-file-name=include 5 -isystem DIR 6 -nostdinc/-nostdinc++ 7 -Wp/-Wa/-Wl 8 -EL/-EB 9 -DMACRO/-UMACRO 10 -G num 11 -msym32/-mnosym32 12 -...

嘿,逮到一只大码农 2149

【GCC、gcc、g++】中

本文介绍了GCC编译器套件中的gcc和g++工具。

优快云_RTKLIB的博客 908

CentOS7 升级gcc版本到gcc9

CentOS7 升级gcc版本到gcc9 CentOS7自带的GCC版本是4.8.5,如下所示: # cat /etc/redhat-release CentOS Linux release <strong>7.6.1810</strong> (Core) #which gcc #gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux

xunye的博客 1万+

GCC学习总结

GCC(GNU Compiler Collection,GNU编译器套件)是GNU项目的一部分,是一个广泛使用的开源编译器套件,支持多种编程语言和处理器架构。GCC最初是为了编译C语言而开发的,但现在已经成为一个多语言编译器,支持多种编程语言,包括C、C++、Objective-C、Fortran、Ada、Go、D等多种语言。GCC包含以下主要组件:前端(Frontend):负责处理源代码,将源代码转换为中间表示(Intermediate Representation,IR)。不同的编程语言有不同的前端。

studyingdda的博客 4357

gcc的基本用法

目录 一、GCC 二、GCC、gcc、g++三者关系 三、gcc编译过程 四、文件类型 五、gcc编译选项 一、GCC GCC(GNU Compiler Collection)即GNU编译器套件,属于一种编程语言编译器,其原名为GCC(GNU C Compiler)即GNU c语言编译器,虽然缩写一样但是功能上区别很大。GCC的初衷是为GNU操作系统专门编写的一款编译器,原本的GNU...

hurryddd 4659

GCC是什么? gcc与g++的区别 具体编译细节

GCC是什么?gcc与g++的区别?

偶尔想看云飞的博客 1万+

WINDOWS下如何安装GCC

WINDOWS下如何安装GCC? 2013/09/14 JULUREN 第一章 在视窗操作系统下的GCC 第一节 GCC家族概览 GCC 是一个原本用于 Unix-like 系统下编程的编译器。不过,现在 GCC 也有了许多 Win32 下的移植版本。所以,也许对于许多 Windows 开发者来说, GCC 还是一个比较陌生的东西。所以,我希望通过这章的叙述

yunxian_19的专栏 2万+

Windows中使用GCC介绍

Windows中使用GCC介绍。注意,GCC与gcc,g++是不同的东西: GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。 gcc是GCC中的GUN C Compiler(C 编译器)。 g++是GCC中的GUN C++ Compiler(C++编译器)。.....................

cnds123的专栏 1万+
上一篇: cocos2dx 学习
下一篇: cocos2dx 没有“install-templates-msvc.bat” 创建工程
tspangle
博客等级 码龄19年 81粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值