如何在Makefile中正确包含-Wl,-rpath,$ ORIGIN链接器参数? [英] How to include correctly -Wl,-rpath,$ORIGIN linker argument in a Makefile?

查看:2233
本文介绍了如何在Makefile中正确包含-Wl,-rpath,$ ORIGIN链接器参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm preparing a c++ app on linux (Ubuntu 16.04) with the use of a few poco libraries which I have dynamically linked. I have project folder that consists of : include, bin, lib , src and build folders and the relevant Makefile. So far I used the following Makefile which got the libraries from /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 

现在,我希望在运行链接器期间仅在项目lib文件夹中搜索库,而无需更改LD_LIBRARY_PATH或编辑ld.so.conf.因此,我进行了搜索,发现可以通过链接器参数-Wl,rpath,$ ORIGIN来实现.所以我假设我需要添加以下语句

Now I'd like during running the linker to search for libraries only in project lib folder without changing LD_LIBRARY_PATH or editing ld.so.conf. So I searched and I found that this can be achieved by the linker argument -Wl,rpath,$ORIGIN. So I assume that I need to add the following statement

LDFLAGS := -Wl,-rpath,$ORIGIN/../lib

,然后更改LIB语句,如下所示:

and change the the LIB statement as following:

LIB := -L $ORIGIN/../lib -lPocoFoundation -lPocoNet -lPocoUtil 

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

However it still get the libraries from the default directory (usr/local/lib) , since I tested it with no library on the project lib folder. What have I done wrong?

推荐答案

不,您误会了.您需要将文字字符串$ORIGIN/../lib作为参数传递给链接器. $ORIGIN令牌在创建之后保留在您的程序中,并且当运行时链接程序开始运行您的程序时,它将用调用程序的当前路径替换$ORIGIN.即使您已将程序复制到其他位置,也是如此.因此,如果您以/usr/local/bin/myprogram身份运行程序,则运行时链接程序会将$ORIGIN替换为/usr/local/bin.如果将其复制到/opt/mystuff/libexec/myprogram,则运行时链接程序会将$ORIGIN替换为/opt/mystuff/libexec.

No, you're misunderstanding. You need to pass the literal string $ORIGIN/../lib as an argument to your linker. The $ORIGIN token is kept inside your program after it's created and when the runtime linker starts to run your program it will replace $ORIGIN with the current path that your program was invoked from. This is true even if you've copied your program somewhere else. So if you run your program as /usr/local/bin/myprogram then the runtime linker will replace $ORIGIN with /usr/local/bin. If you copy it to /opt/mystuff/libexec/myprogram then the runtime linker will replace $ORIGIN with /opt/mystuff/libexec.

为了将文字$传递给make配方调用的命令,您必须通过将$加倍来对其进行转义:$$.否则,make将$视为引入了make变量或函数.请记住,make变量避免使用括号等是完全合法的,如果 是单个字符(请注意,$@$<等)

In order to pass a literal $ to the command invoked by a make recipe, you have to escape the $ by doubling it: $$. Otherwise, make will see the $ as introducing a make variable or function. Remember, it's perfectly legal for a make variable to avoid the parentheses etc., if it's a single character (note, $@, $<, etc.)

因此,当您编写-Wl,-rpath,$ORIGIN/../lib时,make会将$ORIGIN中的$O解释为扩展名为O的变量,该变量为空,为您提供-Wl,-rpath,RIGIN/../lib.

So when you write -Wl,-rpath,$ORIGIN/../lib make will interpret the $O in $ORIGIN as expanding a variable named O, which is empty, giving you -Wl,-rpath,RIGIN/../lib.

此外,您还必须从外壳中转出$,否则它将尝试将$ORIGIN扩展为不需要的外壳变量.

Also you have to escape the $ from the shell, otherwise it will try to expand $ORIGIN as a shell variable which you don't want.

您想做这样的事情:

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

$(TARGET): $(OBJECTS)
        @echo " Linking..."
        $(CC) $^ -o $@ $(LDFLAGS) $(LDLIBS)

(我不知道您为什么使用@隐藏命令,然后回显命令...为什么不只取出@echo并让命令显示出来?)

(I don't know why you use @ to hide the command, then echo the command... why not just take out the @ and the echo and let make show you the command?)

这篇关于如何在Makefile中正确包含-Wl,-rpath,$ ORIGIN链接器参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