GCC编译动态和静态链接库

合集下载

gcc 编译器命令总结

gcc 编译器命令总结

gcc 编译器命令总结1. 三种常用格式i.gcc C源文件-o 目标文件名。

ii.gcc -o 目标文件名C源文件。

iii.gcc C源文件。

(目标文件名默认为:a.out)2. gcc 支持的一些源文件的后缀.c C语言源代码文件。

.a 是由目标文件构成的档案库文件。

.C .cc 或.cxx 是C++ 源代码文件。

.h 是程序所包含的头文件。

.i 是已经预处理过的C源代码文件。

.ii 是已经预处理的C++源代码文件。

.m 是Objective-C源代码文件。

.o 是编译后的目标文件。

.s 是汇编语言源代码文件。

.S 是经过预处理的汇编语言源代码文件。

3.gcc 常用参数-c 只激活预处理,编译和汇编,也就是只把程序做成obj文件。

-S 只激活预处理和编译,就是把文件编译成汇编代码。

-E 只激活预处理,不生成文件,需要把它重定向到一个输出文件里面。

-g 在可执行文件中包含调试信息。

-v 显示gcc 版本信息。

-o file 把输出文件输出到文件中。

-I dir 在头文件的搜索路径中添加dir 目录。

-L dir 在库文件的搜索路径列表中添加dir目录。

-static 链接静态库。

-library 连接名为library的库文件。

4.例子实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)。

4.1 示例程序如下:#include <stdio.h>int main(void){printf("Hello World!\n");return 0;}这个程序,一步到位的编译指令是:gcc test.c -o test该命令结束后,在文件目下生成(可执行文件)test通过./test 可运行本程序。

4.2 预处理gcc -E test.c -o test.i 或gcc -E test.c可以输出test.i文件中存放着test.c经预处理之后的代码。

工程的编译、链接及基本的调试手段。

工程的编译、链接及基本的调试手段。

工程的编译、链接及基本的调试手段。

1. 工程的编译在计算机科学中,编译是将高级语言源代码转换为机器语言可执行文件的过程。

要进行工程的编译,我们需要先安装相应的编译器,例如C++工程需要安装Microsoft Visual C++或者GCC等等。

然后通过编译器的命令行或者IDE工具,对工程的源代码进行编译。

编译器会对代码进行语义分析、词法分析、语法分析等等操作,生成中间语言,再通过优化生成目标平台的可执行文件。

2. 工程的链接链接是将编译生成的目标文件、库文件和系统提供的标准库文件等连接起来的过程。

在编译过程中,编译器只检查代码的正确性,而在链接过程中,会根据符号表查找函数、变量等的定义,将它们链接到目标文件中。

链接可以分为静态链接和动态链接两种方式。

静态链接将库文件中的函数和变量复制到可执行文件中,使得可执行文件比较大。

而动态链接则将库文件作为独立的文件存在,可供程序使用。

动态链接更节省空间,但需要保证动态库的兼容性。

3. 基本的调试手段调试是程序开发中不可或缺的环节。

通过调试可以解决在编译、链接过程中产生的错误,还可以查看变量的值、函数的执行情况等,从而方便程序的开发和维护。

基本的调试手段包括:- 打印调试信息:在代码中插入打印语句,输出程序中变量的值,以及代码执行过程中的状态信息。

- 断点调试:在代码中设置断点,当程序执行到该断点时,会暂停程序的执行,允许程序员查看程序状态,并进行相应的调整。

- 单步调试:逐行执行代码,查看程序在每一行的执行情况,从而找出导致程序崩溃的原因。

以上是工程编译、链接及基本的调试手段的简单介绍。

在真正的开发过程中,还需要掌握更多的工具和技巧,以提高程序的质量和效率。

gcc使用大全

gcc使用大全

1、用于linux系统下编程的编译器概述GCC(GNU Compiler Collection,GNU编译器套装),是一套由GNU 开发的编程语言编译器。

