{"thread":{"id":"38508","subject":"[PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","startedAt":"2015-02-05T15:51:39Z","lastAt":"2015-02-05T22:44:55Z","messageCount":11,"participants":["Sebastian Schuberth","Kyle J. McKay","Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"255627","messageId":"CAHGBnuOGv4Zn7dz6voEMn=PtMfm=0TQumt9PxV9nYgXyB0Xj=g@mail.gmail.com","threadId":"38508","inReplyTo":null,"subject":"[PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Sebastian Schuberth","fromEmail":"sschuberth@gmail.com","sentAt":"2015-02-05T15:51:39Z","receivedAt":"2015-02-05T15:51:39Z","isPatch":true,"sender":{"key":"sschuberth@gmail.com","avatar":"https://avatars.githubusercontent.com/u/349154?v=4"},"body":"For consistency, we should use the same source for symbolic links as for\nhard links and copies.\n\nSigned-off-by: Sebastian Schuberth <sschuberth@gmail.com>\n---\n Makefile | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex c44eb3a..21f23cb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2265,14 +2265,14 @@ endif\n         $(RM) \"$$bindir/$$p\" && \\\n         test -z \"$(NO_INSTALL_HARDLINKS)\" && \\\n         ln \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n-        ln -s \"git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n+        ln -s \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n         cp \"$$bindir/git$X\" \"$$bindir/$$p\" || exit; \\\n     done && \\\n     for p in $(BUILT_INS); do \\\n         $(RM) \"$$execdir/$$p\" && \\\n         test -z \"$(NO_INSTALL_HARDLINKS)\" && \\\n         ln \"$$execdir/git$X\" \"$$execdir/$$p\" 2>/dev/null || \\\n-        ln -s \"git$X\" \"$$execdir/$$p\" 2>/dev/null || \\\n+        ln -s \"$$execdir/git$X\" \"$$execdir/$$p\" 2>/dev/null || \\\n         cp \"$$execdir/git$X\" \"$$execdir/$$p\" || exit; \\\n     done && \\\n     remote_curl_aliases=\"$(REMOTE_CURL_ALIASES)\" && \\\n@@ -2280,7 +2280,7 @@ endif\n         $(RM) \"$$execdir/$$p\" && \\\n         test -z \"$(NO_INSTALL_HARDLINKS)\" && \\\n         ln \"$$execdir/git-remote-http$X\" \"$$execdir/$$p\" 2>/dev/null || \\\n-        ln -s \"git-remote-http$X\" \"$$execdir/$$p\" 2>/dev/null || \\\n+        ln -s \"$$execdir/git-remote-http$X\" \"$$execdir/$$p\" 2>/dev/null || \\\n         cp \"$$execdir/git-remote-http$X\" \"$$execdir/$$p\" || exit; \\\n     done && \\\n     ./check_bindir \"z$$bindir\" \"z$$execdir\" \"$$bindir/git-add$X\"\n-- \n2.1.2-mingw-1\n"},{"id":"255633","messageId":"D060A1E5-DAF3-49D5-B0B3-F831BCDFD41F@gmail.com","threadId":"38508","inReplyTo":"CAHGBnuOGv4Zn7dz6voEMn=PtMfm=0TQumt9PxV9nYgXyB0Xj=g@mail.gmail.com","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Kyle J. McKay","fromEmail":"mackyle@gmail.com","sentAt":"2015-02-05T17:48:41Z","receivedAt":"2015-02-05T17:48:41Z","isPatch":true,"sender":{"key":"mackyle@gmail.com","avatar":"https://avatars.githubusercontent.com/u/813346?v=4"},"body":"On Feb 5, 2015, at 07:51, Sebastian Schuberth wrote:\n> For consistency, we should use the same source for symbolic links as  \n> for\n> hard links and copies.\n>\n> Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>\n> ---\n> Makefile | 6 +++---\n> 1 file changed, 3 insertions(+), 3 deletions(-)\n>\n> diff --git a/Makefile b/Makefile\n> index c44eb3a..21f23cb 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -2265,14 +2265,14 @@ endif\n>         $(RM) \"$$bindir/$$p\" && \\\n>         test -z \"$(NO_INSTALL_HARDLINKS)\" && \\\n>         ln \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n> -        ln -s \"git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n> +        ln -s \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n\nThis is wrong.\n\nCurrently with symlinks you will get installed into bindir something  \nlike this:\n\n   git\n   git-tag -> git\n   git-show -> git\n\netc.\n\nWith your change you would have\n\n   git\n   git-tag -> /usr/local/libexec/git-core/git\n   git-show -> /usr/local/libexec/git-core/git\n\nAnd I don't think we want that.  While those absolute path symlinks  \nare technically correct, what we have now is much simpler.  While  \nthere are a number of build-time paths hard-coded into the  \nexecutables, the binaries work for the most part if you relocate them  \nas a whole.  Your change totally breaks that.\n\n-Kyle\n"},{"id":"255642","messageId":"xmqqmw4skvrn.fsf@gitster.dls.corp.google.com","threadId":"38508","inReplyTo":"D060A1E5-DAF3-49D5-B0B3-F831BCDFD41F@gmail.com","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-02-05T19:23:24Z","receivedAt":"2015-02-05T19:23:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Kyle J. McKay\" <mackyle@gmail.com> writes:\n\n>> -        ln -s \"git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n>> +        ln -s \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n>\n> This is wrong.\n>\n> Currently with symlinks you will get installed into bindir something\n> like this:\n>\n>   git\n>   git-tag -> git\n>   git-show -> git\n>\n> etc.\n>\n> With your change you would have\n>\n>   git\n>   git-tag -> /usr/local/libexec/git-core/git\n>   git-show -> /usr/local/libexec/git-core/git\n>\n> And I don't think we want that.  While those absolute path symlinks\n> are technically correct,...\n\nIt is not even correct, is it?\n\nWhen DESTDIR is set to allow you to install into a temporary place\nonly so that you can \"tar\" up the resulting filesystem tree, bindir\npoints at the location we need to \"cp\" the built programs into, i.e.\ninside DESTDIR.\n"},{"id":"255643","messageId":"CAHGBnuP5e7NsDrD31otFGZiFYW-vxsOf7kV61=Zt32n3S78RBg@mail.gmail.com","threadId":"38508","inReplyTo":"xmqqmw4skvrn.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Sebastian Schuberth","fromEmail":"sschuberth@gmail.com","sentAt":"2015-02-05T19:26:08Z","receivedAt":"2015-02-05T19:26:08Z","isPatch":true,"sender":{"key":"sschuberth@gmail.com","avatar":"https://avatars.githubusercontent.com/u/349154?v=4"},"body":"On Thu, Feb 5, 2015 at 8:23 PM, Junio C Hamano <gitster@pobox.com> wrote:\n\n>> This is wrong.\n>>\n>> Currently with symlinks you will get installed into bindir something\n>> like this:\n>>\n>>   git\n>>   git-tag -> git\n>>   git-show -> git\n>>\n>> etc.\n>>\n>> With your change you would have\n>>\n>>   git\n>>   git-tag -> /usr/local/libexec/git-core/git\n>>   git-show -> /usr/local/libexec/git-core/git\n>>\n>> And I don't think we want that.  While those absolute path symlinks\n>> are technically correct,...\n>\n> It is not even correct, is it?\n>\n> When DESTDIR is set to allow you to install into a temporary place\n> only so that you can \"tar\" up the resulting filesystem tree, bindir\n> points at the location we need to \"cp\" the built programs into, i.e.\n> inside DESTDIR.\n\nAgreed folks, please disregard this as well as 2/2 of this series.\n\n-- \nSebastian Schuberth\n"},{"id":"255646","messageId":"20150205195143.GB15326@peff.net","threadId":"38508","inReplyTo":"CAHGBnuP5e7NsDrD31otFGZiFYW-vxsOf7kV61=Zt32n3S78RBg@mail.gmail.com","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-02-05T19:51:43Z","receivedAt":"2015-02-05T19:51:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 05, 2015 at 08:26:08PM +0100, Sebastian Schuberth wrote:\n\n> > It is not even correct, is it?\n> >\n> > When DESTDIR is set to allow you to install into a temporary place\n> > only so that you can \"tar\" up the resulting filesystem tree, bindir\n> > points at the location we need to \"cp\" the built programs into, i.e.\n> > inside DESTDIR.\n> \n> Agreed folks, please disregard this as well as 2/2 of this series.\n\nWe would still want an equivalent to 2/2 to set up a relative symlink\nfor $(ALL_PROGRAMS), though, right?\n\n-Peff\n"},{"id":"255652","messageId":"CAHGBnuPL7NN9J+4xd7xifsmbSPcC5V2ze05ji7P_qnvWHPGV+A@mail.gmail.com","threadId":"38508","inReplyTo":"20150205195143.GB15326@peff.net","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Sebastian Schuberth","fromEmail":"sschuberth@gmail.com","sentAt":"2015-02-05T20:29:04Z","receivedAt":"2015-02-05T20:29:04Z","isPatch":true,"sender":{"key":"sschuberth@gmail.com","avatar":"https://avatars.githubusercontent.com/u/349154?v=4"},"body":"On Thu, Feb 5, 2015 at 8:51 PM, Jeff King <peff@peff.net> wrote:\n\n> On Thu, Feb 05, 2015 at 08:26:08PM +0100, Sebastian Schuberth wrote:\n>\n>> > It is not even correct, is it?\n>> >\n>> > When DESTDIR is set to allow you to install into a temporary place\n>> > only so that you can \"tar\" up the resulting filesystem tree, bindir\n>> > points at the location we need to \"cp\" the built programs into, i.e.\n>> > inside DESTDIR.\n>>\n>> Agreed folks, please disregard this as well as 2/2 of this series.\n>\n> We would still want an equivalent to 2/2 to set up a relative symlink\n> for $(ALL_PROGRAMS), though, right?\n\nProbably. But I'm not sure how to calculate the relative path\ncorrectly so that it'll work with all possible bin / execdir\ncombinations. A simple\n\ndiff --git a/Makefile b/Makefile\nindex 21f23cb..d2849c3 100644\n\n--- a/Makefile\n+++ b/Makefile\n\n@@ -2258,8 +2258,8 @@\n\n endif\n ········$(RM)·\"$$execdir/$$p\"·&&·\\\n ········test·-z·\"$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)\"·&&·\\\n ········ln·\"$$bindir/$$p\"·\"$$execdir/$$p\"·2>/dev/null·||·\\\n+········ln·-s·\"../$$p\"·\"$$execdir/$$p\"·2>/dev/null·||·\\\n ········cp·\"$$bindir/$$p\"·\"$$execdir/$$p\"·||·exit;·\\\n ······done;·\\\n ····}·&&·\\\n--·\n\ndoes not seem to be correct in all cases.\n\n-- \nSebastian Schuberth\n"},{"id":"255653","messageId":"4CF52072-713F-4456-B894-B874B0EFFC6B@gmail.com","threadId":"38508","inReplyTo":"20150205195143.GB15326@peff.net","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Kyle J. McKay","fromEmail":"mackyle@gmail.com","sentAt":"2015-02-05T20:41:00Z","receivedAt":"2015-02-05T20:41:00Z","isPatch":true,"sender":{"key":"mackyle@gmail.com","avatar":"https://avatars.githubusercontent.com/u/813346?v=4"},"body":"On Feb 5, 2015, at 11:51, Jeff King wrote:\n> On Thu, Feb 05, 2015 at 08:26:08PM +0100, Sebastian Schuberth wrote:\n>\n>>> It is not even correct, is it?\n>>>\n>>> When DESTDIR is set to allow you to install into a temporary place\n>>> only so that you can \"tar\" up the resulting filesystem tree, bindir\n>>> points at the location we need to \"cp\" the built programs into, i.e.\n>>> inside DESTDIR.\n>>\n>> Agreed folks, please disregard this as well as 2/2 of this series.\n>\n> We would still want an equivalent to 2/2 to set up a relative symlink\n> for $(ALL_PROGRAMS), though, right?\n\nIt's this line here:\n\n>                 ln \"$$bindir/$$p\" \"$$execdir/$$p\" 2>/dev/null || \\\n\nBut since bindir and execdir can be configured to be arbitrary paths  \nyou must compute the relative path between them in order to create a  \nrelative symlink.  In principle you just remove the common directory  \nprefix, remove the non-directory part from the destination, change any  \nremaining directories in the destination to '..' and then append  \nwhat's left of the source to get the new source.\n\nSo if you have\n\n   bindir=/usr/local/bin\n   execdir=/usr/local/libexec/git-core\n\nAnd the ln line would be:\n\n   ln /usr/local/bin/git /usr/local/libexec/git-core/git\n\n1) Strip the common prefix which is /usr/local/\n\n   source = bin/git\n   dest = libexec/git-core/git\n\n2) remove non-directory part of dest (the basename part) and replace  \nremaining dirs with '..'\n\n   source = bin/git\n   dest = ../../\n\n3) append source to dest and you get\n\n   ../../bin/git\n\nSo the symlink line becomes:\n\n   ln -s ../../bin/git /usr/local/libexec/git-core/git\n\nNow, can you do that easily in a Makefile? ;)\n\nAnd lastly there's the issue of which should be the symlink and which  \nshould be the binary?\n\nShould /usr/local/bin/git be the symlink or the binary?\n\nIf it's the binary, then /usr/local/libexec/git-core/git will be a  \nsymlink to it.  But we're already installing several other symlinks to  \n'git' in /usr/local/libexec/git-core so they will need to traverse two  \nsymlinks to get to the binary rather than just the one.\n\nThat seems suboptimal.\n\nOn the other hand if /usr/local/bin/git becomes the symlink then we  \nhave a user-facing binary that's a symlink.  As generally it's the  \nbindir that ends up in the PATH.\n\nI'm not sure exactly why, but I think:\n\nOn Jan 30, 2015, at 13:10, Junio C Hamano wrote:\n> That would make me feel dirty.\n\n\nHaving a user-facing binary that is actually a symlink can potentially  \ncause problems on OS X if the binary it refers to locates its  \nlibraries using a relative path.  Not sure if that's the case on other  \nsystems or not.\n\nNeither of these is probably a show-stopper (two-symlinks-to-binary or  \nuser-facing-symlink-binary) assuming the magic relative symlink  \ncomputation can be worked out.\n\nBut it does not surprise me that those items were allowed to skip  \nmaking a symlink and just go directly to cp.\n\n-Kyle\n"},{"id":"255655","messageId":"20150205204534.GE15326@peff.net","threadId":"38508","inReplyTo":"CAHGBnuPL7NN9J+4xd7xifsmbSPcC5V2ze05ji7P_qnvWHPGV+A@mail.gmail.com","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-02-05T20:45:35Z","receivedAt":"2015-02-05T20:45:35Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 05, 2015 at 09:29:04PM +0100, Sebastian Schuberth wrote:\n\n> > We would still want an equivalent to 2/2 to set up a relative symlink\n> > for $(ALL_PROGRAMS), though, right?\n> \n> Probably. But I'm not sure how to calculate the relative path\n> correctly so that it'll work with all possible bin / execdir\n> combinations. A simple\n> \n> diff --git a/Makefile b/Makefile\n> index 21f23cb..d2849c3 100644\n> \n> --- a/Makefile\n> +++ b/Makefile\n> \n> @@ -2258,8 +2258,8 @@\n> \n>  endif\n>  ········$(RM)·\"$$execdir/$$p\"·&&·\\\n>  ········test·-z·\"$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)\"·&&·\\\n>  ········ln·\"$$bindir/$$p\"·\"$$execdir/$$p\"·2>/dev/null·||·\\\n> +········ln·-s·\"../$$p\"·\"$$execdir/$$p\"·2>/dev/null·||·\\\n>  ········cp·\"$$bindir/$$p\"·\"$$execdir/$$p\"·||·exit;·\\\n>  ······done;·\\\n>  ····}·&&·\\\n> --·\n> \n> does not seem to be correct in all cases.\n\nAh, I see. Yeah, you'd have to calculate that relative path between\n$bindir and $execdir. We have C code already to do that (see\nrelative_path() in path.c), so in theory you could build a wrapper\nduring the build phase and then run:\n\n  ln -s $(./my-wrapper \"$bindir\" \"$execdir\")/$p $execdir/$p\n\nor something during the install phase.\n\n-Peff\n"},{"id":"255656","messageId":"CAHGBnuM0uTDxRB1NZm0fxe2yLs-QoU1J+Txb8_o7zVdYahAdow@mail.gmail.com","threadId":"38508","inReplyTo":"20150205204534.GE15326@peff.net","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Sebastian Schuberth","fromEmail":"sschuberth@gmail.com","sentAt":"2015-02-05T20:52:44Z","receivedAt":"2015-02-05T20:52:44Z","isPatch":true,"sender":{"key":"sschuberth@gmail.com","avatar":"https://avatars.githubusercontent.com/u/349154?v=4"},"body":"On Thu, Feb 5, 2015 at 9:45 PM, Jeff King <peff@peff.net> wrote:\n\n>>  endif\n>>  ········$(RM)·\"$$execdir/$$p\"·&&·\\\n>>  ········test·-z·\"$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)\"·&&·\\\n>>  ········ln·\"$$bindir/$$p\"·\"$$execdir/$$p\"·2>/dev/null·||·\\\n>> +········ln·-s·\"../$$p\"·\"$$execdir/$$p\"·2>/dev/null·||·\\\n>>  ········cp·\"$$bindir/$$p\"·\"$$execdir/$$p\"·||·exit;·\\\n>>  ······done;·\\\n>>  ····}·&&·\\\n>> --·\n>>\n>> does not seem to be correct in all cases.\n>\n> Ah, I see. Yeah, you'd have to calculate that relative path between\n> $bindir and $execdir. We have C code already to do that (see\n> relative_path() in path.c), so in theory you could build a wrapper\n> during the build phase and then run:\n>\n>   ln -s $(./my-wrapper \"$bindir\" \"$execdir\")/$p $execdir/$p\n>\n> or something during the install phase.\n\nThanks for pointing out the C code to do that. But IMO creating and\nusing such a wrapper is not worth the effort.\n\n-- \nSebastian Schuberth\n"},{"id":"255657","messageId":"xmqqvbjgjcqw.fsf@gitster.dls.corp.google.com","threadId":"38508","inReplyTo":"4CF52072-713F-4456-B894-B874B0EFFC6B@gmail.com","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-02-05T20:59:35Z","receivedAt":"2015-02-05T20:59:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Kyle J. McKay\" <mackyle@gmail.com> writes:\n\n> Now, can you do that easily in a Makefile? ;)\n\nOr is it worth doing it?\n\nI do not mind a full symbolic link as long as it points at the\ncorrect place (Sebastian's version did not under DESTDIR which was\nthe only issue I had against it), but is there a good reason why we\nwould prefer a relative one (or we would want to avoid a full one)?\n\n> I'm not sure exactly why, but I think:\n>\n> On Jan 30, 2015, at 13:10, Junio C Hamano wrote:\n>> That would make me feel dirty.\n\nThat is a confusing style of quoting.  I suspect that I said the\nabove in a totally different context.\n\n> Having a user-facing binary that is actually a symlink can potentially\n> cause problems on OS X if the binary it refers to locates its\n> libraries using a relative path.\n\nI am not sure what problem you are trying to single out by repeating\n\"user-facing\" here.\n\nAs doing this is still fully supported:\n\n    $ PATH=$(git --exec-path):$PATH\n    $ export PATH\n    $ git-cat-file -t HEAD\n\nYou can arrange things in different ways:\n\n - /usr/libexec/git-core/git-cat-file can a symbolic link to\n   /usr/bin/git (cross directory)\n\n - /usr/libexec/git-core/git-cat-file can a symbolic link to \"git\"\n   (in the same directory) and then /usr/bin/git may be a symbolic\n   link to /usr/libexec/git-core/git (cross directory)\n\nNo matter what, as long as you have these two directories, you would\nhave the issue that a symbolic link that is given to execv(2) might\nmisbehave somewhere anyway, no?\n\nI do not know (and I am not quite sure if I want to know) how\nserious your \"potential\" problems would be, and I do not doubt you\nknow OS X quirks much better than I do and do not intend to argue\nthere aren't such problems.  I am just curious how \"user-facing\"\ncomes into the picture.\n"},{"id":"255663","messageId":"0BAD0471-1070-4520-9D09-CA816DECD59C@gmail.com","threadId":"38508","inReplyTo":"xmqqvbjgjcqw.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 1/2] Makefile: Use the same source directory for \"ln -s\" as for \"ln\" / \"cp\"","fromName":"Kyle J. McKay","fromEmail":"mackyle@gmail.com","sentAt":"2015-02-05T22:44:55Z","receivedAt":"2015-02-05T22:44:55Z","isPatch":true,"sender":{"key":"mackyle@gmail.com","avatar":"https://avatars.githubusercontent.com/u/813346?v=4"},"body":"On Feb 5, 2015, at 12:59, Junio C Hamano wrote:\n> I do not know (and I am not quite sure if I want to know) how\n> serious your \"potential\" problems would be, and I do not doubt you\n> know OS X quirks much better than I do and do not intend to argue\n> there aren't such problems.  I am just curious how \"user-facing\"\n> comes into the picture.\n\nSuppose you have built and installed some software to /usr/local and  \nit's ended up in the usual subdirectories, /usr/local/bin, /usr/local/ \nlib, etc.\n\nNow you get an installer for package X, and to avoid stepping on  \nthings it installs to /opt/XYZ with the usual suspects /opt/XYZ/bin, / \nopt/XYZ/lib.  There are several of these that I'm aware of where XYZ  \nis whatever package you're installing.\n\nNow since /opt/XYZ/bin is not usually in one's PATH it installs a few  \nselect symlinks from /usr/local/bin/whatever to /opt/XYZ/bin/ \nwhatever.  Not all of the /opt/XYZ installers do this, for some of  \nthem it's a selectable option.\n\nSo now we have:\n\n# This one can be a relative or absolute symlink, doesn't matter\n/usr/local/bin/foo -> /opt/XYZ/bin/foo\n\nAnd we also now have this:\n\n# A real binary, not a symlink\n# Uses and locates libfoo with ../lib/libfoo.dylib\n/opt/XYZ/bin/foo\n\n# A real library binary, not a symlink\n/opt/XYZ/lib/libfoo.dylib\n\nSo /opt/XYZ/bin/foo locates libfoo.dylib by using a relative path  \nembedded within it (in this case it would be @loader_path/../lib/ \nlibfoo.dylib).\n\nSo far, so good, right?\n\nNothing complicated going on.\n\nBut the user has built and installed an older version of libfoo  \nalready to /usr/local/lib/libfoo.dylib.\n\nAh-oh.\n\nUser attempts to run foo.\n\nShell finds foo at /usr/local/bin/foo and runs it.\n\nThe dynamic linker correctly loads /opt/XYZ/bin/foo and starts to  \nresolve the dynamic library links embedded in it.\n\nFor the \"@loader_path/../lib/libfoo.dylib\" one it first tries /usr/ \nlocal/bin/../lib/libfoo.dylib rather than /opt/XYZ/bin/foo/../lib/ \nlibfoo.dylib because /usr/local/bin/foo was the executable that was  \nrun and since the user has installed an older version of libfoo.dylib  \nin /usr/local/lib, it finds and loads that instead of the intended  \none.  If it didn't find that it would then try /opt/XYZ/bin/foo/../lib/ \nlibfoo.dylib and get the right one.\n\nSometimes you get an immediate error if the unintended library version  \nis just too old to be compatible.  On the other hand, if it's just old  \nenough to be buggy but not version incompatible now you're running  \nwith a buggy library or some other incompatibility that doesn't show  \nup right away.\n\nI think this is a nasty bug specific to OS X, the fact that it tries  \nboth paths though suggests it was deliberate.\n\nI have not tested all versions of OS X to see if it might have been  \nfixed in the latest, but there it is.\n\nIf you put /opt/XYZ/bin directly in the PATH this can't happen  \n(provided /opt/XYZ/bin/foo is not itself a symlink).\n\nSo that's how a user-facing binary that is a symlink can cause  \nproblems.  I suppose it's not just limited to user-facing binaries,  \nbut that's where it tends to show up as it seems the non-user-facing,  \nnon-executable stuff usually has a sufficiently controlled surrounds  \nthat they're not vulnerable.\n\nI say \"user-facing\" because the binary is found in the user's $PATH.   \nI do not consider the libexec/git-core binaries to be user-facing  \nsince they are not normally in the user's $PATH but rather  normally  \naccessed via the \"git\" binary which is likely in the user's $PATH.\n\nIn the case of Git, a /usr/local/bin/git -> ../libexec/git-core/git  \nsymlink should not be vulnerable to this problem, because even if the  \nexecutable ends up with some relative dylib paths in it (usually not  \nthe case) when applied to /usr/local/bin they're unlikely to lead  \nanywhere with user-installed libraries since git-core is one directory  \ndeeper than bin.\n\nAnyhow, that's why I tend to avoid putting symlink-to-binary stuff in  \nPATH.  In any case a packager can make adjustments to avoid the  \nproblem before creating an installer.\n\n-Kyle\n\nP.S.\n\nOn Feb 5, 2015, at 12:59, Junio C Hamano wrote:\n>> I'm not sure exactly why, but I think:\n>>\n>> On Jan 30, 2015, at 13:10, Junio C Hamano wrote:\n>>> That would make me feel dirty.\n>\n> That is a confusing style of quoting.  I suspect that I said the\n> above in a totally different context.\n\nBut I've been dying to work that in somehow ever since I saw that.  ;)\n"}]}