0:GNU,linux与Unix
Unix 系统被发明之后,大家用的很爽。但是后来开始收费和商业闭源了。一个叫 RMS 的大叔觉得很不爽,于是发起 GNU 计划,模仿 Unix 的界面和使用方式,从头做一个开源的版本。然后他自己做了编辑器 Emacs 和编译器 GCC。GNU 是一个计划或者叫运动。在这个旗帜下成立了 FSF,起草了 GPL 等。接下来大家纷纷在 GNU 计划下做了很多的工作和项目,基本实现了当初的计划。包括核心的 gcc 和 glibc。但是 GNU 系统缺少操作系统内核。原定的内核叫 HURD,一直完不成。同时 BSD(一种 UNIX 发行版)陷入版权纠纷,x86 平台开发暂停。然后一个叫 Linus 的同学为了在 PC 上运行 Unix,在 Minix 的启发下,开发了 Linux。注意,Linux 只是一个系统内核,系统启动之后使用的仍然是 gcc 和 bash 等软件。Linus 在发布 Linux 的时候选择了 GPL,因此符合 GNU 的宗旨。最后,大家突然发现,这玩意不正好是 GNU 计划缺的么。于是合在一起打包发布叫 GNU / Linux。然后大家念着念着省掉了前面部分,变成了 Linux 系统。实际上 Debian,RedHat 等 Linux 发行版中内核只占了很小一部分容量。
一:
1.GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C等语言。
gcc是GCC中的GUN C Compiler(C 编译器)
g++是GCC中的GUN C++ Compiler(C++编译器)
更准确的说法是:gcc调用了C compiler,而g++调用了C++ compiler
1.对于 .c和.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)
2. 对于 .c和.cpp文件,g++则统一当做cpp文件编译
附加:
MinGW是Minimalist GNU for Windows的缩写,提供了一套简单方便的Windows下的基于GCC 程序开发环境。MinGW 收集了一系列免费的Windows 使用的头文件和库文件;同时整合了GNU ( http://www.gnu.org/ )的工具集,特别是GNU 程序开发工具,如经典gcc, g++, make等。MinGW是完全免费的自由软件,它在Windows平台上模拟了Linux下GCC的开发环境,为C++的跨平台开发提供了良好基础支持,为了在Windows下工作的程序员熟悉Linux下的C++工程组织提供了条件。
二:
gcc 与 g++ 分别是 gnu 的 c & c++ 编译器 gcc/g++ 在执行编译工作的时候,总共需要4步:
1、(-E预处理,但不编译)预处理.i:将所有的“#define”删除,并且展开所有的宏定义,删除所有的注释,处理“#include”预编译指令,添加行号和文件名标识,生成 .i 的文件[预处理器cpp]
2、(-S编译,但不汇编)编译.s:编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析以及优化后生成相应的汇编代码文件,编译过程是整个程序构建的核心部分, 生成文件 .s [编译器egcs]
3、(-c汇编,但不链接)汇编.o:由汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]注:.o文件是ELF格式的文件,Linux下有哪些ELF类型的文件?.o文件、可执行文件、核心转储文件(core dump)、.so文件(动态链链接库)
4、链接:将各个模块之间相互引用的部分正确的衔接起来,连接目标代码, 生成可执行程序 [链接器ld],分为静态链接和动态链接。
最基本的链接叫做静态链接,就是将每个模块的源代码文件编译成目标文件(Linux:.o Windows:.obj),然后将目标文件和库一起链接形成最后的可执行文件。库其实就是一组目标文件的包,就是一些最常用的代码编译成目标文件后打包存放。最常见的库就是运行时库,它是支持程序运行的基本函数的集合
-o: 指定生成的输出文件名称
-g: 令 gcc 生成调试信息,该选项可以利用操作系统的“原生格式(native format)”生成调试信息。GDB 可以直接利用这个信息,其它调试器也可以使用这个调试信息
-shared参数表示生成动态链接库。
-fPIC参数表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的;所以动态载入时是通过代码拷贝的方式来满足不同的调用,而不能达到真正的代码段共享的目的。
gcc -c Test.s -o Test.o
visual studio 2010 编译程序时,首先是cpp经过预处理,处理掉#define,#include等等。#include部分,将头文件部分替换到cpp中。之后进行优化过程,到.s。之后进入汇编,变成.obj。之后是将.obj链接在一起变为exe。
三:
##windows平台:
1.dll : 动态链接库,作为共享函数库的可执行文件.
2.obj : 目标文件,相当于源代码对应的二进制文件,未经过重定义.
3.lib :静态库,可理解为多个 obj 的集合,本质与 .obj 相同.
##linux平台:
1.so:(share object)动态链接库,和windows 的 dll 类似,使用时才载入。以下命令生成so文件:gcc cfun.c -fPIC -shared -o lib_cfun.so
2.o : 就是object,目标文件,相当于源代码对应的二进制文件,是目标代码,类似 windows 下 obj;一个.c或.cpp文件对应一个.o文件
3.a : 就是archive,静态库文件,与 .o 类似,是多个 .o 的集合,类似 windows 下 lib,多个.a可以链接生成一个exe的可执行文件。命令如下:ar -crv libstaticmath.a StaticMath.o,生成静态库libstaticmath.a。
###########重要!!#############
库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。所谓静态、动态是指链接。
之所以成为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。
静态库特点总结:
1.静态库对函数库的链接是放在编译时期完成的。
2.程序在运行时与函数库再无瓜葛,移植方便。
3.浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
为什么需要动态库?现在程序尤其是游戏的更新都只是替换了对应目录的动态链接库,从而极大的节省了流量,不必一次更新就要下载一个完整安装包:)
1.空间浪费是静态库的一个问题。
2.另一个问题是静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。
动态库特点总结:
1.动态库把对一些库函数的链接载入推迟到程序运行的时期。
2.可以实现进程之间的资源共享。(因此动态库也称为共享库)
3.将一些程序升级变得简单。
4.甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。
从底层实现上,动态库的效率可能会比静态库稍差一点点,注意,这里用了“可能”二字,具体差不差,还得看写程序的人。之所以可能会差,主要原因在于,程序总无法直接调用动态库中的函数符号,而只能通过调用操作系统的runtime enviroment接口来动态载入某个函数符号,同时获得该函数符号在内存中的地址,将其保存为函数指针进行调用,这就在函数调用时增加了一次间接寻址的过程
四:
Linux与Windows不同,不是根据扩展名来区分文件类型的。
事实上,Linux下的文件不需要扩展名。一切皆文件,包含设备文件、目录文件、普通文件等。要知道是否是可执行文件,一般是通过 ls -l 命令看文件属性中是否包含可执行权限 (x)。
Linux不使用文件名扩展来识别文件的类型。相反,Linux根据文件的头内容来识别其类型。为了提高文件可读性您仍可以使用文件名扩展,但这对 Linux 系统来说没有任何作用。
linux可执行文件为ELF格式。
目标文件是源代码经过编译但未进行链接的那些中间文件,在linux中的.o文件,它跟可执行文件的内容与结构很相似,所以一般与可执行格式采用一种方式存储,在linux下,我们可以将他们统称ELF文件。
五:
ELF文件标准里面把系统中采用ELF格式的文件归为四类:
可重定位文件(Relocatable File):linux的.o;windows的.obj;
可执行文件(Executable File):比如/bin/bash文件;window的.exe;
共享目标文件(Shared Object File):linux的.so,如/lib/glibc-2.5.so;windows的DDL
核心转储文件(Core Dump File):linux下的core dump
六:
minGW生成的exe程序,通过在cmd中输入gcc test.exe来运行,直接双击会一闪而过。
python运行.py程序C:\Users\dzdas\Desktop>python tes.py。前提是把python.exe加入环境变量
python使用其他语言:
(1)编写C语言代码:没有main
(2)将c语言编译为动态库:gcc cfun.c -fPIC -shared -o lib_cfun.so
(3)编写python代码:
#加载动态库
lib = cdll.LoadLibrary("./lib_cfun.so")
#创建一个子线程,让其执行c语言编写的函数
t = Thread(target=lib.CFun)
t.start()
(4)执行python代码: