C编译器如何发现-lm指向文件libm.a?

Linux中的C编程中的.a文件是什么? 是库文件吗?

To merge with the math library libm.a you would type cc -o program_name prog.c -lm when you compile the program. The -lm means: add in libm. If we wanted to add in the socket library libsocket.a to do some network programming as well, we would type cc -o program_name prog.c -lm -lsocket and so on. 

在这里,编译器如何find-lm指向文件libm.a,-lsocket指向libsocket.a?

如果我们将头文件添加到程序中,编译时是否必须提到库?

正如Ignacio所说,.a文件是静态库。 “a”代表“归档”,.a文件由名为“ar”的程序构建。

每个.a文件都包含一个或多个.o文件和一个名称索引。 在链接过程中,只有包含使用名称的.o文件才被包含在最终的程序中。 这样就不需要包含整个C库,只会复制像“printf”这样使用过的函数。

编译器如何找到这些库? 它有一个内置的搜索库路径的集合。 作为一个例子,如果问GCC会告诉你它的搜索路径:

 # gcc -print-search-dirs install: /usr/lib/gcc/i686-redhat-linux/4.4.4/ programs: =/usr/libexec/gcc/i686-redhat-linux/4.4.4/:/usr/libexec/gcc/i686-redhat-linux/4.4.4/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/:/usr/libexec/gcc/i686-redhat-linux/4.4.4/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/bin/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/bin/ libraries: =/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/lib/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/lib/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../:/lib/i686-redhat-linux/4.4.4/:/lib/:/usr/lib/i686-redhat-linux/4.4.4/:/usr/lib/ 

您可以使用“-L / path”选项添加更多的库搜索路径。

在这些路径中,它首先搜索以“.so”扩展名命名的“动态库”。 然后搜索带“.a”扩展名的静态库。 它总是将“lib”添加到名称的前面。

.a文件是静态库 ,而不是.so文件是动态库。 通常情况下,gcc会查找动态库(如果可用),除非通过静态。

头文件包含编译器为了将源代码构建到目标文件中而需要的定义,但是这些库包含链接器将目标文件转换为可执行文件所需的实际例程。

当你传递选项-lm ,编译器“知道”要查找libm.a(或libm.so),因为这就是-l选项被记录和实现的方式:以-l (这里只是m ),前缀lib和后缀.a来获取libm.a

每个库在使用的头文件和库文件之间可以有它自己的关系。 一个头文件根本不需要任何库,但是更常见的是一个库有多个头文件。