它是一套GNU编译器套装以GPL 及LGPL 许可证所发行的自由软件,也是GNU计划的关键部分,亦是自由的类Unix及苹果电脑Mac OS X 操作系统的标准编译器。

GCC 原名为GNU C 语言编译器,因为它原本只能处理C语言。

GCC 很快地扩展,变得可处理C++。

之后也变得可处理Fortran、Pascal、Objective-C、Jav a, 以及Ada与其他语言。

历史GCC是由理查德·马修·斯托曼在1985年开始的。

他首先扩增一个旧有的编译器,使它能编译C,这个编译器一开始是以Pastel语言所写的。

Pastel是一个不可移植的Pascal语言特殊版,这个编译器也只能编译Pastel语言。

为了让自由软件有一个编译器,后来此编译器由斯托曼和Len Tower在1987年以C语言重写并成为GNU 专案的编译器。

GCC的建立者由自由软件基金会直接管理。

在1997年,一群不满GCC缓慢且封闭的创作环境者,组织了一个名为EGCS 〈Experimental/Enhanced GNU Compiler System〉的专案,此专案汇整了数项实验性的分支进入某个GCC专案的分支中。

EGCS比起GCC的建构环境更有活力,且EGCS最终也在1999年四月成为GCC的官方版本。

GCC目前由世界各地不同的数个程序设计师小组维护。

它是移植到中央处理器架构以及操作系统最多的编译器。

由于GCC已成为GNU系统的官方编译器(包括GNU/Linux家族),它也成为编译与建立其他操作系统的主要编译器,包括BSD家族、Mac OS X、NeXTSTEP 与BeOS。

GCC通常是跨平台软件的编译器首选。

有别于一般局限于特定系统与执行环境的编译器,GCC在所有平台上都使用同一个前端处理程序,产生一样的中介码,因此此中介码在各个其他平台上使用GCC编译,有很大的机会可得到正确无误的输出程序。

gcc链接文件语法

gcc链接文件语法

gcc链接文件语法在GCC编译器中,链接文件的语法可以通过以下几种方式来指定:1. 直接指定文件名:gcc file1.c file2.c -o output.这种方式将会编译并链接`file1.c`和`file2.c`这两个源文件,并将生成的可执行文件命名为`output`。

2. 使用通配符:gcc .c -o output.这种方式将会编译并链接当前目录下所有以`.c`为后缀的源文件,并将生成的可执行文件命名为`output`。

3. 使用对象文件:gcc file1.o file2.o -o output.如果你已经通过其他方式将源文件编译为对象文件(`.o`文件),你可以直接链接这些对象文件。

这种方式可以提高编译的效率。

4. 使用静态库:gcc file.c -L/path/to/library -lmylib -o output.如果你使用了外部的静态库,你需要通过`-L`选项指定静态库所在的路径,通过`-l`选项指定要链接的静态库的名称。

这个例子中,`-lmylib`将会链接名为`libmylib.a`的静态库。

5. 使用动态库:gcc file.c -L/path/to/library -lmylib -o output.如果你使用了外部的动态库,你同样需要通过`-L`选项指定动态库所在的路径,通过`-l`选项指定要链接的动态库的名称。

这个例子中,`-lmylib`将会链接名为`libmylib.so`的动态库。

需要注意的是,链接文件的顺序也很重要。

GCC将按照文件在命令行中出现的顺序进行链接,因此如果某个源文件依赖于另一个源文件中定义的函数或变量,那么被依赖的源文件应该出现在依赖它的源文件之前。

以上是关于GCC链接文件语法的一些基本介绍,具体的使用方法还可以根据实际情况进行调整和扩展。

gcc的使用简介与命令行参数说明

gcc的使用简介与命令行参数说明

gcc的使⽤简介与命令⾏参数说明(⼀) gcc的基本⽤法(⼆) 警告提⽰功能选项(三) 库操作选项(四) 调试选项(五) 交叉编译选项(⼀) gcc的基本⽤法使⽤gcc编译器时,必须给出⼀系列必要的调⽤参数和⽂件名称。

