如何在Makefile中正确包含-Wl,-rpath,$ ORIGIN链接器参数?

dk1*_*k13 10 c++ linker makefile

我正在linux(Ubuntu 16.04)上准备一个c ++应用程序,使用了一些动态链接的poco库.我有项目文件夹,包括:include,bin,lib,src和build文件夹以及相关的Makefile.到目前为止,我使用了以下Makefile,它从/ usr/local/lib获取了库

CC := g++ 

# Folders
SRCDIR := src
BUILDDIR := build
TARGETDIR := bin

# Targets
EXECUTABLE := C++_APP
TARGET := $(TARGETDIR)/$(EXECUTABLE)

SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -c -Wall
INC := -I include -I /usr/local/include
LIB := -L /usr/local/lib -lPocoFoundation -lPocoNet -lPocoUtil 

$(TARGET): $(OBJECTS)
@echo " Linking..."
@echo " $(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB)

$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
@mkdir -p $(BUILDDIR)
@echo " $(CC) $(CFLAGS) $(INC) -c -o $@ $<"; $(CC) $(CFLAGS) $(INC) -c -o $@      $<

clean:
@echo " Cleaning..."; 
@echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET)

.PHONY: clean 
Run Code Online (Sandbox Code Playgroud)

现在我想在运行链接器时只在项目lib文件夹中搜索库而不更改LD_LIBRARY_PATH或编辑ld.so.conf.所以我搜索了一下,发现这可以通过链接器参数-Wl,rpath,$ ORIGIN来实现.所以我假设我需要添加以下语句

LDFLAGS := -Wl,-rpath,$ORIGIN/../lib
Run Code Online (Sandbox Code Playgroud)

并更改LIB语句如下:

LIB := -L $ORIGIN/../lib -lPocoFoundation -lPocoNet -lPocoUtil 
Run Code Online (Sandbox Code Playgroud)

但是它仍然从默认目录(usr/local/lib)获取库,因为我在项目lib文件夹中没有库测试它.我做错了什么?

Mad*_*ist 19

不,你是误会.您需要将文字字符串$ORIGIN/../lib作为参数传递给链接器.该$ORIGIN令牌保持你的程序里面创建之后,当运行时链接程序开始运行您的程序将取代$ORIGIN与你的程序是从调用当前路径.即使您已将程序复制到其他位置,也是如此.因此,如果您运行程序,/usr/local/bin/myprogram则运行时链接程序将替换$ORIGIN/usr/local/bin.如果将其复制到,/opt/mystuff/libexec/myprogram则运行时链接程序将替换$ORIGIN/opt/mystuff/libexec.

为了将文字传递给$make配方调用的命令,你必须$通过加倍来逃避:$$.否则,make会看到$引入make变量或函数.请记住,这是完全合法的make变量,以避免括号等,如果它是一个字符(注,$@,$<,等)

所以当你写-Wl,-rpath,$ORIGIN/../libmake时会将$Oin 解释$ORIGIN为扩展一个名为的变量O,它是空的,给你-Wl,-rpath,RIGIN/../lib.

你也必须$从shell中逃脱,否则它会尝试扩展$ORIGIN为你不想要的shell变量.

你想做这样的事情:

LDFLAGS = '-Wl,-rpath,$$ORIGIN/../lib' -L/usr/local/lib
LDLIBS = -lPocoFoundation -lPocoNet -lPocoUtil

$(TARGET): $(OBJECTS)
        @echo " Linking..."
        $(CC) $^ -o $@ $(LDFLAGS) $(LDLIBS)
Run Code Online (Sandbox Code Playgroud)

(我不知道为什么你使用@隐藏的命令,然后回显命令为什么不拿出@echo让让你表演的命令?)