初学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'中定义的函数。

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

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

 


 

Logo

更多推荐