不同参数的先后顺序对执⾏结果没有影响,只有在使⽤同类参数时的先后顺序才需要考虑。

如果使⽤了多个 -L 的参数来定义库⽬录,gcc会根据多个 -L 参数的先后顺序来执⾏相应的库⽬录。

因为很多gcc参数都由多个字母组成,所以gcc参数不⽀持单字母的组合,Linux中常被叫短参数(short options),如 -dr 与 -d -r 的含义不⼀样。

gcc编译器的调⽤参数⼤约有100多个,其中多数参数我们可能根本就⽤不到,这⾥只介绍其中最基本、最常⽤的参数。

gcc最基本的⽤法是:gcc [options] [filenames]其中,options就是编译器所需要的参数,filenames给出相关的⽂件名称,最常⽤的有以下参数:-c只编译,不链接成为可执⾏⽂件。

编译器只是由输⼊的 .c 等源代码⽂件⽣成 .o 为后缀的⽬标⽂件,通常⽤于编译不包含主程序的⼦程序⽂件。

-o output_filename确定输出⽂件的名称为output_filename。

同时这个名称不能和源⽂件同名。

如果不给出这个选项,gcc就给出默认的可执⾏⽂件 a.out 。

-g产⽣符号调试⼯具(GNU的 gdb)所必要的符号信息。

想要对源代码进⾏调试,就必须加⼊这个选项。

-O对程序进⾏优化编译、链接。

采⽤这个选项,整个源代码会在编译、链接过程中进⾏优化处理,这样产⽣的可执⾏⽂件的执⾏效率可以提⾼,但是编译、链接的速度就相应地要慢⼀些,⽽且对执⾏⽂件的调试会产⽣⼀定的影响,造成⼀些执⾏效果与对应源⽂件代码不⼀致等⼀些令⼈“困惑”的情况。

因此,⼀般在编译输出软件发⾏版时使⽤此选项。

-O2⽐ -O 更好的优化编译、链接。

gccstatic静态编译选项提示错误:usrlibld:cannotfind-lc

gccstatic静态编译选项提示错误:usrlibld:cannotfind-lc

gccstatic静态编译选项提⽰错误:usrlibld:cannotfind-lc 在学习gcc静态库动态库编译的时候选⽤静态库编译时出错显⽰:/usr/lib/ld:cannot find -lc百度:/usr/lib/ld:cannot find -lc多处给的解决⽅案为:然⽽并不能解决问题,最终定位发现是静态编译的问题。

⽽且不⽌会出现这种情况:/usr/lib/ld:cannot find -lc/usr/lib/ld:cannot find -lgcc_s/usr/lib/ld:cannot find -lm等的错误,主要原因在静态编译时需要链接静调库。

如上命令:[xiaohexiansheng@centos6 app]$ gcc -static -I./libs main.c -o app -L./libs -lcrypto -lfunc如果在编译时去掉-static选项选⽤动态库编译则不会出现此种情况[xiaohexiansheng@centos6 app]$ gcc -I./libs main.c -o app -L./libs -lcrypto -lfunc[xiaohexiansheng@centos6 app]$ lsapp libs main.c⾮静态编译时ldd filename,显⽰如下,这是可执⾏程序所需的动态库,运⾏可执⾏程序时需要的动态库。

[xiaohexiansheng@centos6 app]$ ldd applinux-gate.so.1 => (0x004ad000)libcrypto.so => /usr/lib/libcrypto.so (0x03ad9000)libfunc.so => not foundlibc.so.6 => /lib/libc.so.6 (0x0052a000)libdl.so.2 => /lib/libdl.so.2 (0x0070c000)libz.so.1 => /lib/libz.so.1 (0x00713000)/lib/ld-linux.so.2 (0x00508000)静态编译时需要将所有的.a库链接到可执⾏⽂件中,所以需要libc静态库⽂件,在系统找查找glibc-static提⽰没有库⽂件。

