看流星社区

 找回密码
 注册账号
查看: 1778|回复: 0

GCC基础

[复制链接]

该用户从未签到

发表于 2017-6-1 12:52:14 | 显示全部楼层 |阅读模式
GCC基础:
1.hello world
编译:
0.不使用Makefile
    1.编译一个文件:

<code class=" hljs avrasm">gcc –o hello main.c
    ./hello
    or:
    g++ –o hello  main.cpp
    ./hello
</code>[/code]

1.使用Makefile
    1.编译一个文件:

<code class=" hljs avrasm">hello:main.o
        gcc -o hello main.o
    main.o:main.c
        gcc -c main.c -o main.o
    clean:
        rm -f *.o hello</code>[/code]

<code>**//注意,2,4,6行都是以一个tab字符开始,否则编译的时候会有问题**

2.编译多个文件
</code>[/code]

<code class=" hljs avrasm">hello:main.o func.o
        g++ -g -o hello  main.o func.o
    func.o:func.cpp
        g++ -g -c func.cpp -o func.o
    main.o:main.cpp
        g++ -g -c main.cpp -o main.o
    clean:
        rm -f main *.o</code>[/code]

GCC参数:
gcc*.c;g++*.cpp  
-o outfile 输出到指定的文件
-E 仅作预处理(code.i),不进行编译、汇编和链接。
-S 仅编译到汇编语言(code.s),不进行汇编和链接。
-c 编译、汇编到目标代码(code.o),不进行链接。
-shared 生成共享目标文件。通常用在建立共享库时。
-static 禁止使用共享连接。
-llibrary 进行链接时搜索名为library的库 小写l
-Idir 把dir 加入到搜索头文件的路径列表中。 I i 大写i
-Ldir 把dir 加入到搜索库文件的路径列表中。 大写L  
例子: <nobr>gcc?I/home/foo?L/home/foo?ltesttest.c?otest?Dname预定义一个名为name的宏,值为1。例子:</nobr> gcc -DTEST_CONFIG test.c -o test
-Dname =definition 预定义名为name ,值为definition 的宏。

//——————————————————————
-ggdb -ggdblevel  
为调试器 gdb 生成调试信息。level 可以为1,2,3,默认值为2。
-g -glevel  
生成操作系统本地格式的调试信息。-g 和 -ggdb 并不太相同, -g 会生成 gdb 之外的信息。level 取值同上。
-Wall 会打开一些很有用的警告选项,建议编译时加此选项。
-w 禁止显示所有警告信息。
Optimization
-O0 禁止编译器进行优化。默认为此项。
-O -O1 尝试优化编译时间和可执行文件大小。
-O2 更多的优化,会尝试几乎全部的优化功能,但不会进行“空间换时间”的优化方法。
-O3 在 -O2 的基础上再打开一些优化选项:-finline-functions, -funswitch-loops 和 -fgcse-after-reload 。
-Os 对生成文件大小进行优化。它会打开 -O2 开的全部选项,除了会那些增加文件大小的。

Makefile可以使用scons来代替
Scons :跨平台的gnu make替代工具,其集成功能类似autoconf/automake 。scons是一个更简便,更可靠,更高效的编译软件。
Scons help doc :http://blog.sina.com.cn/s/blog_5eb8ebcb0100sjlb.html
http://www.ibm.com/developerworks/cn/linux/l-cn-scons/

2.linux 动/静态库.so开发与调用



<code class=" hljs vala">/*firstlib.h*/
void Print();


/*firstlib.c*/
#include &lt;stdio.h&gt;
#include “firstlib.h"
void Print()
{
    printf("hello first lib\n");
}


/*main.c*/
#include &lt;stdio.h&gt;
#include "firstlib.h"
int main()
{
    Print();
}
</code>[/code]

静态库:
编译



<code class=" hljs avrasm">gcc –c firstlib.c
ar –rsv libfirstlib.a firstlib.o</code>[/code]

引用



<code class=" hljs avrasm">gcc –o main –L. –lfirtlib main.c</code>[/code]

静态库(.a)Makefile例子:



<code class=" hljs avrasm">libfirstlib.a:firstlib.c
    gcc -c firstlib.c
    ar -rsv libfirstlib.a firstlib.o
clean:
    rm -f *.o *.a</code>[/code]

将firstlib.a文件拷到目标程序目录下
调用静态库程序的Makefile例子:



<code class=" hljs avrasm">testlib:main.o
    gcc -o testlib -L. -lfirstlib main.c
clean:
    rm -f *.o testlib</code>[/code]

testlib就是我们调用的程序啦
需要注意的是在调用程序的Makefile中-l后面跟的不加lib,尾部也不加.a

动态库:



<code class=" hljs lasso">gcc -fpic -shared firstlib.c -o libfirstlib.so
//或者:
gcc -fPIC -c firstlib.c//多个文件可以继续加
gcc -fPIC -c xx.c
........................
//-fPIC:postion independent code
gcc -shared libfirstlib.so firstlib.o xx.o xxx.0</code>[/code]

引用:



<code class=" hljs lasso">gcc -o firstlibtest -L. -lfirstlib main.c</code>[/code]

动态库Makefile例子:



<code class=" hljs avrasm">libfirstlib.so:firstlib.c
    gcc -shared -fPIC -o libfirstlib.so firstlib.c
clean:
    rm -f *.so *.o
</code>[/code]

<em>重要:将动态库拷贝到/lib或/usr/lib或/usr/lib64/中去</em>
如:sudo cp libfirstlib.so  /usr/lib64
否则编译不过
调用动态库Makefile例子:
例子:



<code class=" hljs avrasm">main:main.c
    gcc -o main -I. -L. -lfirstlib  main.c
clean:
    rm -f main *.o
</code>[/code]

linux中查看程序使用了哪些动态库:
    ldd xxxx//xxxx是程序
查看xxx.so的符号表
    objdump -tT xxx.so  
列出动态库的符号清单(理解为导出表)
    nm -D xxx.so

3.辅助编写工具
    1.Sublime_Text
    一般的算法编写可以用默认的编译系统,否则直接使用make编译系统,需在目录下写一个makefile
    2.Eclipse
    没使用过 不过朋友说挺好用的
    3.Code::Blocks
    没使用过
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 16:21

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表