GCC Reference
本文简单整理了GCC编译的命令项,可作为后续使用的参考。
编译
本文以GCC为主,默认编译*.c的c语言源代码。
源文件->可执行文件
gcc -Wall test.c -o test
gcc -Wall a.c b.c -o main
这里a.c、b.c一起编译生成一个可执行文件。
注意 -Wall
选项表示打开所有最常用的编译警告,也是gcc最推荐使用的选项。
分段编译通常是先生成中间文件(*.o),然后通过链接器生成可执行文件。GCC也提供了类似机制。
源文件->中间文件(*.o)
gcc -Wall -c test.c
gcc -Wall -c a.c b.c main.c
多个*.c文件表示同时生成对应的中间目标文件。
中间文件(*.o)->可执行文件
gcc test.o -o test
gcc a.o b.o main.o -o test
依赖项设置
外部库文件依赖
对于需要引用库的情况,可以使用-l
(小写字母L)指定依赖库,或者使用绝对路径引入。比如,:
import libm.a
gcc -Wall calc.c -lm -o calc
gcc -Wall calc.c /usr/lib/libm.a -o calc
默认情况下GCC会在/usr/local/include
、/usr/include
目录中搜索头文件;在/usr/local/lib
、/usr/lib
中搜索库。同时可以单独使用-I
、-L
分别指定包含头文件、包含库文件的搜索路径。
比如下面命令:
gcc -Wall test.c -I/header -L/lib -o test
在Shell脚本中也可以通过环境变量指定默认搜索的头文件和库文件路径,分别使用C_INCLUDE_PATH和LIBRARY_PATH参数。
对于动态链接的情况,还有一个比较重要的环境变量,LD_LIBRARY_PATH,设置默认加载动态库的目录。
预处理和宏
GCC支持使用"-DNAME"的形式在编译时定义宏。
比如下面指令,会在test.c文件中定义TEST宏
gcc -Wall -DTEST test.c -o test
宏也可以带有参数,比如下面指令,
gcc -Wall -DNUM=100 val.c -o value
gcc -Wall -DNUM val.c -o value
在不指定的值的情况下,gcc会将宏默认赋值为1。也支持宏展开
gcc -Wall -DNUM="2+2" val.c -o value
下面是val.c的代码,感兴趣的可以验证下上面语句的实际输出情况
#include <stdio.h>
int main(void)
{
printf("Value of NUM is %d", NUM);
return 0;
}
生成预处理之后的文件(*.i)
gcc -E test.c -o test.i
或者使用-save-temps
选项。
带有调试信息编译
GCC提供了“-g”调试选项在对象文件(*.o)和可执行文件中存储额外的调试信息。使用“-g”选项除了允许程序在调试器控制下运行外,还可以找到程序崩溃的环境。当程序异常退出时,操作系统会在当前目录生成“core”文件。程序员可以从core文件中查询到程序退出的位置和当时的变量值。
可以使用下面格式加载core文件。
gdb EXECUTABLE-FILE CORE-FILE
gdb backtrace显示调用堆栈
编译优化
GCC提供了"-OLEVEL",用于选择哪一种优化,LEVEL可取值0、1、2、3、s。默认GCC使用“-O0”或者“-O”(大写字母o)。通常我们在实际开发调试时使用默认的“-O0”调试,发布或者部署时使用“-O2”。
至于具体含义建议参考GCC用户手册。优化的含义是在运行速度或者可执行程序大小上优化,当然优化级别越高,与源代码差距越大,可读性越差。
GNU 发行的软件包默认都打开了调试选项“-g”和优化选项“-O2”。
c++编译
c++编译需要使用g++,例如:
g++ -Wall test.cpp -o test
其他编译指令跟gcc类似
生成静态库
GCC提供了ar生成静态库,通常静态库是一系列对象文件(.o)的集合。
可以用下面指令将两个对象文件打包成linux下的静态库文件(.a)。
gcc -Wall -c init.c uninit.c
ar cr libhello.a init.o uninit.o
查看*.a中的内容列表
ar t libhello.a
生成动态库
编译时使用“-fpic”选项,用于指定输出的目标文件是按照可重定位地址(relocatable addressing)方式生成的。pic表示position independent code。并在链接时使用“-shared”生成最终动态库。
以下指令将两个源代码生成一个*.so文件。
gcc -Wall -c -fpic first.c second.c
gcc -Wall -shared first.o second.o -o hello.so
生成文件查看及分析
查看可执行文件类型
使用file指令,可以查看可执行文件的类型。比如下面输出:
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
查看符号表
使用nm指令,比如:
nm test.o
查看动态库依赖项
使用ldd指令,可查看可执行模块的外部库依赖项
c程序中文件后缀说明
- .a 静态对象库,是目标文件的封装格式。
- .c c语言源代码
- .h 源代码的头文件
- .i 预处理之后的c语言源代码,是GCC编译中间产物
- .o 目标文件,汇编之后的模块,是GCC编译中间产物
- .s 汇编语言代码,是GCC中间产物。
- .so 共享对象库
源代码(*.c)通过预处理,生成*.i文件;经过词法分析和语法分析之后生成伪代码形式的*.s文件;然后通过汇编之后生成依赖特定平台的目标文件(*.o);最后使用链接器将多个目标文件生成一个可执行文件。
备注
本文主要参考“An Introduction to GCC”整理。算是简单的GCC编译指令汇总。
GCC Reference的更多相关文章
- Summary on deep learning framework --- PyTorch
Summary on deep learning framework --- PyTorch Updated on 2018-07-22 21:25:42 import osos.environ[ ...
- gcc参数-l传递顺序错误导致`undefined reference'的一点小结
刚才编译一个pthread的单文件程序, 使用的命令行是: gcc -o thread1 -lpthread thread1.c 结果报错: $ gcc -o thread1 -lpthread th ...
- variadic templates & pass by const reference & member operator [] in const map & gcc sucks
/// bugs code with comments #include <iostream> #include <memory> #include <unordered ...
- GCC编译uboot出现(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'错误的解决的方法
/opt/arm-2010.09/bin/../lib/gcc/arm-none-linux-gnueabi/4.5.1/armv4t/libgcc.a(_bswapsi2.o):(.ARM.exid ...
- [Linux][C][gcc] Linux GCC 编译链接 报错ex: ./libxxx.so: undefined reference to `shm_open'
本人原创文章,文章是在此代码github/note的基础上进行补充,转载请注明出处:https://github.com/dramalife/note. 以librt丶用户自定义动态库libxxx 和 ...
- ubuntu下 GCC编译程序出现 undefined reference to `std::ios_base::Init::Init()'问题
网上的解释是:“ you need to add -lstdc++, or use 'g++' rather than 'gcc' as your driver program.”,也就是说如果想要使 ...
- gcc链接程序时出现undefined reference to""错误
如:: undefined reference to ‘mq_unlink',意思是指函数mq_unlink没有定义. 可以使用如下步骤找到该函数所在的库: 1).查找哪些库包含了或使用了该函数:gr ...
- 在Linux下使用gcc编译mesa文件报undefined reference to symbol 'sin@@GLIBC_2.2.5和DSO missing from command line两个错误的解决方案
一.概述 在Linux系统下使用gcc编译用C语言写的mesa的示例程序. 环境:Ubuntu Server 18.04.1 二.问题的出现 在Ubuntu下安装好mesa所需的库文件,将目标文件从g ...
- 利用gcc编译链接时出现 ‘undefined reference to `std::ios_base::Init::Init()’ 解决
一般编译链接c++程序最好使用g++,若有如上的报错信息,需要在gcc后加上 -lstdc++ eg: gcc test.c -lstdc++ gcc和g++都是GNU的一个编译器. g++:后缀.c ...
随机推荐
- Python装饰器几个有用又好玩的例子
装饰器是一种巧妙简洁的魔术,类似于Java中的面向切面编程,我们可以再函数执行前.执行后.抛出异常时做一些工作.利用装饰器,我们可以抽象出一些共同的逻辑,简化代码.而简化代码的同时,就是在增加代码鲁棒 ...
- C语言学习笔记 (001) - 常量指针与指针常量的区别(转帖)
三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量 ...
- 【javascript】js中的函数节流和函数防抖
一.概念解释 函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段. 大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...
- Xcode 常用插件
1.Xcode 插件 从 Xcode 8 起 Apple 禁用 Xcode 插件. 1)Xcode 插件安装目录 ~/library/Application Support/Developer/Sha ...
- 【Algorithm】二分查找
今天在学习<编程之美>的时候,看到一个二分查找的题目,发现原来我真的不懂二分查找. 二分查找时候注意的事项: 在求二分查找的中间点时没有使用 midIndex = (minIndex + ...
- 一个web.Config或app.Config自定义段configSections的示例
一个web.Config或app.Config自定义段configSections的示例 越来越觉得,直接用配置文件app.Config或web.Config配置应用系统的运行参数,比自己做一个xml ...
- 日志收集-Flume-ng-mongodb-sink
本文主要介绍使用Flume传输数据到MongoDB的过程,内容涉及环境部署和注意事项. 一.环境搭建 1.flune-ng下载地址:http://www.apache.org/dyn/closer.c ...
- Linux下实现脚本监测特定进程占用内存情况
Linux系统下,我们可以利用以下命令来获取特定进程的运行情况: cat /proc/$PID/status 其中PID是具体的进程号,这个命令打印出/proc/特定进程/status文件的内容,信息 ...
- 豆瓣上9分以上的IT书籍-编程技术篇
在豆瓣上9分以上的IT书籍-编程语言篇中,收集了很多优秀的编程语言书籍,也得到了不少读者的喜欢.不过也有一些读者留言说某某书为什么没有,一种是因为某些书并不算讲某种编程语言的,一种是由于豆瓣9分以上这 ...
- logrotate日志管理工具
一.概述 logrotate是一个Linux系统默认安装了的日志文件管理工具,用来把旧文件轮转.压缩.删除,并且创建新的日志文件.我们可以根据日志文件的大小.天数等来转储,便于对日志文件管理. log ...