动态链接库.so的编译与使用

动态链接库.so的编译与使用

动态链接库*.so的编译与使用- -动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。

1、动态库的编译下面通过一个例子来介绍如何生成一个动态库。

这里有一个头文件:so_test.h,三个.c文件:test_a.c、t est_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

so_test.h:#include <stdio.h>#include <stdlib.h>void test_a();void test_b();void test_c();test_a.c:#include "so_test.h"void test_a(){printf("this is in test_a...\n");}test_b.c:#include "so_test.h"void test_b(){printf("this is in test_b...\n");}test_c.c:#include "so_test.h"void test_c(){printf("this is in test_c...\n");}将这几个文件编译成一个动态库:libtest.so$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so2、动态库的链接在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。

程序的源文件为:test.c。

test.c:#include "so_test.h"int main(){test_a();test_b();test_c();return 0;}l 将test.c与动态库libtest.so链接生成执行文件test:$ gcc test.c -L. -ltest -o testl 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了$ ldd test./test 执行test,可以看到它是如何调用动态库中的函数的。

gcc编译参数

gcc编译参数

gcc编译参数在GCC中,编译参数用于指定编译器的行为和选项。

这些参数可以对代码进行优化、生成调试信息、链接不同的库等等。

以下是一些常用的GCC编译参数:1.优化参数:--O0:不进行优化--O1:进行基本优化--O2:进行更多优化--O3:进行最大优化--Os:进行优化以缩小代码尺寸2.调试参数:--g:生成调试信息- -ggdb:生成GDB可用的调试信息- -gdwarf:生成DWARF调试信息3.警告参数:- -Wall:开启所有警告- -Werror:将所有警告视为错误- -Wextra:开启额外的警告- -Wno-unused-parameter:忽略未使用的函数参数的警告4.标准库参数:- -std=c89:使用C89标准- -std=c99:使用C99标准- -std=c11:使用C11标准- -std=c++98:使用C++98标准- -std=c++11:使用C++11标准- -std=c++14:使用C++14标准- -std=c++17:使用C++17标准5.预处理参数:- -D<symbol>=<value>:定义宏- -U<symbol>:取消宏定义- -I<dir>:指定头文件路径6.链接参数:- -L<dir>:指定库文件路径- -l<library>:链接库文件- -shared:生成共享库- -static:生成静态库7.其他参数:--c:只编译,不链接- -o <output>:指定输出文件名- -Wl,<option>:传递选项给链接器- -Wp,<option>:传递选项给预处理器这只是一小部分常用的GCC编译参数,GCC还提供了许多其他参数用于更精细地控制编译过程。

可以通过运行`gcc --help`命令查看GCC支持的所有编译参数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程
序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需
要动态库存在。本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它
们。

在创建函数库前,我们先来准备举例用的源程序,并将函数库的源程序编译成.o文件。
第1步:编辑得到举例的程序--hello.h、hello.c和main.c;
hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出
"Hello XXX!"。hello.h(见程序1)为该函数库的头文件。main.c(见程序3)为测试库文件的
主程序,在主程序中调用了公用函数hello。

1. #ifndef HELLO_H
2. #define HELLO_H
3.
4. void hello(const char *name);
5.
6. #endif //HELLO_H

复制代码
程序1: hello.h

1. #include
2.
3. void hello(const char *name)
4. {
5. printf("Hello %s!\n", name);
6. }

复制代码
程序2: hello.c

1. #include "hello.h"
2.
3. int main()
4. {
5. hello("everyone");
6. return 0;
7. }

复制代码
程序3: main.c
第2步:将hello.c编译成.o文件;
无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过g
cc先编译成.o文件。

在系统提示符下键入以下命令得到hello.o文件。
# gcc -c hello.c
#

我们运行ls命令看看是否生存了hello.o文件。
# ls
hello.c hello.h hello.o main.c
#

