我在makefile中使用ln命令时遇到了麻烦。
这是我创建动态库的makefile的一部分:
NAME := Net
DDIR := dynamic_library
DLIB := $(DDIR)/lib$(NAME).so
MAJOR := 1
MINOR := 0
VERSION := $(MAJOR).$(MINOR)
$(DLIB).$(VERSION): $(OBJD)
g++ -shared -Wl,-soname,$(DLIB).$(MAJOR) $^ -o $@
$(DLIB): $(DLIB).$(VERSION)
ln -sf $(DLIB).$(VERSION) $(DLIB)
ln -sf $(DLIB).$(VERSION) $(DLIB).$(MAJOR)
OBJD
是我的.o文件。
我正在尝试在dynamic_library /中的libNet.so.1.0旁边创建链接。
ln命令会创建具有不完整目标地址的断开链接,但位于正确的目标位置。
我尝试在源之前添加./
和/
,但它们不起作用。
任何帮助将不胜感激
修改 通过反复试验找到了答案
显然我们应该在消息来源之前添加../
。我不知道为什么。
如果有人有更好的方法,请回答。
答案 0 :(得分:1)
ln
命令的一些变体是:
ln -s abs_path_to_link_target rel_path_from_current_dir_to_link_source
ln -s rel_path_from_link_src_to_target rel_path_from_current_dir_to_link_source
但是您尝试使用的以下内容不是其中之一:
ln -s rel_path_from_current_dir_to_link_target ...
你的makefile有另一个微妙的错误,即链接源,不依赖于对链接目标的更改,它只取决于链接目标的存在。
另一个问题是,当你制作$(DLIB)
目标时,你会产生“副作用”。我猜你是一个软件工具,所以你知道副作用对并行性不利,导致竞争条件,并使代码难以阅读。
此外,应始终使用自动变量,例如$@
,并将所有内容都依赖于Makefile。
最后,我希望您知道为什么使用-f
。上面的一些回复,包括我的:),不使用它。它在Makefile上下文中非常重要,请不要删除它。
牢记这些要点,最简洁和正确的方法是:
$(DLIB) $(DLIB).$(MAJOR): Makefile | $(DLIB).$(VERSION)
ln -sf $(abspath $|) $@
答案 1 :(得分:0)
g++ -shared -Wl,-soname,$(DLIB).$(MAJOR) $^ -o $@
不应该是-Wl,-soname,$(DLIB).$(VERSION)
吗?
答案 2 :(得分:0)
ln -s
在目标位置创建一个链接,其中包含源路径的链接目标(而不是您为ln命令指定路径的完整路径)。如果您的链接目标是源目录下的目录,并且您没有使用源的完整路径,那么您需要../
,以便链接目标为../source.file
而不是source.file
这将使链接指向同一目录中的文件。
比较
$ ln -s bar foo
$ readlink foo
bar
$ readlink -f foo
/tmp/bar
$ ln -s ../bar foo
$ readlink foo
../bar
$ readlink -f foo
/foo
$ ln -s /tmp/bar foo
$ readlink foo
/tmp/bar
$ readlink -f foo
/tmp/bar