GCC:如何使这个编译和链接工作?

3
我想从文件tester-1.c中使用我在libdrm.h中定义并在libdrm.c中实现的函数。这三个文件都在同一个文件夹中,并使用pthread函数。
它们的包含文件如下: libdrm.h
#ifndef __LIBDRM_H__
#define __LIBDRM_H__

#include <pthread.h>

#endif

libdrm.c <- 没有 main() 函数

#include <stdio.h>
#include <pthread.h>
#include "libdrm.h"

tester-1.c <- has teh main()

#include <stdio.h>
#include <pthread.h>
#include "libdrm.h"

编译libdrm.c时出现的错误提示如下:
gcc libdrm.c -o libdrm -l pthread
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

编译器针对 tester-1.c 的错误信息如下:

gcc tester-1.c -o tester1 -l pthread
/tmp/ccMD91zU.o: In function `thread_1':
tester-1.c:(.text+0x12): undefined reference to `drm_lock'
tester-1.c:(.text+0x2b): undefined reference to `drm_lock'
tester-1.c:(.text+0x35): undefined reference to `drm_unlock'
tester-1.c:(.text+0x3f): undefined reference to `drm_unlock'
/tmp/ccMD91zU.o: In function `thread_2':
tester-1.c:(.text+0x57): undefined reference to `drm_lock'
tester-1.c:(.text+0x70): undefined reference to `drm_lock'
tester-1.c:(.text+0x7a): undefined reference to `drm_unlock'
tester-1.c:(.text+0x84): undefined reference to `drm_unlock'
/tmp/ccMD91zU.o: In function `main':
tester-1.c:(.text+0x98): undefined reference to `drm_setmode'
tester-1.c:(.text+0xa2): undefined reference to `drm_init'
tester-1.c:(.text+0xac): undefined reference to `drm_init'
tester-1.c:(.text+0x10e): undefined reference to `drm_destroy'
tester-1.c:(.text+0x118): undefined reference to `drm_destroy'

所有这些函数都在libdrm.c中定义。
我应该使用什么gcc命令来编译和链接这些文件?

1
双前导下划线(以及单前导下划线后跟大写字母)是为实现保留的。请不要在自己的命名中使用这样的名称。 - user395760
3个回答

11

使用GCC的-c选项将你的.c源文件编译成目标文件,然后可以链接这些目标文件到可执行程序中并连接所需的库:

gcc libdrm.c -c
gcc tester-1.c -c
gcc tester-1.o libdrm.o -o tester1 -lpthread

像许多其他人建议的那样,一次完成编译和链接也可以正常工作。但是,了解构建过程涉及这两个阶段是很重要的。

你的构建失败了,因为你的翻译模块(即源文件)需要彼此之间的符号。

  • libdrm.c 单独无法生成可执行文件,因为它没有 main() 函数。
  • tester-1.c 的链接失败,因为链接器没有被告知在 libdrm.c 中定义的所需符号。

使用 -c 选项,GCC 编译并汇编源代码,但跳过链接,留下.o文件,这些文件可以链接成可执行文件或打包成库。


1
gcc tester-1.c libdrm.c -o tester1 -l pthread

你需要一次性编译所有的源文件,而不是逐个进行编译。或者将libdrm.c编译为库文件,然后在编译tester1.c时将其链接。


或者您可以将libdrm.c编译为一个目标文件,然后链接它。这就是“一次性”编译在底层执行的操作。 - Conrad Meyer

1
gcc test-1.c libdrm.c -o libdrm -l pthread

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接