linux gcc编译参数顺序问题

初学Linux C编程遇到编译出错

运行下面编译命令,出错

gcc -g -W -Wall -pthread  -lcrypto -o httpd httpd.c

错误信息:

/tmp/ccYw8W8E.o: In function `md5test':
/home/rivulet/work/Tinyhttpd-master/httpd.c:666: undefined reference to `MD5_Init'
/home/rivulet/work/Tinyhttpd-master/httpd.c:667: undefined reference to `MD5_Update'
/home/rivulet/work/Tinyhttpd-master/httpd.c:668: undefined reference to `MD5_Final'
collect2: error: ld returned 1 exit status
make: *** [httpd] Error 1

一开始以为是库没找到,但是在/user/local/lib下面明明存在libcrypto.so库,后来发现下面命令能编译成功

gcc -g -W -Wall -o httpd httpd.c -lssl -lcrypto 

编译时候,-l所知识的库需要跟在.c文件的后面,表明依赖关系,库与库的之间的依赖关系需要通过顺序定义好,写在前面的库依赖于 写在后边的库

具体解释如下:

The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it. This includes libraries specified with the short-cut -l option, as shown in the following command:

$ gcc -Wall calc.c -lm -o calc   (correct order)

With some linkers the opposite ordering (placing the -lm option before the file which uses it) would result in an error,

$ cc -Wall -lm calc.c -o calc    (incorrect order)
main.o: In function `main':
main.o(.text+0xf): undefined reference to `sqrt'

because there is no library or object file containing sqrt after 'calc.c'. The option -lm should appear after the file 'calc.c'.

When several libraries are being used, the same convention should be followed for the libraries themselves. A library which calls an external function defined in another library should appear before the library containing the function.

For example, a program 'data.c' using the GNU Linear Programming library 'libglpk.a', which in turn uses the math library 'libm.a', should be compiled as,

$ gcc -Wall data.c -lglpk -lm

since the object files in 'libglpk.a' use functions defined in 'libm.a'.

Most current linkers will search all libraries, regardless of order, but since some do not do this it is best to follow the convention of ordering libraries from left to right.

This is worth keeping in mind if you ever encounter unexpected problems with undefined references, and all the necessary libraries appear to be present on the command line.

google翻译如下:

链接器的传统行为是在命令行中指定的库中从左到右搜索外部函数。这意味着包含函数定义的库应该出现在使用它的任何源文件或目标文件之后。这包括使用short-cut -l选项指定的库,如以下命令所示:

$ gcc -Wall calc.c -lm -o calc(正确的顺序)
对于一些链接器,相反的顺序(在使用它的文件之前放置-lm选项)会导致错误,

$ cc -Wall -lm calc.c -o calc(错误的顺序)
main.o:在函数`main'中:
main.o(.text + 0xf):对'sqrt'的未定义引用
因为'calc.c'之后没有包含sqrt的库或目标文件。选项-lm应出现在文件'calc.c'之后。

当使用多个库时,库本身应遵循相同的约定。调用另一个库中定义的外部函数的库应该出现在包含该函数的库之前。

例如,使用GNU线性编程库'libglpk.a'的程序'data.c',它反过来使用数学库'libm.a',应编译为,

$ gcc -Wall data.c -lglpk -lm
因为'libglpk.a'中的目标文件使用'libm.a'中定义的函数。

大多数当前链接器将搜索所有库,无论顺序如何,但由于一些不执行此操作,因此最好遵循从左到右排序库的约定。

如果您遇到未定义引用的意外问题,并且所有必需的库似乎都出现在命令行中,则值得记住。

 


 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当你在Linux上使用gcc编译器时,通常需要执行以下步骤: 1. 打开终端窗口并进入要编译的源代码目录。 2. 编写一个Makefile文件,它描述了源文件之间的依赖关系以及如何编译它们。这是可选的,但对于大型项目来说,它可以使编译过程更加自动化和可靠。 3. 输入以下命令来编译源代码: `gcc -o <输出文件名> <源文件1> <源文件2> ...` 这将使用gcc编译器将所有源文件编译成一个可执行文件,并将其保存在指定的输出文件名中。例如: `gcc -o myprogram main.c file1.c file2.c` 4. 如果编译过程中出现错误,gcc将会给出相应的错误信息,你需要检查错误并修复它们,然后重新编译。 这是一个基本的编译过程。当然,gcc还有许多选项和参数可供使用,可以根据需要进行调整和定制。 ### 回答2: GCC是GNU编译器集合的缩写。本质上,它是一个用于编译和链接C和C++代码的编译器。GCC是开源的,可移植的,以及非常流行的编译器。由于其开源的本质,GCC在许多不同的操作系统上是通用的,包括Linux。 在Linux系统中,GCC是默认的编译器。它被包含在大多数Linux分发版中,并且它有一个Linux专用版本,称为Linux GCCGCC可以用于编译许多不同类型的代码,包括应用程序,库和驱动程序。当然,GCC最重要的特点之一是其灵活性,它可以输入许多不同的源代码文件格式,包括C,C++,Fortran,和Ada等。 GCC的安装通常随着Linux系统的安装而自动安装。如果您的Linux系统上没有安装GCC,您可以通过在终端中使用包管理器命令安装它。命令可能是: sudo apt-get install gcc GCC编译过程中首先会预处理源代码(将源文件中的预处理指令进行展开),接着是编译阶段,将源代码转换为汇编代码,然后将汇编代码转换为二进制机器代码,最后是链接阶段,将不同的模块组合在一起形成可执行文件或动态库。 GCC编译器支持大量的编译选项和参数,使其更加灵活。其中一些选项是可用于微调编译器优化,减少代码大小等。GCC也提供了许多调试选项,以便在处理编译错误和调试代码时使用。 总之,作为一个开源,跨平台的编译器,GCCLinux系统中具有不可替代的地位。它是许多开发人员的首选,因为它能够在Linux系统上编译和构建各种类型的应用程序和库。 ### 回答3: GCC是GNU Compiler Collection的简称,是一个跨平台的编译器集合,被广泛地使用在Linux操作系统下的应用程序开发中。 在Linux下进行程序开发,需要进行编译过程,将源代码转换成可执行文件。GCC提供了一个强大的编译器和链接器,可编译多种语言的源代码,例如C、C++、Objective-C、Fortran等,支持多种编译选项,能够满足不同开发者的需求。 在使用GCC进行编译时,首先需要安装GCC编译器。在Linux系统中,安装GCC非常简单,可以执行以下命令: sudo apt-get update sudo apt-get install gcc 上述命令会从Linux软件仓库中下载并安装GCC编译器。安装完成后,就可以开始进行编译了。 使用GCC编译一个C程序时,可以将源代码保存为.c文件,然后在终端中执行以下命令: gcc -o hello hello.c 其中,-o选项用于指定输出文件的名称,hello.c为源文件的名称。如果编译成功,会生成一个名为hello的可执行文件。 除了基本的编译命令外,GCC还提供了许多编译选项,可以用来控制编译过程,例如优化级别、警告选项等。开发者可以根据自己的需求选择合适的编译选项,以优化程序的性能和可靠性。 总之,GCC是一款功能强大的编译器,提供了丰富的编译选项,为Linux操作系统下的应用程序开发提供了良好的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值