为什么在Linux平台上动态链接需要在GCC中存在SO文件?

时间:2018-08-15 07:44:16

标签: gcc linker

使用pthread考虑以下简单代码:

#include<pthread.h>
#include<stdio.h>
#include <unistd.h>

void *thread(void *ptr) {
  long type = (long) ptr;
  printf("value: %ld\n", type);
  return NULL;
}

int main() {
  pthread_t thread1;
  long value = 1;
  pthread_create(&thread1, NULL, *thread, (void*) value);
  pthread_join(thread1, NULL);
  return 0;
}

运行gcc -o thread thread.c会产生以下错误:

/tmp/ccNBTPFM.o: In function `main':
thread.c:(.text+0x69): undefined reference to `pthread_create'
thread.c:(.text+0x7a): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status

我知道我应该使用gcc -o thread thread.c -lpthread来完成这项工作。我的问题是,为什么SO文件需要由-lpthread指定。我的猜测是,链接器需要在链接时知道所需的SO文件的文件名,例如libpthread.so,并在符号(pthread_createpthread_join)与文件之间添加映射pthread库的名称到结果程序thread中。结果,在运行thread时,链接程序可以通过映射找到SO文件,以定义pthread_createpthread_join

我正在使用16.04.5 LTS 64位和GCC 8.1.0。

我的猜测正确吗?

1 个答案:

答案 0 :(得分:0)

加载动态可执行文件时,动态链接器将加载所有引用的.so文件,然后针对所有引用的库解析所有外部符号。静态链接器只是在验证是否可以在某个引用的库中找到所有外部符号。为了知道应该引用哪些库,请使用-l。

例如,如果您偶然知道pthread函数已经在运行时libc中(但不是在编译时libc中),则可以使用-Wl,-undefined之类的标志来告诉静态链接器:忽略未定义的符号。在运行时,将在运行时库中找到该符号。