GCC简单使用

-v/-v/--version 查看gcc版本号

python@ubuntu:~$ gcc -v

-I 指定头文件目录,注意-I和之间没有空格

1 #include<stdio.h> //表示从系统路径下查找

2 #include"include/test.h" //表示从当前系统路径下查找include路径在的tesst.h

3 void main()

4 {

5 printf("ok");

6 }

python@ubuntu:~$ gcc -I .include/test.h 1.c -o app

-c 只编译,生产.o文件,不进行连接

-g 包含调试信息

python@ubuntu:~$ gcc 1.c -g -o app1

python@ubuntu:~$ gcc 1.c -o app2

python@ubuntu:~$ ls -l

总用量 3628

-rw-rw-r-- 1 python python 85 1月 17 13:31 1.c

-rwxrwxr-x 1 python python 8600 1月 15 09:36 app

-rwxrwxr-x 1 python python 9592 1月 17 13:32 app1

-rwxrwxr-x 1 python python 8600 1月 17 13:32 app2

//可以看出app1比app2大

python@ubuntu:~$ gdb app1

(gdb) list

1    #include<stdio.h> //表示从系统路径下查找

2    void main()

3    {

4     printf("ok");

5    }

(gdb)

//因为没有调试信息所以不能调试

python@ubuntu:~$ gdb app2

(gdb) list

没有符号表被读取。请使用 "file" 命令。

 

-On n=0-3 编译优化,n越大优化的越多

//编译器优化自动把不必要的指令优化掉,比如优化有100行,优化后70行

 

 

 

 

 

-Wall 提示更多警告信息

python@ubuntu:~$ gcc 1.c -Wall -o app3

1.c:2:6: warning: return type of 'main' is not 'int' [-Wmain]

void main()
//严格编译,不能有一点问题

-D 编译时定义宏,注意-D和之间没有空格

1.c文件测试

1 #include<stdio.h>

2

3 int main()

4 {

5 #ifdef DEBUG

6 printf("debug test\n");

7 #endif

8 printf("helloworld\n");

9 return 0;

10 }

python@ubuntu:~$ gcc 1.c -o app

python@ubuntu:~$ ./app

helloworld

python@ubuntu:~$ gcc 1.c -D DEBUG -o app

python@ubuntu:~$ ./app

debug test

helloworld

~

-E 编译生产预处理文件

python@ubuntu:~$ gcc 1.c -E -o app

python@ubuntu:~$ vim app

extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));

# 942 "/usr/include/stdio.h" 3 4

# 2 "1.c" 2

 

 

# 3 "1.c"

int main()

{

 

 

 

printf("helloworld\n");

return 0;

}

-M 生产.c文件与头文件依赖关系用于makefile,包括系统的头文件

 

-MM 生产.c文件与头文件依赖关系用于MakeFile,不包括系统库的文件

 

Binutils

一组用于编译、连接、汇编、和其他调试目的的程序,包括ar、as、nm、object等

gcc编译器

glibc,该库实现linux系统函数,例如open、read等,也实现标准c语言库,如printf

 

ar打包生产静态库

as汇编器

ld链接器

nm查看目标文件中的符号

objcopy将原目标文件中的内容复制到新的目标文件中

objdump用于生成反汇编文件,主要依赖objcopy实现,a.out编译需要-g

python@ubuntu:~$ gcc 1.c -D DEBUG -g -o app

python@ubuntu:~$ objdump -dSsx app >file

windows下obj,lib,dll,exe的关系

lib是和dll对应的。lib是静态链接库的库文件,dll是动态链接库的库文件。 
    所谓静态就是link的时候把里面需要的东西抽取出来安排到你的exe文件中,以后运行你的exe的时候不再需要lib。
    所谓动态就是exe运行的时候依赖于dll里面提供的功能,没有这个dll,你的exe无法运行。 
    
    lib,dll,exe都算是最终的目标文件,是最终产物。而c/c++属于源代码。源代码和最终目标文件中过渡的就是中间代码obj,实际上之所以需要中间代码,是你不可能一次得到目标文件。比如说一个exe需要很多的cpp文件生成。而编译器一次只能编译一个cpp文件。这样编译器编译好一个cpp以后会将其编译成obj,当所有必须要的cpp都编译成obj以后,再统一link成所需要的exe,应该说缺少任意一个obj都会导致exe的链接失败。
    
    1.obj里存的是编译后的代码跟数据,并且有名称,所以在连接时有时会出现未解决的外部符号的问题。当连成exe后便不存在名称的概念了,只有地址。lib就是一堆obj的组合。
    2.理论上可以连接obj文件来引用其他工程(可以认为一个obj文件等价于编译生成它的cpp文件,可以引用obj来替换cpp,也可以添加cpp来替换obj ),但实际中通常用lib来实现工程间相互引用。
    3.编译器会默认链接一些常用的库,其它的需要你自己指定。

