Reliable paste solution with pure Make:
override define \s := $() $() endef ifndef $(\s) override $(\s) := else $(error Defined special variable '$(\s)': reserved for internal use) endif override define dirname $(patsubst %/,%,$(dir $(patsubst %/,%,$1))) endef override define prefix_1 $(if $(or $\ $(patsubst $(abspath $3)%,,$(abspath $1)),$\ $(patsubst $(abspath $3)%,,$(abspath $2))),$\ $(strip $(call prefix_1,$1,$2,$(call dirname,$3))),$\ $(strip $(abspath $3))) endef override define prefix $(call prefix_1,$1,$2,$1) endef override define relpath_1 $(patsubst /%,%,$(subst $(\s),/,$(patsubst %,..,$(subst /,$(\s),$\ $(patsubst $3%,%,$(abspath $2)))))$\ $(patsubst $3%,%,$(abspath $1))) endef override define relpath $(call relpath_1,$1,$2,$(call prefix,$1,$2)) endef
Test cases:
$(info $(call prefix,/home/user,/home/user)) $(info $(call prefix,/home/user,/home/user/)) $(info $(call prefix,/home/user/,/home/user)) $(info $(call prefix,/home/user/,/home/user/)) $(info $(call relpath,/home/user,/home/user)) $(info $(call relpath,/home/user,/home/user/)) $(info $(call relpath,/home/user/,/home/user)) $(info $(call relpath,/home/user/,/home/user/)) $(info ----------------------------------------------------------------------) $(info $(call prefix,/home/user,/home/user/.local/share)) $(info $(call prefix,/home/user,/home/user/.local/share/)) $(info $(call prefix,/home/user/,/home/user/.local/share)) $(info $(call prefix,/home/user/,/home/user/.local/share/)) $(info $(call relpath,/home/user,/home/user/.local/share)) $(info $(call relpath,/home/user,/home/user/.local/share/)) $(info $(call relpath,/home/user/,/home/user/.local/share)) $(info $(call relpath,/home/user/,/home/user/.local/share/)) $(info ----------------------------------------------------------------------) $(info $(call prefix,/home/user/.config,/home/user/.local/share)) $(info $(call prefix,/home/user/.config,/home/user/.local/share/)) $(info $(call prefix,/home/user/.config/,/home/user/.local/share)) $(info $(call prefix,/home/user/.config/,/home/user/.local/share/)) $(info $(call relpath,/home/user/.config,/home/user/.local/share)) $(info $(call relpath,/home/user/.config,/home/user/.local/share/)) $(info $(call relpath,/home/user/.config/,/home/user/.local/share)) $(info $(call relpath,/home/user/.config/,/home/user/.local/share/)) $(info ----------------------------------------------------------------------) $(info $(call prefix,/home/user/.local/share,/home/user)) $(info $(call prefix,/home/user/.local/share,/home/user/)) $(info $(call prefix,/home/user/.local/share/,/home/user)) $(info $(call prefix,/home/user/.local/share/,/home/user/)) $(info $(call relpath,/home/user/.local/share,/home/user)) $(info $(call relpath,/home/user/.local/share,/home/user/)) $(info $(call relpath,/home/user/.local/share/,/home/user)) $(info $(call relpath,/home/user/.local/share/,/home/user/)) $(info ----------------------------------------------------------------------) $(info $(call prefix,/home/user/.local/share,/home/user/.config)) $(info $(call prefix,/home/user/.local/share,/home/user/.config/)) $(info $(call prefix,/home/user/.local/share/,/home/user/.config)) $(info $(call prefix,/home/user/.local/share/,/home/user/.config/)) $(info $(call relpath,/home/user/.local/share,/home/user/.config)) $(info $(call relpath,/home/user/.local/share,/home/user/.config/)) $(info $(call relpath,/home/user/.local/share/,/home/user/.config)) $(info $(call relpath,/home/user/.local/share/,/home/user/.config/)) $(info ----------------------------------------------------------------------) $(info $(call prefix,/root,/home/user)) $(info $(call prefix,/root,/home/user/)) $(info $(call prefix,/root/,/home/user)) $(info $(call prefix,/root/,/home/user/)) $(info $(call relpath,/root,/home/user)) $(info $(call relpath,/root,/home/user/)) $(info $(call relpath,/root/,/home/user)) $(info $(call relpath,/root/,/home/user/))
Expected results:
/home/user /home/user /home/user /home/user ---------------------------------------------------------------------- /home/user /home/user /home/user /home/user ../.. ../.. ../.. ../.. ---------------------------------------------------------------------- /home/user /home/user /home/user /home/user ../../.config ../../.config ../../.config ../../.config ---------------------------------------------------------------------- /home/user /home/user /home/user /home/user .local/share .local/share .local/share .local/share ---------------------------------------------------------------------- /home/user /home/user /home/user /home/user ../.local/share ../.local/share ../.local/share ../.local/share ---------------------------------------------------------------------- ../../root ../../root ../../root ../../root