C语言 Linux CentOS 7和Ubuntu 20.04.1 LTS之间的共享库差异



我正在将一个用C编写的项目从CentOS 7 (Core)移植到Ubuntu 20.04.1 LTS (Focal Fossa)系统。本项目在很大程度上依赖于<cpuset.h>库,并在CentOS系统上正确编译和执行。然而,当我试图在Ubuntu系统上使用cpuset.h中的函数时,我得到了"未定义的引用"错误。

下面的代码,存储在文件test.c中,在CentOS上编译并正确运行:

#define _GNU_SOURCE
#include<stdio.h>
#include <cpuset.h>
int main(){
int x = cpuset_version();
printf("cpuset lib version: %dn",x );
return 0;
}

如何编译:gcc -Wall -O2 -std=gnu99 -g -lcpuset test.c -o test

输出:

[xxxx@CentOS]$ ./test 
cpuset lib version: 3

然而,当我试图在Ubuntu系统上编译相同的test.c文件时,我得到这个错误:

xxxx@Ubuntu:$ gcc -Wall -O2 -std=gnu99 -g -lcpuset test.c -o test
/usr/bin/ld: /tmp/ccpxlk4F.o: in function `main':
test.c:8: undefined reference to `cpuset_version'
collect2: error: ld returned 1 exit status

此外,这并不局限于<cpuset.h>库。我试图使用一个简单的函数从<pthread.h>,它也给了我同样的错误。谁能帮我确定为什么我不能在Ubuntu系统上使用共享库?提前感谢

由于OP的问题是GCC的参数顺序错误(许多指南确实显示了错误的顺序!),正如在对问题的评论中讨论的那样,我认为显示最小的Makefile来处理这些是有保证的:

CC      := gcc
CFLAGS  := -Wall -O2 -g
LDFLAGS := -lcpuset
TARGETS := test
.PHONY: all clean
all: $(TARGETS)
clean:
rm -f *.o $(TARGETS)
%.o: %.c
$(CC) $(CFLAGS) -c $^
test: test.o
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@

注意,Makefiles中的缩进必须使用制表符s,而不是空格。由于本论坛将Tabs转换为空格,因此您需要修复上述makefile,例如通过运行sed -e 's|^ *|t|' -i Makefile

如果您想将foo.c直接编译为可执行文件,那么方法是

foo: foo.c
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@

您只需要运行make(默认使用当前目录中的Makefile,默认目标是第一个,位于名为all的目标之上)来重新编译TARGETS(这里是test,但您可以通过将它们添加到行中以空格分隔)。

你也可以运行make clean test从"scratch"重建test,即首先删除所有临时文件和所有目标。

您可以通过在命令行中提供CFLAGS这样的变量来覆盖它们;例如,make CFLAGS="-Wall -Wextra -Os" clean all可以重新编译具有不同编译标志的所有内容。

最新更新