linux .o,.a,.so

       .o,是目标文件,相当于windows中的.obj文件 

  .so 为共享库,是shared object,用于动态连接的,相当于windows下的dll 

  .a为静态库,是好多个.o合在一起,用于静态连接 

 

 

 

 

静态库和共享库

程序库,简单说,就是包含了数据和执行码的文件,其不能单独执行可作为其他执行程序一部分完成某些功能,可以使的程序模块化,可以加快程序的在编译,可以实现代码重用,使得程序升级,程序库可为静态库(static library)和共享库(share object)

 

静态库可以在程序运行前就已经加入到执行码中,成为执行程序的一部分;

共享库是在执行程序启动后加载到执行文件中,可以被多个执行程序共享使用;

 

静态库

在应用程序生成时,可以不在编译,节约再编译时间,但在编译器越来越快的今天,这一点似乎已不重要了,如何其他开发任意要使用你的程序,而你有不想给源码,提供静态库是一个种选择,从理论上讲,应用程序使用了静态库,要比加载动态库速度快1-5%但实际上可能被非如此,由此看来,除了使用方便外,静态库可能备份一种好的选择

 

要创建一个静态库,或要将目标代码加入到已经存在的静态库中,可以使用一下命令:

ar rcs libmylib.a file1.o

 

表示将file1.o加入到 libmulib.a库中

静态库创建成功后,需要链接到引用程序中使用,使用gcc的-l选项来指定静态库,使用-L参数来指定库文件的搜索路径。

 

 

 

共享库

共享库创建比较简单,基本有两步。首先使用-FPIC或-Fpic创建目标文件,或者PIC或

Pic表示位置无关代码,然后可以使用一下格式创建共享库了:gcc -share -Wl,-soname.your_soname -o library_name file_list library_list

[root@Zh gccTestLib]# gcc -I/root/gccTestLib/ -c -fpic h.c

[root@Zh gccTestLib]# cat h.h h.c

int add(int a,int b)

{

return a+b;

}

#include "h.h"

#include <stdio.h>

 

void main()

{

printf("%d",add(10,20));

}

//-I 指定头文件的目录

[root@Zh gccTestLib]# gcc -I/root/gccTestLib/ -c -fpic h.c//编译成.o文件

[root@Zh gccTestLib]# gcc -c -fpic *.c

[root@Zh gccTestLib]# ls

h.c h.o w.c w.o

[root@Zh gccTestLib]# ls

h.c h.h h.o

[root@Zh gccTestLib]# gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.10 h.o

-soname主版本好

Libtest.so.1.1o此版本号

[root@Zh gccTestLib]# ls

h.c h.h h.o libtest.so.1.10 //编译的库

[root@Zh gccTestLib]# ldd libtest.so.1.10 //查看库的依赖

    linux-vdso.so.1 => (0x00007ffd0adf1000)

    libc.so.6 => /lib64/libc.so.6 (0x00007ff8e2d82000)

    /lib64/ld-linux-x86-64.so.2 (0x00005558c022f000)

[root@Zh gccTestLib]# pwd //记作当前的路径,放在系统库的配置文件中,让系统加载

/root/gccTestLib

[root@Zh gccTestLib]# vim /etc/ld.so.conf

[root@Zh gccTestLib]# ldconfig

[root@Zh gccTestLib]# cat /etc/ld.so.conf

