GCC the GNU
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的更多相关文章
- 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码
不可否认,这次的标题有点长.之所以把标题写得这么详细,主要是为了搜索引擎能够准确地把确实需要了解 GCC 生成 16 位实模式代码方法的朋友带到我的博客.先说一下背景,编写能在 x86 实模式下运行的 ...
- Linux 桌面玩家指南:08. 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码
特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...
- 关于QT、GCC、GNU下各个版本的下载地址
http://download.qt.io/ http://ftp.gnu.org/gnu/gcc/ http://ftp.gnu.org/pub/gnu/
- GCC、GNU C、C99、ANSI C
ANSI C ANSI C是由美国国家标准协会(ANSI)及国际标准化组织(ISO)推出的关于C语言的标准.ANSI C 标准同时规定了 C 标准库. ANSI C发展历史 C 的第一个标准是由ANS ...
- gcc, g++ - GNU 工程的 C 和 C++ 编译器 (egcs-1.1.2)
总览 (SYNOPSIS) gcc [ option | filename ]... g++ [ option | filename ]... 警告 (WARNING) 本手册页 内容 摘自 GNU ...
- 【转】简说GNU, GCC and MinGW (Lu Hongling)
原地址:https://my.oschina.net/u/588967/blog/73478 GNU, GCC, MinGW是开源社区常常要遇到的概念. 网上一般的解释比较繁琐, 让人如坠云雾. 本文 ...
- 基础概念——何为GNU与GCC
GNU:GNU 是一个自由软件操作系统.全称是GNU‘s Not Unix. GNU 是一款类似Unix的操作系统,它所采用的的典型内核是Linux. 该组合叫作GNU/Linux操作系统: GNU网 ...
- 【转载】 GNU GCC 选项说明
GCC 1 Section: GNU Tools (1) Updated: 2003/12/05 Sponsor: GCC Casino Winning Content NAME gcc,g++-GN ...
- 你必须知道的指针基础-1.预备篇:搭建GCC开发环境
一.关于GCC编译器 GCC(GNU Compiler Collection)是一套功能强大.性能优越的编程语言编译器,它是GNU计划的代表作品之一.GCC是Linux平台下最常用的编译器,GCC原名 ...
随机推荐
- hadoop集群搭建过程中遇到的问题
在安装配置Hadoop集群的过程中遇到了很多问题,有些是配置导致的,有些是linux系统本身的问题造成的,现在总结如下. 1. hdfs namenode -format出现错误:hdfs namen ...
- Mac下使用wireshark解决Interface为空的办法
Terminal中运行chown <user-name> /dev/bpf*命令 <user-name>处替换为当前mac用户名
- win10中xshell的ssh链接virtualBox中的centos7
win10下virtualbox中centos7.3与主机通过xshell的ssh建立连接的方法 2017-02-19 01:29 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近 ...
- [Visual studio code 常见问题解决] ——中文乱码、
中文乱码问题解决 描述:刚开始安装VScode要打开含中文的文件,都会出现乱码,这时只要点击右下方的“UTF-8”改成“GB2312”即可.但每次都改是很麻烦的,所以要使得VScode默认支持GB23 ...
- 深入理解JavaScript系列(结局篇)
介绍 最近几个月忙得实在是不可开交,终于把<深入理解JavaScript系列>的最后两篇“补全”了,所谓的全是不准确的,因为很多内容都没有写呢,比如高性能.Ajax安全.DOM详解.Jav ...
- 关于webApi使用session
1.关于webApi使用session 在Global.asax中注册session添加以下代码 public override void Init() { //开启session this.Post ...
- TortoiseGit记住用户名&密码
配置并安装好git之后鼠标右键: 在全局配置文件末尾添加一行: [credential] helper = store *主意保存时以utf-8格式保存,否则中文可能会乱码,这样下次只需输入一次用户名 ...
- [javaEE] jsp的指令
jsp的指令:jsp的指令(directive)是为jsp引擎而设计的,他们并不直接产生任何可见输出,而是告诉引擎如何处理jsp 页面中的其他部分 页面头部的page指令 <%@page imp ...
- java类与对象基础--抽象类和接口
在java的类体系中,有两个比较特殊的抽象体--抽象类和接口.抽象体并不可以拥有具体的对象(而且接口甚至不是类),但是它们却是在java设计领域非常重要的两个概念,很多优秀的设计模式都是基于这两个概念 ...
- Spring学习笔记:Spring整合Mybatis学习PPT(三:整合思路)
三.Spring-Mybatis的整合思路