gcc常用命令

gdb相关

gcc加-g才能使用gdb调试
gdb -tui a.out打开调试界面
run/stop/continue控制运行和停止,step/finish进出函数,until+行号跳出循环到指定行。
break+行号打断点,break+行号 if n==100条件断点,watch 某行断点检测变量,在变量改变时停下来。
display 变量名跟踪变量,set var 变量名设置变量的值。
info break查看所有断点,delete N删除第N号断点,clear+行号清除断点。使用save breakpoint xxx.bp命令保存断点, gdb -x xxx.bp加载断点, 也可以source xxx.bp加载断点
info stack查看堆栈信息,info args查看当前参数值,bt(backtrace)查看函数调用栈。
list a,b显示a行到b行的代码

将gdb输出显示到别的终端: 先在新终端输入tty查看终端编号如20, 然后在gdb启动时输入终端编号tty /dev/pts/20. 如果需要从标准输入读, 可以在终端20中sleep 10000, 开新的终端输入给gdb的程序, 再回到20终端ctrl+c取消sleep.

print/p var 打印变量的值
print/p &var 打印变量地址
printf/p *addr 打印指针的值
printf/p /x var 用16进制显示数据 //x十六进制/d十进制/u十六进制无符号/t二进制/c字符/f浮点

gcc编译指令参数

-c

gcc -c test.c (-o test.o)

只编译不链接编译生成目标文件test.o 后面命名可省略

-o

gcc -o xxx test.c

或者gcc -o xxx test.o
编译链接生成名为xxx.out可执行文件, 不使用-o将生成a.out

-I, -L, -lxxx

gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld

上面这句表示在编译hello.c时:
-I(大写的i) /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录,寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include
-L /home/hello/lib表示将/home/hello/lib目录作为第一个寻找库文件的目录,寻找的顺序是:/home/hello/lib-->/lib-->/usr/lib-->/usr/local/lib
-lworld表示在上面的lib的路径中寻找libworld.so动态库文件(如果gcc编译选项中加入了“-static”表示寻找libworld.a静态库文件)
参考https://www.cnblogs.com/cy163/archive/2009/03/12/1409434.html
-include用来包含头文件,但一般情况下包含头文件都在源码里用#include xxxxxx实现,-include参数很少用。
不加-L则先后搜索1.elf文件的DT_RPATH段-->2.环境变量LD_LIBRARY_PATH-->3./etc/ld.so.cache文件列表-->4./lib, /usr/lib

-E

将源文件作为输入文件,将预处理文件作为输出文件,也即只进行预处理操作:

gcc -E main.c -o demo.i

对源文件 main.c 进行预处理操作,并将结果放在 demo.i 文件中。如果不使用 -o 选项,那么将生成名为 main.i 的预处理文件。

ar生成静态函数库

gcc -c lib1.c lib2.c
ar -rcs libtest.a lib1.o lib2.o

命名规则为libxxx.a, .a表示静态函数库. 库名字是test,链接时可以用-ltest查找库名
必选参数:
-r: 在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
任选参数:
-c: 创建一个库。不管库是否存在,都将创建。
-v: 该选项用来显示执行操作选项的附加信息。
-s: 创建目标文件索引,这在创建较大的库时能加快时间
nm libtest.a可以查看打包的各个.o文件

gcc -c test.c
gcc -o test test.o -L./ -ltest

当test.c调用lib1.o和lib2.o中的函数时, 会直接在./目录下查找libtest.a库, 用到什么函数就把对.a对应的.o打包的可执行文件中.
静态库优点: 1. 发布时候不用提供依赖库 2. 加载库速度快
缺点: 1. 程序体积大 2. 库改变后要重新编译程序
另外, 大部分libxxx.so只是一个链接, 还需要ln -s libxxxx-x.x.x.so libxxx.so

-shared与-fPIC生成动态函数库

gcc -shared -fPIC test.c -o libtest.so

动态函数库为.so, -shared表明产生共享库,而-fPIC则表明使用地址无关代码. -fPIC命令行标记告诉GCC产生的代码不要包含对函数和变量具体内存位置的引用,这是因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。这样编译出的test.o可以被用于建立共享链接库。
如何确认一个共享对象是PIC(位置无关)的呢?readelf -d foo.so |grep TEXTREL, 如果上边的shell有任何输出,则说明这foo.so不是PIC。TEXTREL表示代码段重定位表地址,PIC的共享对象不会包含任何代码段重定位表。

pkg-config

手工来写链接参数总是很麻烦的,还好很多库开发包提供了生成链接参数的程序,名字一般叫xxxx-config, --libs返回链接参数, --cflags返回头文件目录, 一般放在/usr/bin目录下,比如:

$ python-config --libs --cflags
-lpython2.7 -lpthread -ldl  -lutil -lm 
-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7  -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes

编译时直接将xxxx-config返回的参数作为输入即可:

gcc gtktest.c `gtk-config --libs --cflags`

除了xxx-config以外,现在新的开发包一般都用pkg-config来生成链接参数,使用方法跟xxx-config类似,但xxx-config是针对特定的开发包,但pkg-config包含很多开发包的链接参数的生成,用pkg-config --list-all命令可以列出所支持的所有开发包,pkg-config的用法就是pkg-config pagName --libs --cflags,其中pagName是包名,是pkg-config--list-all里列出名单中的一个,比如gtk1.2的名字就是gtk+,pkg-config gtk+ --libs --cflags的作用跟gtk-config --libs --cflags是一样的。比如:

gcc gtktest.c `pkg-config gtk+ --libs --cflags`

PKG_CONFIG_PATH:用来指定pkg-config用到的pc文件的路径,默认是/usr/lib/pkgconfig,pc文件是文本文件,扩展名是.pc,里面定义开发包的安装路径,Libs参数和Cflags参数等等。
CC:用来指定c编译器。
CXX:用来指定cxx编译器。
LIBS:跟上面的--libs作用差不多。
CFLAGS:跟上面的--cflags作用差不多。
CC,CXX,LIBS,CFLAGS手动编译时一般用不上,在做configure时有时用到,一般情况下不用管。
环境变量设定方法:

export PKG_CONFIG_PATH=/usr/local/bin/opencv-2.4.13.6/lib/pkgconfig

-O

这是一个程序优化参数,一般用-O2就是用来优化程序用的,比如gcc test.c -O2,优化得到的程序比没优化的要小,执行速度可能也有所提高.

交叉编译器

使得在一个linux平台开发的程序可以在另一个linux平台使用, 不过CPU架构不一样. 用法和本地gcc差不多, 但是configure参数有区别. 为了不跟本地编译器混淆,交叉编译器的名字一般都有前缀,比如sparc-xxxx-linux-gnu-gcc,sparc-xxxx-linux-gnu-g++等等.
交叉编译器必须用-L和-I参数指定编译器用sparc系统的库和头文件,不能用本地(X86)的库(头文件有时可以用本地的)。
例子:

sparc-xxxx-linux-gnu-gcc test.c -L/path/to/sparcLib -I/path/to/sparcInclude

CMake强制编译成32位程序

sudo apt-get install gcc-multilib g++-multilib
再在CMakeLists文件中添加set(CMAKE_CXX_FLAGS "-m32")

gcc文件路径

ubuntu16.04下gcc5.4默认头文件路径/usr/include/c++/5/包含/bits和/ext文件夹
mac下brew install gcc@4.9后的默认头文件路径为/usr/local/Cellar/gcc@4.9/4.9.4_1/include/c++/4.9.4/,也包含/bits和/ext

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353