GCC链接库用于编译

时间:2016-02-09 18:41:40

标签: c linux gcc

为什么当 #include 形式的信息已经存在于源文件中时,我们必须告诉 gcc 链接哪个库?

例如,如果我有一个使用线程的代码并且有:

#include <pthread.h>

我仍然需要在 gcc 中使用 -pthread 选项进行编译:

gcc -pthread test.c

如果我不提供 -pthread 选项,则会在找到线程函数定义时出错。

我正在使用这个版本:

gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4

4 个答案:

答案 0 :(得分:4)

这可能是让初学者走向C的最常见的事情之一。

在C中,有两个不同的步骤来构建程序,编译和链接。出于您的问题的目的,这些步骤将您的代码连接到两种不同类型的文件,标题和库。

C代码中的hive -S -e "SHOW COLUMNS IN database_name.table_name" > column_names.txt 指令由编译器处理。在将C文件转换为目标文件之前,编译器(实际上是预处理器)将#include <pthread.h>的内容字面粘贴到您的代码中。

pthread.h是头文件,而不是库。它包含了您可以在库中找到的函数列表,它们采用的参数以及它们返回的内容。标头可以在没有库的情况下存在,反之亦然。标题是一个文本文件,通常在Unix派生系统的pthread.h中找到。你可以像任何C文件一样打开它来阅读内容。

命令行/usr/include同时进行编译和链接。在过去,您首先会执行gcc -lpthread test.c,然后cc test.c之类的操作。如您所见,ld -lpthread test.o实际上是链接器的一个选项。

链接器对C代码或标题等文本文件一无所知。它仅适用于编译的目标文件和现有的库。 -lpthread标志告诉它查找哪些库以查找您正在使用的函数。

答案 1 :(得分:3)

标题的名称与库的名称无关。这真的只是出乎意外。通常,图书馆提供了许多标题。

特别是在C ++中,每个类通常有一个标头,并且该库通常提供来自同一名称空间的类实现。在C中,标题被组织为包含一些共同的函数子集 - stdio.h包含数学运算,Random ran = new Random(); int x = ran.nextInt(eMinor.size() - 1) System.out.println(eMinor.get(x)); 提供IO函数等。

答案 2 :(得分:2)

它们是两个不同的东西。 .h文件包含声明,有时也包含内联函数。众所周知,每个函数都应该有一个实现/定义才能工作。这些实现是分开保存的。 pwd例如是以二进制形式保存-lpthread实现的库。

当您不想与他人分享您的商业代码时,将实施分离是人们想要的

所以,

functions declared in headers

告诉gcc -pthread test.c 查找gccpthread.h中声明的定义。 libpthread被链接器自动扩展为-pthread

答案 3 :(得分:1)

有一些编译器,你告诉它lib目录的位置,它只是扫描了所有想要找到匹配的文件。然后有一些编译器是另一个极端,你必须告诉它要链接的所有东西。这里的关键是简单地告诉编译器寻找一些定义,甚至更简单地将一些外部文件包含到这个文件中。这不一定与库或对象有任何连接,有许多包含与这些东西无关,这是一个不好的假设。接下来链接器是一个不同的步骤,通常是与编译器不同的程序,因此包含不仅与对象或库没有一对一的关系,链接器也不是编译器。