美文网首页
gcc常用命令

gcc常用命令

作者: D_Major | 来源:发表于2019-07-08 17:50 被阅读0次

    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

    相关文章

      网友评论

          本文标题:gcc常用命令

          本文链接:https://www.haomeiwen.com/subject/tvpahctx.html