include ld.so.conf.d/*.conf

/root/gccTestLib

[root@Zh gccTestLib]# tree

.

├── h.c

├── h.h

├── h.o

├── libtest.so.1 -> libtest.so.1.10 //自动创建主版本号

└── libtest.so.1.10

 

0 directories, 5 files

 

 

python@ubuntu:~$ gcc 1.c -fpic -shared -o libtest.so.1 一条命令编译

GCC the GNU的更多相关文章

  1. 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码

    不可否认,这次的标题有点长.之所以把标题写得这么详细,主要是为了搜索引擎能够准确地把确实需要了解 GCC 生成 16 位实模式代码方法的朋友带到我的博客.先说一下背景,编写能在 x86 实模式下运行的 ...

  2. Linux 桌面玩家指南:08. 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  3. 关于QT、GCC、GNU下各个版本的下载地址

    http://download.qt.io/ http://ftp.gnu.org/gnu/gcc/ http://ftp.gnu.org/pub/gnu/

  4. GCC、GNU C、C99、ANSI C

    ANSI C ANSI C是由美国国家标准协会(ANSI)及国际标准化组织(ISO)推出的关于C语言的标准.ANSI C 标准同时规定了 C 标准库. ANSI C发展历史 C 的第一个标准是由ANS ...

  5. gcc, g++ - GNU 工程的 C 和 C++ 编译器 (egcs-1.1.2)

    总览 (SYNOPSIS) gcc [ option | filename ]... g++ [ option | filename ]... 警告 (WARNING) 本手册页 内容 摘自 GNU ...

  6. 【转】简说GNU, GCC and MinGW (Lu Hongling)

    原地址:https://my.oschina.net/u/588967/blog/73478 GNU, GCC, MinGW是开源社区常常要遇到的概念. 网上一般的解释比较繁琐, 让人如坠云雾. 本文 ...

  7. 基础概念——何为GNU与GCC

    GNU:GNU 是一个自由软件操作系统.全称是GNU‘s Not Unix. GNU 是一款类似Unix的操作系统,它所采用的的典型内核是Linux. 该组合叫作GNU/Linux操作系统: GNU网 ...

  8. 【转载】 GNU GCC 选项说明

    GCC 1 Section: GNU Tools (1) Updated: 2003/12/05 Sponsor: GCC Casino Winning Content NAME gcc,g++-GN ...

  9. 你必须知道的指针基础-1.预备篇:搭建GCC开发环境

    一.关于GCC编译器 GCC(GNU Compiler Collection)是一套功能强大.性能优越的编程语言编译器,它是GNU计划的代表作品之一.GCC是Linux平台下最常用的编译器,GCC原名 ...

随机推荐

  1. 基础selenium+Python(定位、等待、打印)

    1.第一个脚本 # coding = utf-8 from selenium import webdriver browser = webdriver.Firefox() browser.get(&q ...

  2. 028-applicationContext.xml配置文件

    版本一 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http: ...

  3. JavaScript Ajax 实现学习

    创建异步对象: function createXmlHttp(){ var xhobj=false; try{ xhobj=new ActiveXObject("Msxml2.XMLHTTP ...

  4. leetcode_173【二叉搜索树迭代器】

    实现一个二叉搜索树迭代器.你将使用二叉搜索树的根节点初始化迭代器. 调用 next() 将返回二叉搜索树中的下一个最小的数. 示例: BSTIterator iterator = new BSTIte ...

  5. Firebird Case-Insensitive Searching 大小写不敏感查找

    Firebird 默认是大小写敏感,在检索的时候. 要想不敏感检索,两种方法: 1.where upper(name) = upper(:flt_name) 2.检索时指定字符集collation,例 ...

  6. springmvc4集成swagger2

    首先在原有的springmvc工程的pom文件中增加swagger <dependency> <groupId>io.springfox</groupId> < ...

  7. golang学习之select用法

    早期的select函数是用来监控一系列的文件句柄,一旦其中一个文件句柄发生IO操作,该select调用就会被返回.golang在语言级别直接支持select,用于处理异步IO问题. select用法同 ...

  8. 如何使用 MySQL EntityFramework 组件处理 MYSQL PaaS DB

    MySQL Database on Azure 是 Azure 平台上推出的 MySQL 云数据库服务,通过全面兼容 MySQL 协议,为用户提供了一个全托管的性能稳定.可快速部署.高可用.高安全性的 ...

  9. About custom Theme and Style

    For android system, of course you can custom your own style and theme, but you can't break compatibi ...

  10. [转]Shared——React Native与原生关系理解与对比

    零.关系理解 这个是我对RN和原生关系的理解.简单解释下这个图. RN js编写完业务代码后,通过react-native bundle命令,将代码分别编译成一个index.ios.bundle和in ...