在《Python中扩展C语言加快执行速度的实现方法》中提到了在linux下经过GCC命令编译生成动态连接库的方法,同时咱们也能够经过《Linux平台上部署Mongoose服务器的方法介绍》中介绍的利用make工具解析makefile文件的编译规则来更高效率的处理多个源文件,其实万变不离其宗,makefile文件中仍然是以GCC命令调用编译器来编译源文件的,但对于开发者而言更加的简单有效。linux
相信大多数开发者有在使用Eclipse软件编辑代码,但Eclipse并不只仅是一款编辑器,它是跨平台的自由集成开发环境,经过各类插件能够构建各类语言的开发环境。本文介绍在linux平台上使用Eclipse工具编译C工程生成静态和动态连接库方法。程序员
C/C++的编译器不少,在Linux平台上多数是以GCC为主。GCC全称为GNU Compiler Collection,目前能够编译的语言包括:C,C++,Objective-C,Fortran,Java和Ada。GCC是GNU公社的一个项目,是一个用于编程开发的自由编译器。最初,GCC只是一个C语言编译器,它是GNU C Compiler 的英文缩写。随着众多自由开发者的加入和GCC自身的发展,现在的GCC已是一个包含众多语言的编译器了。
(1)gcc命令语法格式为选项和参数的结合:gcc [options] file1 file2...编程
经常使用选项包括: -E:只进行预处理,不编译 -S:只编译,不汇编 -c:只编译、汇编,不连接 -g:包含调试信息 -I dir:在头文件的搜索路径列表中添加dir目录 -L dir:在库文件的搜索路径列表中添加dir目录 -v:打印编译器内部编译各过程的命令行信息和编译器的版本号 -o:输出成指定文件名 -O0:关闭全部优化选项 -O1:第一级别优化,使用此选项可以使可执行文件更小、运行更快,并不会增长太多编译时间,能够简写为-O -O2:第二级别优化,采用了几乎全部的优化技术,使用此选项会延长编译时间 -O3:第三级别优化,在-O2的基础上增长了产生inline函数、使用寄存器等优化技术 -Os:此选项相似于-O2,做用是优化所占用的空间,但不会进行性能优化,经常使用于生成最终版本 -w:忽略全部警告 -Werror:不区分警告和错误,遇到任何警告都中止编译 -Wall:开启大部分警告提示注:gcc –o 和 gcc –c的区别。gcc –o是将.c源文件默认编译链接生成一个可执行的二进制代码(未加-c选项),输出文件名称由-o选项指定。该过程调用GCC的C编译器(ccl),汇编器(as)和连接器(ld)。而gcc –c在将源文件转化为目标代码以后结束,在这个过程当中只调用了C编译器(ccl)和汇编器(as),而连接器(ld)并无被执行,目标代码可在以后被链接到一个程序。segmentfault
经常使用参数包括: .c后缀文件——C语言源文件 .a后缀文件——由目标文件构成的档案库文件 .C或.cc或.cxx后缀文件——C++源文件 .h后缀文件——头文件; .i 后缀文件——通过预处理的C源文件 .ii后缀文件——通过预处理的C++源文件 .m后缀文件——Objective-C源文件 .o后缀文件——编译后的目标文件 .s后缀文件——汇编语言源码文件 .S/.sx后缀文件——通过预编译的汇编语言源码文件
(2)经过GCC编译的预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)、连接(Linking)4个阶段来举例说明GCC命令的使用。性能优化
根据连接时期的不一样分为静态库和动态库两种。静态库是在连接阶段被链接至可执行文件中,所以即便库被删除了,程序依然能够成功运行。而动态库的连接是在程序执行的时候被链接的,在连接阶段仅链接函数的引用,所以程序编译完成后,须要将库保留在系统中,供程序运行时调用。C的标准库就是动态连接库,系统中全部运行的程序共享着同一个C标准库的代码段。服务器
对于静态连接库来讲,多个程序连接了同一个库,那么每个生成的可执行文件都会有这个库的副本,虽然能够避免程序在其余系统上运行时缺乏相关库文件,可是却致使了系统空间的浪费。而动态连接库直接在程序运行时被连接,程序的运行速度相比静态连接库会略有影响,却大大的节省了系统的资源。另外当动态连接库升级时无需像静态连接库那样从新编译连接其余原有的代码。编辑器
动态连接库的后缀名为.so,建立命令须要添加-fPIC标签告诉编译器相对跳转、-shared标签告诉编译器创建动态连接库。函数
命令gcc -shared -fPIC hello.c -o libhello.so
静态库的后缀名为.a,文件名的命名规范为libxxxx.a,lib为前缀,xxxx为lib的名称。例如:建立的静态库名为mystatic,则静态库文件名就是libmystatic.a。工具
关于在linux下经过GCC命令编译生成动态连接库的方法可参考《Python中扩展C语言加快执行速度的实现方法》一文,接下来本文详细介绍下经过GCC命令编译生成和链接静态库的方法。性能
(1).c源程序编译成.o文件
gcc -c static_share.c
(2)ar命令将.o转换成.a静态库
ar rcs libmystatic.a static_share.o ar:归档工具命令,把多个目标文件打包到一个归档文件中,每个目标文件都是归档文件的一个成员。 r:插入目标文件到归档文件中,若归档文件中已存在此目标文件,则替换。若归档文件中不存在此目标文件,则建立。 c:建立归档文件,即静态连接库。 s:写入一个目标文件索引到归档文件中,或者更新已经存在的归档文件索引。对一个库作ar s等同于对该库作ranlib。randlib工具的做用为对静态库的符号索引表进行更新。
注:ar rcs libmystatic.a static_share.c生成.a静态库,应用于连接时会出现报错:./libmystatic.a: 没法添加符号: 归档没有索引;运行 ranlib 以添加一个collect2: error: ld returned 1 exit status。此处须要先生成.o目标文件,由.o文件生成静态库,不然没法添加符号至符号表。
(3)连接静态库
使用静态库中函数时,须要在源程序中包含静态库的头文件,然后使用GCC命令连接静态库生成可执行文件。
gcc -o test test.c -static -L. -lmystatic (-I/home/yuanxiao/static_share_test) -L:指定静态库的查找位置,.表示静态库在当前目录下查找。Linux下库文件默认的路径为/usr/lib/ -l:指定静态库名,因为静态库的命名规则是以lib开头且以.a结尾,gcc会在静态库名前加上前缀lib,而后追加扩展名.a后获得的静态库文件名来查找静态库文件,所以如libmystatic.a的库,只写:-lmystatic便可。当多个静态库连接时每一个静态库名前都要加-l。 -static:-lmystatic 连接libhello.so 或者libhello.a库文件, 当同时存在静态库和共享库时共享库文件优先,此时可使用-static强制使用静态库
注:include头文件时< >引用的是系统指定路径内的头文件(linux下头文件默认路径为/usr/include/)," "引用的是程序目录的相对路径中的头文件,当编译器在程序目录的相对路径中找不到该头文件时会继续在类库路径里搜寻该头文件。所以有时须要-I选项指定所须要的头文件路径。
(4)运行可执行文件
静态连接库中的函数已经连接到目标文件中,所以删除静态库文件后程序仍然正常运行。
./test
(1)在Eclipse中创建新的C Project,选择Shared Library,选择Linux GCC。
注:因为是Linux环境,选择Linux GCC时Eclipse无需额外配置,编译生成的目标文件基于X86-64。选择Cross Gcc时须要配置prefix和path选项才能编译成功。
(2)添加源文件。将源文件存于项目文件夹下,在项目上右击选择“refresh”直接更新至项目路径下
(3)C/C++Build--->Setting--->Include下添加路径信息后,GCC C Compiler下会同步显示。
注:在GCC C Linker选项卡下,能够发现手动建立动态连接库时-shared选项。
(4)点击工程Project,Build All完成编译,能够看到.so后缀文件。
注:此处有Debug和Release两种编译方式。Debug为调试版本,包含调试信息,而且不做任何优化,便于程序员调试程序。Release为发布版本,每每进行了各类优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 能够看到Debug方式编译选项为-O0,而 Release方式编译选项为-O3。
生成静态连接库时,将Project工程的Build Artifact选项配置为Static Library生成类型。其他也参考动态连接库的生成方法。
在GCC C Linker选项卡下,能够发现手动建立静态连接库时ar命令。
点击工程Project,Build All完成编译,能够看到.a后缀文件生成。
当一个Project工程须要连接静态连接库时,将Project的Build Artifact选项配置为Excutable生成类型。
同时须要将添加静态连接库文件和头文件路径,使其包含至工程文件中。点击工程Project,Build All完成编译,能够看到可执行文件生成。