如何修改Makefile强制链接本地预编译fftw3库?
问题描述
我在external_libs目录存放了预编译的fftw3库,通过自定义Makefile链接后,用ldd命令查看生成的.so文件,发现它依赖的是/usr/lib/x86_64-linux-gnu/下的系统fftw库,而非我指定的本地库。怎么修改Makefile才能强制生成的.so使用本地库?
现有Makefile代码
include config.h # Define the executable file MAIN = libmyfftw MAINC = LIBMYFFTW # Define the path VPATH = ../../src/fftw # Define the source and object files SRCS := $(shell find $(VPATH) -name '*.c') OBJS = $(SRCS:.c=.o) # Define import and export flags IMPORTFLAGS = EXPORTFLAGS = -DEXPORT_$(MAINC) # Define any directories containing header files other than /usr/include INCLUDES = -I$(INCDIR) # Define library paths in addition to /usr/lib LFLAGS = -L./ -L../../external_libs/linux/fftw # Define libraries to link into the executable ILIBS = -lfftw3_omp -lfftw3 -lfftw3f_omp -lfftw3f -lutils # Define all programs to build PROGS = $(MAIN).$(SHLE) all: $(PROGS) @echo "\n-------------------------------------------------------------------------------" @echo $(MAIN) has been compiled successfully @echo "-------------------------------------------------------------------------------\n" $(MAIN).$(SHLE): $(OBJS) $(LN) -o $(MAIN).$(SHLE) $(OBJS) $(LFLAGS) $(ILIBS) $(LIBS) .c.o: $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ install: $(PROGS) @-cp $(PROGS) $(BINDIR) @echo "\n-------------------------------------------------------------------------------" @echo "Finished $(MAIN) make install" @echo "-------------------------------------------------------------------------------\n" clean: @-rm $(PROGS) $(OBJS) @echo "\n-------------------------------------------------------------------------------" @echo "Finished $(MAIN) make clean" @echo "-------------------------------------------------------------------------------\n"
环境细节
- 本地库路径:
external_libs/linux/fftw,包含文件:libfftw3.a、libfftw3f.a、libfftw3f_omp.so、libfftw3_omp.so config.h相关配置:LIBS = -lm -lc -lz- 当前
ldd libmyfftw.so关键输出:
libfftw3_omp.so.3 => /usr/lib/x86_64-linux-gnu/libfftw3_omp.so.3 (0x00007fd5710d3000) libfftw3f_omp.so.3 => /usr/lib/x86_64-linux-gnu/libfftw3f_omp.so.3 (0x00007fd570ecc000) libfftw3.so.3 => /usr/lib/x86_64-linux-gnu/libfftw3.so.3 (0x00007fd57010c000) libfftw3f.so.3 => /usr/lib/x86_64-linux-gnu/libfftw3f.so.3 (0x00007fd56fae0000)
期望效果
fftw相关动态库路径指向本地库,例如:
libfftw3_omp.so => /path/to/external_libs/linux/fftw/libfftw3_omp.so (0x00007fd5710d3000)
解决方案
这是因为链接器运行时优先查找系统默认路径,且当前编译配置未将本地库路径嵌入到生成的.so中。可通过以下两种方式修改Makefile:
方法一:添加rpath参数(推荐)
rpath会把指定的库路径直接嵌入到.so文件里,让运行时加载器优先从该路径找依赖库。修改LFLAGS:
# 相对路径版本 LFLAGS = -L./ -L../../external_libs/linux/fftw -Wl,-rpath=../../external_libs/linux/fftw # 绝对路径版本(避免部署时路径变动问题) LFLAGS = -L./ -L$(CURDIR)/../../external_libs/linux/fftw -Wl,-rpath=$(CURDIR)/../../external_libs/linux/fftw
$(CURDIR)是Make内置变量,代表当前Makefile所在的绝对路径。
方法二:直接指定本地库文件(强制绑定)
如果不想依赖链接器的库名查找逻辑,直接把ILIBS里的库名替换成本地库的完整路径:
ILIBS = ../../external_libs/linux/fftw/libfftw3_omp.so \ ../../external_libs/linux/fftw/libfftw3.a \ ../../external_libs/linux/fftw/libfftw3f_omp.so \ ../../external_libs/linux/fftw/libfftw3f.a \ -lutils
这种方式会直接链接指定的文件,完全跳过系统库的查找。注意动态库(.so)要放在静态库(.a)前面。
验证修改
重新编译后,运行ldd libmyfftw.so查看依赖路径,应该已经指向本地external_libs目录。也可以用以下命令检查rpath是否正确嵌入:
readelf -d libmyfftw.so | grep rpath
内容的提问来源于stack exchange,提问作者mjswartz
相关产品推荐
相关产品推荐