在ls命令结果中,我们看到了hello.o文件,本步操作完成。
下面我们先来看看如何创建静态库,以及使用它。
第3步:由.o文件创建静态库;
静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将
创建的静态库名为myhello,则静态库文件名就是libmyhello.a。在创建和使用静态库时,
需要注意这点。创建静态库用ar命令。

在系统提示符下键入以下命令将创建静态库文件libmyhello.a。
# ar crv libmyhello.a hello.o
#

我们同样运行ls命令查看结果:
# ls
hello.c hello.h hello.o libmyhello.a main.c
#

ls命令结果中有libmyhello.a。
第4步:在程序中使用静态库;
静态库制作完了,如何使用它内部的函数呢?只需要在使用到这些公用函数的源程序中包含
这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明静态库名,gcc将会从静
态库中将公用函数连接到目标文件中。注意,gcc会在静态库名前加上前缀lib,然后追加
扩展名.a得到的静态库文件名来查找静态库文件。
在程序3:main.c中,我们包含了静态库的头文件hello.h,然后在主程序main中直接调用
公用函数hello。下面先生成目标程序hello,然后运行hello程序看看结果如何。

(# gcc -o hello main.c -L. -lmyhello??)
#gcc main.c libmyhello.a -o main
# ./hello
Hello everyone!
#

我们删除静态库文件试试公用函数hello是否真的连接到目标文件 hello中了。
# rm libmyhello.a
rm: remove regular file `libmyhello.a'? y
# ./hello
Hello everyone!
#

程序照常运行,静态库中的公用函数已经连接到目标文件中了。
我们继续看看如何在Linux中创建动态库。我们还是从.o文件开始。
第5步:由.o文件创建动态库文件;
动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀lib,但其
文件扩展名为.so。例如:我们将创建的动态库名为myhello,则动态库文件名就是
libmyhello.so。用gcc来创建动态库。

在系统提示符下键入以下命令得到动态库文件libmyhello.so。
# gcc -shared -fPCI -o libmyhello.so hello.o
#

我们照样使用ls命令看看动态库文件是否生成。
# ls
hello.c hello.h hello.o libmyhello.so main.c
#

第6步:在程序中使用动态库;
在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含这
些公用函数的原型声明,然后在用gcc命令生成目标文件时指明动态库名进行编译。我们先
运行gcc命令生成目标文件,再运行它看看结果。
# gcc -o hello main.c -L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shared
object file: No such file or directory
#

哦!出错了。快看看错误提示,原来是找不到动态库文件libmyhello.so。程序在运行时,
会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提
示类似上述错误而终止程序运行。我们将文件libmyhello.so复制到目录/usr/lib中,再
试试。

# mv libmyhello.so /usr/lib
# ./hello
Hello everyone!
#

成功了。这也进一步说明了动态库在程序运行时是需要的。
我们回过头看看,发现使用静态库和使用动态库编译成目标程序使用的gcc命令完全一样,
那当静态库和动态库同名时,gcc命令会使用哪个库文件呢?抱着对问题必究到底的心情,
来试试看。

先删除除.c和.h外的所有文件,恢复成我们刚刚编辑完举例程序状态。
# rm -f hello hello.o /usr/lib/libmyhello.so
# ls
hello.c hello.h main.c
#

在来创建静态库文件libmyhello.a和动态库文件libmyhello.so。
# gcc -c hello.c
# ar cr libmyhello.a hello.o
# gcc -shared -fPCI -o libmyhello.so hello.o
# ls
hello.c hello.h hello.o libmyhello.a libmyhello.so main.c
#

通过上述最后一条ls命令,可以发现静态库文件libmyhello.a和动态库文件
libmyhello.so都已经生成,并都在当前目录中。然后,我们运行gcc命令来使用函数库
myhello生成目标文件hello,并运行程序 hello。
# gcc -o hello main.c -L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shared
object file: No such file or directory
#

相关文档
最新文档