流星悟语 发表于 2017-6-1 12:52:14

GCC基础

GCC基础:
1.hello world
编译:
0.不使用Makefile
    1.编译一个文件:

<code class=" hljs avrasm">gcc –o hello main.c
    ./hello
    or:
    g++ –o hellomain.cpp
    ./hello
</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>**//注意,2,4,6行都是以一个tab字符开始,否则编译的时候会有问题**

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

<code class=" hljs avrasm">hello:main.o func.o
      g++ -g -o hellomain.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>

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 class=" hljs avrasm">gcc –c firstlib.c
ar –rsv libfirstlib.a firstlib.o</code>

引用



<code class=" hljs avrasm">gcc –o main –L. –lfirtlib main.c</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>

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



<code class=" hljs avrasm">testlib:main.o
    gcc -o testlib -L. -lfirstlib main.c
clean:
    rm -f *.o testlib</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 class=" hljs lasso">gcc -o firstlibtest -L. -lfirstlib main.c</code>

动态库Makefile例子:



<code class=" hljs avrasm">libfirstlib.so:firstlib.c
    gcc -shared -fPIC -o libfirstlib.so firstlib.c
clean:
    rm -f *.so *.o
</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. -lfirstlibmain.c
clean:
    rm -f main *.o
</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
    没使用过
页: [1]
查看完整版本: GCC基础