C 为什么一些系统库需要a-l选项,而另一些则不需要?

C 为什么一些系统库需要a-l选项,而另一些则不需要?,c,compilation,C,Compilation,我最近参加了一个使用pthreads的课程,在编译时我们被告知添加-lpthread。但是,当为系统头文件使用其他#include语句时,对象实现代码的链接似乎会自动发生?例如,如果我只想获取头文件#include,我不需要编译中的-l选项,只需链接该.o实现文件即可 #include <stdio.h> int main() { return 0; } 您将看到gcc实际上做了什么。您将看到它在背后与库链接。这就是为什么您没有明确指定系统库。-l选项用于链接外部库。在这种情

我最近参加了一个使用pthreads的课程,在编译时我们被告知添加
-lpthread
。但是,当为系统头文件使用其他
#include
语句时,对象实现代码的链接似乎会自动发生?例如,如果我只想获取头文件
#include
,我不需要编译中的
-l
选项,只需链接该
.o
实现文件即可

#include <stdio.h>

int main() {
  return 0;
}

您将看到gcc实际上做了什么。您将看到它在背后与库链接。这就是为什么您没有明确指定系统库。

-l选项用于链接外部库。在这种情况下,
libpthread
默认情况下链接系统库


基本答案:-lpthreads告诉编译器/链接器链接到pthreads库

更长的答案
标头告诉编译器,当稍后链接代码时,某个函数将可用(有时该函数在标头中定义,可能是内联的)。因此,编译器将函数标记为基本可用,但稍后在链接阶段,链接器必须将函数调用连接到实际函数。系统头中的许多函数是链接器自动使用的“C运行时库”的一部分,但其他函数是由外部库(如pthreads)提供的。在由外部库提供的情况下,必须使用'-lxxx',以便编译器/链接器知道要在进程中包括哪个外部库,以便正确获取函数的地址


希望这对C头文件不包含函数的实现有所帮助。它只包含函数原型,因此编译器可以生成正确的函数调用

实际实现存储在库中。最常用的函数(如
printf
malloc
)在标准C库(LibC)中实现,除非您请求不链接,否则它隐式链接到任何可执行文件。线程支持在一个单独的库中实现,该库必须通过向链接器传递
-pthread
选项来显式链接


注意:您可以将选项
-pthread
传递给编译器。

默认情况下会搜索一些库文件,只是为了方便,基本上是C标准库。链接器有禁用这种便利性的选项,并且没有默认库(如果您正在做一些不寻常的事情并且不想要它们)。非默认库,您必须告诉链接器使用它们

可以有一种机制来告诉源代码中需要哪些库(包含文件是纯文本,只是在#include行“复制粘贴”),没有技术困难。但实际上没有(据我所知,甚至没有非标准的编译器扩展)


不过,有一些解决方案可以解决这个问题,例如unixy平台的pkg config,它通过为库提供编译器和链接器选项来解决包含和库文件的问题。

编译器链接标准C库libc。隐式地使用
-lc
参数是不必要的。Pthreads是一个系统库,但不是C标准库的一部分,因此必须显式链接

如果要指定,则需要显式链接libc(或其他替代的C库)


如果所有系统库都是隐式链接的,则gcc必须为每个系统提供不同的实现(例如,pthreads不是Windows上的系统库),并且如果系统引入了新库,gcc必须在锁定步骤中进行更改。此外,链接时间会随着每个库在未知序列中搜索以解析符号而增加。C标准库是编译器在任何特定实现中都可以依赖的库,因此隐式链接通常是安全和简单的。

我找不到合适的副本,但是。指定的副本回答了标题中措辞相当糟糕的问题(现在由我修改),但该机构表示,这实际上是一个不同的问题。
gcc -v -o simple simple.c