سؤال

I'm having trouble using the ln command in a makefile.

This is a part of my makefile for creating a dynamic library:

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 are my .o files.

I'm trying to create the links next to libNet.so.1.0 which is in dynamic_library/ .

The ln commands create broken links with incomplete target addresses but in the correct destination.

I've tried adding ./ and / before the sources but they don't work.

Any help would be appreciated

EDIT found the answer through trial and error

apparently we're supposed to add ../ before the sources. I have no idea why though.

if anybody has a better way, please answer.

هل كانت مفيدة؟

المحلول

Some of the variations of ln command are:

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

But the following, which you were trying to use, is not one of them:

ln -s rel_path_from_current_dir_to_link_target ...

Your makefile has another subtle error, namely, the link source, does not depend on the changes to the link target, it only depends on the existence of the link target.

And another problem, is that you have a "side effect", when you are making $(DLIB) target. I am guessing you are a software eng, so you know that side effects are bad for parallelism, cause race conditions, and make code hard to read.

Also, one should always use automatic variables such as $@, and depend everything on the Makefile.

Finally, I am hoping that you know why you are using -f. Some of the responses above, including mine :), do not use it. It is very important in the Makefile context, don't drop it.

Bearing these points in mind, the cleanest and correct way to do this would be:

$(DLIB) $(DLIB).$(MAJOR): Makefile | $(DLIB).$(VERSION)
    ln -sf $(abspath $|) $@

نصائح أخرى

g++ -shared -Wl,-soname,$(DLIB).$(MAJOR) $^ -o $@

Isn't it supposed to be -Wl,-soname,$(DLIB).$(VERSION)?

ln -s creates a link at the destination location with a link target of your source path (not the full path the path you give the ln command). If your link destination is a directory below your source directory and you aren't using full paths to the source then you need the ../ so that the link target is ../source.file instead of source.file as that would make the link point to a file in the same directory.

Compare:

$ 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top