我正在努力设置 Makefile
用于为 C 库编译 Python 包装器。该文件的内容如下(出于信息安全原因更改了库名称)。行号仅供引用,不包含在文件数据本身中。
1 CC = gcc
2 CFLAGS = -Wall -fPIC -shared
3 EXAMPLE_LIB = example
4 PYTHON = /usr/include/python2.6
5 LIBS = -L./$(EXAMPLE_LIB) -lexample
6 INCLUDE = -I./$(EXAMPLE_LIB)/include -I$(PYTHON)
7 DEPS = test.h
8 OBJ = test.o
9 SHARED = test.so
10
11 .PHONY : build
12
13 all: build $(SHARED)
14
15 build:
16 ./$(EXAMPLE_LIB)/config shared
17 $(MAKE) -C $(EXAMPLE_LIB)
18
19 %.o: %.c $(DEPS)
20 $(CC) $(CFLAGS) $(INCLUDE) -c -o $@ $<
21
22 $(SHARED): $(OBJ)
23 $(CC) $(CFLAGS) $(LIBS) -o $@ $+
24
25 clean:
26 $(MAKE) clean -C $(EXAMPLE_LIB)
27 rm $(OBJ)
28 rm $(SHARED)
EXAMPLE_LIB
共享对象文件 example.so
正在正确编译并存在于 <project-directory>/example/example.so
并且第 3 方库的正确头文件存在于 <project-directory>/example/include
.
我遇到的问题是 example.so
的不同版本(功能较少)共享对象库安装在全局系统上并链接到我的库(test.so
)而不是本地(自编译)副本。这会导致 undefined symbol
尝试在 Python 中导入库时出错。
当我检查 test.so
使用 ldd
的共享对象库我看到了 /usr/lib64/example.so.1
正在加载而不是 <project-directory>/example/example.so
.或者演示:
[mike@tester myproject]$ ldd test.so
linux-vdso.so.1 => (0x00007fff803ff000)
example.so.1 => /usr/lib64/example.so.1 (0x00007f98700e8000)
libc.so.6 => /lib64/libc.so.6 (0x00007f986fd55000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f986fb50000)
libz.so.1 => /lib64/libz.so.1 (0x00007f986f93a000)
/lib64/ld-linux-x86-64.so.2 (0x0000003afda00000)
是否有一个选项可以传递给 GCC 以告诉它显式链接共享对象库的本地版本?
最佳答案
问题是 -L
只是在搜索路径中添加一个目录,而 -l
只是在搜索路径上的任意位置找到库。所以:
LIBS = -L./$(EXAMPLE_LIB) -lexample
... 可能会在 /usr/lib
、/usr/中寻找
、libexample.so
(或 libexample.a
!) local/lib/usr/lib64
等,在查看 ./example
之前。
参见 Link Options和 Options for Directory Search在 GCC 文档中了解详细信息。
如果您想明确指定一个库,只需将其路径传递给链接器即可:
LIBS = ./$(EXAMPLE_LIB)/libexample.so
正如文档明确指出的那样:
The only difference between using an -l option and specifying a file name is that -l surrounds library with ‘lib’ and ‘.a’ and searches several directories.
所以,如果您不想让它搜索多个目录,请不要使用-l
。
关于python - 显式链接本地共享对象库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16112310/