Linux CentOS 7 和 Ubuntu 20.04.1 LTS 之间的共享库差异
Shared library disparity between Linux CentOS 7 and Ubuntu 20.04.1 LTS
我正在将一个用 C 编写的项目从 CentOS 7(核心)移植到 Ubuntu 20.04.1 LTS(Focal Fossa)系统。该项目严重依赖<cpuset.h>
库,在CentOS系统上编译执行正确。但是,当我尝试在 Ubuntu 系统上使用来自 cpuset.h 的函数时,出现 'undefined reference' 错误。
存储在文件 test.c
中的以下代码可在 CentOS 上正确编译和运行:
#define _GNU_SOURCE
#include<stdio.h>
#include <cpuset.h>
int main(){
int x = cpuset_version();
printf("cpuset lib version: %d\n",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 $@
请注意,Makefile 中的缩进必须使用 Tab 而不是 space。由于本论坛将 Tabs 转换为 spaces,因此您需要修复上述 makefile,例如 运行ning sed -e 's|^ *|\t|' -i Makefile
.
如果你想直接编译say foo.c
为可执行文件,方法是
foo: foo.c
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
只需要运行 make
(默认使用当前目录下的Makefile,默认target是第一个,上面那个叫all
的) , 重新编译 TARGETS(此处为 test
,但您可以通过将它们 space 分隔到该行来提供更多)。
您还可以 运行 make clean test
从“从头开始”重建 test
,即首先删除所有临时文件和所有目标。
您可以通过简单地在命令行上提供它们来覆盖像 CFLAGS
这样的变量;例如,make CFLAGS="-Wall -Wextra -Os" clean all
使用不同的编译标志重新编译所有内容。
我正在将一个用 C 编写的项目从 CentOS 7(核心)移植到 Ubuntu 20.04.1 LTS(Focal Fossa)系统。该项目严重依赖<cpuset.h>
库,在CentOS系统上编译执行正确。但是,当我尝试在 Ubuntu 系统上使用来自 cpuset.h 的函数时,出现 'undefined reference' 错误。
存储在文件 test.c
中的以下代码可在 CentOS 上正确编译和运行:
#define _GNU_SOURCE
#include<stdio.h>
#include <cpuset.h>
int main(){
int x = cpuset_version();
printf("cpuset lib version: %d\n",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 $@
请注意,Makefile 中的缩进必须使用 Tab 而不是 space。由于本论坛将 Tabs 转换为 spaces,因此您需要修复上述 makefile,例如 运行ning sed -e 's|^ *|\t|' -i Makefile
.
如果你想直接编译say foo.c
为可执行文件,方法是
foo: foo.c
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
只需要运行 make
(默认使用当前目录下的Makefile,默认target是第一个,上面那个叫all
的) , 重新编译 TARGETS(此处为 test
,但您可以通过将它们 space 分隔到该行来提供更多)。
您还可以 运行 make clean test
从“从头开始”重建 test
,即首先删除所有临时文件和所有目标。
您可以通过简单地在命令行上提供它们来覆盖像 CFLAGS
这样的变量;例如,make CFLAGS="-Wall -Wextra -Os" clean all
使用不同的编译标志重新编译所有内容。