{"thread":{"id":"54025","subject":"[BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","startedAt":"2020-08-12T08:16:13Z","lastAt":"2020-08-17T17:06:40Z","messageCount":9,"participants":["Alexander Ost","Eric Sunshine","Junio C Hamano","Đoàn Trần Công Danh"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"403437","messageId":"CAGNCYk3hGWHuSb4vDzrBE54P5y6Sm+TwfVrCfHD0LnLQWSr9nA@mail.gmail.com","threadId":"54025","inReplyTo":null,"subject":"[BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Alexander Ost","fromEmail":"ost@ieee.org","sentAt":"2020-08-12T08:15:55Z","receivedAt":"2020-08-12T08:16:13Z","isPatch":false,"sender":{"key":"ost@ieee.org","avatar":null},"body":"Hello,\n\nI tried to install git on a filesystem that does not support hard\nlinks (specifically, on a Linux bind mount).\n\nDespite installing with `make NO_INSTALL_HARDLINKS=1 install', the\ninstallation process tries to create hard links, and the installation\nfails (a quick workaround is `sed -i git-gui/Makefile -e \"s/ln /ln -s\n/g\"').\n\nHere's the bugreport:\n\nvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\nThank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n./configure --prefix=/filesystem_without_hardlink_support\nmake\nmake NO_INSTALL_HARDLINKS=1 install\n\nWhat did you expect to happen? (Expected behavior)\nSuccessful installation.\n\nWhat happened instead? (Actual behavior)\nInstallation fails with error\n  ln: failed to create hard link\n‘/filesystem_without_hardlink_support/libexec/git-core/git-citool’ =>\n‘/filesystem_without_hardlink_support/libexec/git-core/git-gui’:\nOperation not permitted\n\nWhat's different between what you expected and what actually happened?\nThe makefile `git-gui/Makefile' tries to create hard links. This is\nnot expected when running `make NO_INSTALL_HARDLINKS=1 install'\n\nAnything else you want to add:\n\nPlease review the rest of the bug report below.\nYou can delete any lines you don't wish to share.\n\n[System Info]\ngit version:\ngit version 2.27.0\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nuname: Linux 3.10.0-957.10.1.el7.x86_64 #1 SMP Mon Mar 18 15:06:45 UTC\n2019 x86_64\ncompiler info: gnuc: 4.8\nlibc info: glibc: 2.17\n\n\n[Enabled Hooks]\nnot run from a git repository - no hooks to show\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThanks for checking this!\n\nBest,\n/alex\n"},{"id":"403594","messageId":"CAPig+cQnGUyM2cwNjDm_zys15B9n82QT6-RD7Lgyz1-XSGp8yw@mail.gmail.com","threadId":"54025","inReplyTo":"CAGNCYk3hGWHuSb4vDzrBE54P5y6Sm+TwfVrCfHD0LnLQWSr9nA@mail.gmail.com","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2020-08-13T21:45:38Z","receivedAt":"2020-08-13T21:45:52Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Aug 12, 2020 at 4:16 AM Alexander Ost <ost@ieee.org> wrote:\n> Despite installing with `make NO_INSTALL_HARDLINKS=1 install', the\n> installation process tries to create hard links, and the installation\n> fails (a quick workaround is `sed -i git-gui/Makefile -e \"s/ln /ln -s\n> /g\"').\n>\n> make NO_INSTALL_HARDLINKS=1 install\n> ln: failed to create hard link\n> ‘/filesystem_without_hardlink_support/libexec/git-core/git-citool’ =>\n> ‘/filesystem_without_hardlink_support/libexec/git-core/git-gui’:\n> Operation not permitted\n\nIndeed, it appears that the git-gui Makefile does not respect\nNO_INSTALL_HARDLINKS. The git-gui project is maintained and developed\noutside of the Git project (even though it gets bundled with Git), so\nit has its own issue tracker. It would probably be best to re-submit\nthis bug report there:\n\nhttps://github.com/prati0100/git-gui/issues\n\nThanks.\n"},{"id":"403595","messageId":"xmqqimdm1ae6.fsf@gitster.c.googlers.com","threadId":"54025","inReplyTo":"CAPig+cQnGUyM2cwNjDm_zys15B9n82QT6-RD7Lgyz1-XSGp8yw@mail.gmail.com","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-13T21:52:33Z","receivedAt":"2020-08-13T21:52:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> On Wed, Aug 12, 2020 at 4:16 AM Alexander Ost <ost@ieee.org> wrote:\n>> Despite installing with `make NO_INSTALL_HARDLINKS=1 install', the\n>> installation process tries to create hard links, and the installation\n>> fails (a quick workaround is `sed -i git-gui/Makefile -e \"s/ln /ln -s\n>> /g\"').\n>>\n>> make NO_INSTALL_HARDLINKS=1 install\n>> ln: failed to create hard link\n>> ‘/filesystem_without_hardlink_support/libexec/git-core/git-citool’ =>\n>> ‘/filesystem_without_hardlink_support/libexec/git-core/git-gui’:\n>> Operation not permitted\n>\n> Indeed, it appears that the git-gui Makefile does not respect\n> NO_INSTALL_HARDLINKS. The git-gui project is maintained and developed\n> outside of the Git project (even though it gets bundled with Git), so\n> it has its own issue tracker. It would probably be best to re-submit\n> this bug report there:\n>\n> https://github.com/prati0100/git-gui/issues\n\nThanks.  Perhaps something along this line (which is totally\nuntested), as the top-level Makefile already exports\nNO_INSTALL_HARDLINKS to submakes?\n\n\n\n Makefile | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex f10caedaa7..1cdbf8e504 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -44,6 +44,11 @@ endif\n ifndef INSTALL\n \tINSTALL = install\n endif\n+ifdef NO_INSTALL_HARDLINKS\n+\tLN = cp\n+else\n+\tLN = ln\n+endif\n \n RM_RF     ?= rm -rf\n RMDIR     ?= rmdir\n@@ -57,7 +62,7 @@ INSTALL_X1 =\n INSTALL_A0 = find # space is required here\n INSTALL_A1 = | cpio -pud\n INSTALL_L0 = rm -f # space is required here\n-INSTALL_L1 = && ln # space is required here\n+INSTALL_L1 = && $(LN) # space is required here\n INSTALL_L2 =\n INSTALL_L3 =\n \n@@ -87,7 +92,7 @@ ifndef V\n \tINSTALL_L0 = dst=\n \tINSTALL_L1 = && src=\n \tINSTALL_L2 = && dst=\n-\tINSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && ln \"$$src\" \"$$dst\"\n+\tINSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && $(LN) \"$$src\" \"$$dst\"\n \n \tCLEAN_DST = echo ' ' UNINSTALL\n \tREMOVE_D0 = dir=\n"},{"id":"403635","messageId":"CAGNCYk2Mc83wsX1FRQZe9kCDFAN1OM6F8_pJ29CWWCoQ0Hf_Qg@mail.gmail.com","threadId":"54025","inReplyTo":"xmqqimdm1ae6.fsf@gitster.c.googlers.com","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Alexander Ost","fromEmail":"ost@ieee.org","sentAt":"2020-08-14T08:33:55Z","receivedAt":"2020-08-14T08:34:13Z","isPatch":false,"sender":{"key":"ost@ieee.org","avatar":null},"body":"Thanks, I'll check it out.\n\nCreated a git-gui bug report (#41,\nhttps://github.com/prati0100/git-gui/issues/41).\n\nOn Thu, Aug 13, 2020 at 11:52 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Eric Sunshine <sunshine@sunshineco.com> writes:\n>\n> > On Wed, Aug 12, 2020 at 4:16 AM Alexander Ost <ost@ieee.org> wrote:\n> >> Despite installing with `make NO_INSTALL_HARDLINKS=1 install', the\n> >> installation process tries to create hard links, and the installation\n> >> fails (a quick workaround is `sed -i git-gui/Makefile -e \"s/ln /ln -s\n> >> /g\"').\n> >>\n> >> make NO_INSTALL_HARDLINKS=1 install\n> >> ln: failed to create hard link\n> >> ‘/filesystem_without_hardlink_support/libexec/git-core/git-citool’ =>\n> >> ‘/filesystem_without_hardlink_support/libexec/git-core/git-gui’:\n> >> Operation not permitted\n> >\n> > Indeed, it appears that the git-gui Makefile does not respect\n> > NO_INSTALL_HARDLINKS. The git-gui project is maintained and developed\n> > outside of the Git project (even though it gets bundled with Git), so\n> > it has its own issue tracker. It would probably be best to re-submit\n> > this bug report there:\n> >\n> > https://github.com/prati0100/git-gui/issues\n>\n> Thanks.  Perhaps something along this line (which is totally\n> untested), as the top-level Makefile already exports\n> NO_INSTALL_HARDLINKS to submakes?\n>\n>\n>\n>  Makefile | 9 +++++++--\n>  1 file changed, 7 insertions(+), 2 deletions(-)\n>\n> diff --git a/Makefile b/Makefile\n> index f10caedaa7..1cdbf8e504 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -44,6 +44,11 @@ endif\n>  ifndef INSTALL\n>         INSTALL = install\n>  endif\n> +ifdef NO_INSTALL_HARDLINKS\n> +       LN = cp\n> +else\n> +       LN = ln\n> +endif\n>\n>  RM_RF     ?= rm -rf\n>  RMDIR     ?= rmdir\n> @@ -57,7 +62,7 @@ INSTALL_X1 =\n>  INSTALL_A0 = find # space is required here\n>  INSTALL_A1 = | cpio -pud\n>  INSTALL_L0 = rm -f # space is required here\n> -INSTALL_L1 = && ln # space is required here\n> +INSTALL_L1 = && $(LN) # space is required here\n>  INSTALL_L2 =\n>  INSTALL_L3 =\n>\n> @@ -87,7 +92,7 @@ ifndef V\n>         INSTALL_L0 = dst=\n>         INSTALL_L1 = && src=\n>         INSTALL_L2 = && dst=\n> -       INSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && ln \"$$src\" \"$$dst\"\n> +       INSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && $(LN) \"$$src\" \"$$dst\"\n>\n>         CLEAN_DST = echo ' ' UNINSTALL\n>         REMOVE_D0 = dir=\n\n\n\n-- \n-- \nDr. Alexander Ost            | email: ost@ieee.org\nPerformance Consulting       | fon:   +49 (0)241 51859-230\nJahnstr. 11 / D-52066 Aachen | mobil: +49 (0)178 5431550\n"},{"id":"403670","messageId":"20200814150214.GC9518@danh.dev","threadId":"54025","inReplyTo":"xmqqimdm1ae6.fsf@gitster.c.googlers.com","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Đoàn Trần Công Danh","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-08-14T15:02:14Z","receivedAt":"2020-08-14T15:02:20Z","isPatch":false,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-08-13 14:52:33-0700, Junio C Hamano <gitster@pobox.com> wrote:\n> Eric Sunshine <sunshine@sunshineco.com> writes:\n> \n> > On Wed, Aug 12, 2020 at 4:16 AM Alexander Ost <ost@ieee.org> wrote:\n> >> Despite installing with `make NO_INSTALL_HARDLINKS=1 install', the\n> >> installation process tries to create hard links, and the installation\n> >> fails (a quick workaround is `sed -i git-gui/Makefile -e \"s/ln /ln -s\n> >> /g\"').\n> >>\n> >> make NO_INSTALL_HARDLINKS=1 install\n> >> ln: failed to create hard link\n> >> ‘/filesystem_without_hardlink_support/libexec/git-core/git-citool’ =>\n> >> ‘/filesystem_without_hardlink_support/libexec/git-core/git-gui’:\n> >> Operation not permitted\n> >\n> > Indeed, it appears that the git-gui Makefile does not respect\n> > NO_INSTALL_HARDLINKS. The git-gui project is maintained and developed\n> > outside of the Git project (even though it gets bundled with Git), so\n> > it has its own issue tracker. It would probably be best to re-submit\n> > this bug report there:\n> >\n> > https://github.com/prati0100/git-gui/issues\n> \n> Thanks.  Perhaps something along this line (which is totally\n> untested), as the top-level Makefile already exports\n> NO_INSTALL_HARDLINKS to submakes?\n> \n> \n> \n>  Makefile | 9 +++++++--\n>  1 file changed, 7 insertions(+), 2 deletions(-)\n> \n> diff --git a/Makefile b/Makefile\n> index f10caedaa7..1cdbf8e504 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -44,6 +44,11 @@ endif\n>  ifndef INSTALL\n>  \tINSTALL = install\n>  endif\n> +ifdef NO_INSTALL_HARDLINKS\n> +\tLN = cp\n\nSince both git-citool and git-gui will be installed into same\ndirectory \"$(libexecdir)\", I think it would make more sense to use:\n\n\tLN = ln -s\n\nhere instead?\n\n> +else\n> +\tLN = ln\n> +endif\n>  \n>  RM_RF     ?= rm -rf\n>  RMDIR     ?= rmdir\n> @@ -57,7 +62,7 @@ INSTALL_X1 =\n>  INSTALL_A0 = find # space is required here\n>  INSTALL_A1 = | cpio -pud\n>  INSTALL_L0 = rm -f # space is required here\n> -INSTALL_L1 = && ln # space is required here\n> +INSTALL_L1 = && $(LN) # space is required here\n>  INSTALL_L2 =\n>  INSTALL_L3 =\n>  \n> @@ -87,7 +92,7 @@ ifndef V\n>  \tINSTALL_L0 = dst=\n>  \tINSTALL_L1 = && src=\n>  \tINSTALL_L2 = && dst=\n> -\tINSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && ln \"$$src\" \"$$dst\"\n> +\tINSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && $(LN) \"$$src\" \"$$dst\"\n>  \n>  \tCLEAN_DST = echo ' ' UNINSTALL\n>  \tREMOVE_D0 = dir=\n\n-- \nDanh\n"},{"id":"403688","messageId":"xmqqo8ndxhof.fsf@gitster.c.googlers.com","threadId":"54025","inReplyTo":"20200814150214.GC9518@danh.dev","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-14T17:26:24Z","receivedAt":"2020-08-14T17:26:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Đoàn Trần Công Danh  <congdanhqx@gmail.com> writes:\n\n>> Thanks.  Perhaps something along this line (which is totally\n>> untested), as the top-level Makefile already exports\n>> NO_INSTALL_HARDLINKS to submakes?\n>> \n>> \n>> \n>>  Makefile | 9 +++++++--\n>>  1 file changed, 7 insertions(+), 2 deletions(-)\n>> \n>> diff --git a/Makefile b/Makefile\n>> index f10caedaa7..1cdbf8e504 100644\n>> --- a/Makefile\n>> +++ b/Makefile\n>> @@ -44,6 +44,11 @@ endif\n>>  ifndef INSTALL\n>>  \tINSTALL = install\n>>  endif\n>> +ifdef NO_INSTALL_HARDLINKS\n>> +\tLN = cp\n>\n> Since both git-citool and git-gui will be installed into same\n> directory \"$(libexecdir)\", I think it would make more sense to use:\n>\n> \tLN = ln -s\n>\n> here instead?\n\nIn the top-level Makefile, INSTALL_SYMLINKS make macro does exist,\nbut it is not exported to submakes.  If it were, something like\n\n    ifdef INSTALL_SYMLINKS\n\tLN = ln -s\n    else\n    ifdef NO_INSTALL_HARDLINKS\n\tLN = cp\n    else\n\tLN = ln\n    endif\n    endif\n\nmight become possible, but you'd need to audit what is fed to $(LN)\nat the locations the macro is used and make necessary adjustment\naccordingly.  \"cp A ../B\" or \"ln A ../B\" will make a usable copy of\nfile A appear inside ../B directory, but \"ln -s A ../B\" will not,\nand I didn't see if all uses of $(LN) was to give synonyms to what\nis already installed, or some of them were truly installing from the\nbuild location when I gave the \"something along this line\" example.\n\n\n\n"},{"id":"403743","messageId":"20200815011544.GB12363@danh.dev","threadId":"54025","inReplyTo":"xmqqo8ndxhof.fsf@gitster.c.googlers.com","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Đoàn Trần Công Danh","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-08-15T01:15:56Z","receivedAt":"2020-08-15T21:53:51Z","isPatch":false,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-08-14 10:26:24-0700, Junio C Hamano <gitster@pobox.com> wrote:\n> > Since both git-citool and git-gui will be installed into same\n> > directory \"$(libexecdir)\", I think it would make more sense to use:\n> >\n> > \tLN = ln -s\n> >\n> > here instead?\n> \n> In the top-level Makefile, INSTALL_SYMLINKS make macro does exist,\n> but it is not exported to submakes.  If it were, something like\n> \n>     ifdef INSTALL_SYMLINKS\n> \tLN = ln -s\n>     else\n>     ifdef NO_INSTALL_HARDLINKS\n> \tLN = cp\n>     else\n> \tLN = ln\n>     endif\n>     endif\n> \n> might become possible, but you'd need to audit what is fed to $(LN)\n> at the locations the macro is used and make necessary adjustment\n> accordingly.  \"cp A ../B\" or \"ln A ../B\" will make a usable copy of\n> file A appear inside ../B directory, but \"ln -s A ../B\" will not,\n> and I didn't see if all uses of $(LN) was to give synonyms to what\n> is already installed, or some of them were truly installing from the\n> build location when I gave the \"something along this line\" example.\n\nYes, the top-level Makefile seems to have a special branch for\nBUILT_INS, in which, we will create symlink for those builtin in\nlibexecdr if NO_INSTALL_HARDLINKS is defined.\n\nI was aiming for something like this to make git-gui a bit more\nconsistent with top-level Git, with or without INSTALL_SYMLINKS\nexported:\n\n----------8<--------\ndiff --git a/git-gui/Makefile b/git-gui/Makefile\nindex f10caedaa7..1a7d4b5075 100644\n--- a/git-gui/Makefile\n+++ b/git-gui/Makefile\n@@ -48,6 +48,13 @@ endif\n RM_RF     ?= rm -rf\n RMDIR     ?= rmdir\n \n+ifneq (,$(NO_INSTALL_HARDLINKS)$(INSTALL_SYMLINKS))\n+\tSAMEDIR_LN = ln -s\n+else\n+\tSAMEDIR_LN = ln\n+endif\n+\n+\n INSTALL_D0 = $(INSTALL) -d -m 755 # space is required here\n INSTALL_D1 =\n INSTALL_R0 = $(INSTALL) -m 644 # space is required here\n@@ -57,7 +64,7 @@ INSTALL_X1 =\n INSTALL_A0 = find # space is required here\n INSTALL_A1 = | cpio -pud\n INSTALL_L0 = rm -f # space is required here\n-INSTALL_L1 = && ln # space is required here\n+INSTALL_L1 = && $(SAMEDIR_LN) # space is required here\n INSTALL_L2 =\n INSTALL_L3 =\n \n@@ -87,7 +94,7 @@ ifndef V\n \tINSTALL_L0 = dst=\n \tINSTALL_L1 = && src=\n \tINSTALL_L2 = && dst=\n-\tINSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && ln \"$$src\" \"$$dst\"\n+\tINSTALL_L3 = && echo '   ' 'LINK       ' `basename \"$$dst\"` '->' `basename \"$$src\"` && rm -f \"$$dst\" && $(SAMEDIR_LN) \"$$src\" \"$$dst\"\n \n \tCLEAN_DST = echo ' ' UNINSTALL\n \tREMOVE_D0 = dir=\n@@ -127,6 +134,12 @@ TCL_PATH_SQ = $(subst ','\\'',$(TCL_PATH))\n TCLTK_PATH_SQ = $(subst ','\\'',$(TCLTK_PATH))\n TCLTK_PATH_SED = $(subst ','\\'',$(subst \\,\\\\,$(TCLTK_PATH)))\n \n+ifneq (,$(NO_INSTALL_HARDLINKS)$(INSTALL_SYMLINKS))\n+\tgitexecdir_SQ_for_LN =\n+else\n+\tgitexecdir_SQ_for_LN = $(DESTDIR_SQ)$(gitexecdir_SQ)/\n+endif\n+\n gg_libdir ?= $(sharedir)/git-gui/lib\n libdir_SQ  = $(subst ','\\'',$(gg_libdir))\n libdir_SED = $(subst ','\\'',$(subst \\,\\\\,$(gg_libdir_sed_in)))\n@@ -293,7 +306,7 @@ install: all\n \t$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1)\n \t$(QUIET)$(INSTALL_X0)git-gui $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'\n \t$(QUIET)$(INSTALL_X0)git-gui--askpass $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'\n-\t$(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(INSTALL_L0)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L1)'$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' $(INSTALL_L2)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L3) &&) true\n+\t$(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(INSTALL_L0)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L1)'$(gitexecdir_SQ_for_LN)git-gui' $(INSTALL_L2)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L3) &&) true\n ifdef GITGUI_WINDOWS_WRAPPER\n \t$(QUIET)$(INSTALL_R0)git-gui.tcl $(INSTALL_R1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'\n endif\n-------->8-----------\n\nGiven that, we also tried to make symlinks when NO_INSTALL_SYMLINKS is\ngiven, I think it's fine to assume that symlink should available on\nthose platform.\n\n-- \nDanh\n"},{"id":"403829","messageId":"xmqq8sed445k.fsf@gitster.c.googlers.com","threadId":"54025","inReplyTo":"20200815011544.GB12363@danh.dev","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-08-17T16:40:23Z","receivedAt":"2020-08-17T16:41:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Đoàn Trần Công Danh  <congdanhqx@gmail.com> writes:\n\n> On 2020-08-14 10:26:24-0700, Junio C Hamano <gitster@pobox.com> wrote:\n>> > Since both git-citool and git-gui will be installed into same\n>> > directory \"$(libexecdir)\", I think it would make more sense to use:\n>> >\n>> > \tLN = ln -s\n>> >\n>> > here instead?\n>> \n>> In the top-level Makefile, INSTALL_SYMLINKS make macro does exist,\n>> but it is not exported to submakes.  If it were, something like\n>> \n>>     ifdef INSTALL_SYMLINKS\n>> \tLN = ln -s\n>>     else\n>>     ifdef NO_INSTALL_HARDLINKS\n>> \tLN = cp\n>>     else\n>> \tLN = ln\n>>     endif\n>>     endif\n>> \n>> might become possible, but you'd need to audit what is fed to $(LN)\n>> at the locations the macro is used and make necessary adjustment\n>> accordingly.  \"cp A ../B\" or \"ln A ../B\" will make a usable copy of\n>> file A appear inside ../B directory, but \"ln -s A ../B\" will not,\n>> and I didn't see if all uses of $(LN) was to give synonyms to what\n>> is already installed, or some of them were truly installing from the\n>> build location when I gave the \"something along this line\" example.\n>\n> Yes, the top-level Makefile seems to have a special branch for\n> BUILT_INS, in which, we will create symlink for those builtin in\n> libexecdr if NO_INSTALL_HARDLINKS is defined.\n\nDid you mean pieces like this?\n\n\tfor p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \\\n\t\t$(RM) \"$$bindir/$$p\" && \\\n\t\ttest -n \"$(INSTALL_SYMLINKS)\" && \\\n\t\tln -s \"git$X\" \"$$bindir/$$p\" || \\\n\t\t{ test -z \"$(NO_INSTALL_HARDLINKS)\" && \\\n\t\t  ln \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n\t\t  ln -s \"git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n\t\t  cp \"$$bindir/git$X\" \"$$bindir/$$p\" || exit; } \\\n\tdone && \\\n\nThe symlinks happen ONLY when INSTALL_SYMLINKS is asked for.  Not\nall filesystems support symbolic links, hardlinks never suffer from\ndangling link problem, and often they are cheaper.\n\n> I was aiming for something like this to make git-gui a bit more\n> consistent with top-level Git, with or without INSTALL_SYMLINKS\n> exported:\n\nSo with or without optional INSTALL_SYMLINKS exported, what I gave\nyou is what is the most consistent with the top-level, that is, if\nINSTALL_SYMLINKS is there, we do \"ln -s\".  Otherwise, we check\nNO_INSTALL_HARDLINKS and we do either \"ln\" or \"cp\".\n"},{"id":"403832","messageId":"20200817170607.GA16630@danh.dev","threadId":"54025","inReplyTo":"xmqq8sed445k.fsf@gitster.c.googlers.com","subject":"Re: [BUG] `make install' partly ignores `NO_INSTALL_HARDLINKS'","fromName":"Đoàn Trần Công Danh","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-08-17T17:06:07Z","receivedAt":"2020-08-17T17:06:40Z","isPatch":false,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-08-17 09:40:23-0700, Junio C Hamano <gitster@pobox.com> wrote:\n> Đoàn Trần Công Danh  <congdanhqx@gmail.com> writes:\n> \n> > On 2020-08-14 10:26:24-0700, Junio C Hamano <gitster@pobox.com> wrote:\n> >> > Since both git-citool and git-gui will be installed into same\n> >> > directory \"$(libexecdir)\", I think it would make more sense to use:\n> >> >\n> >> > \tLN = ln -s\n> >> >\n> >> > here instead?\n> >> \n> >> In the top-level Makefile, INSTALL_SYMLINKS make macro does exist,\n> >> but it is not exported to submakes.  If it were, something like\n> >> \n> >>     ifdef INSTALL_SYMLINKS\n> >> \tLN = ln -s\n> >>     else\n> >>     ifdef NO_INSTALL_HARDLINKS\n> >> \tLN = cp\n> >>     else\n> >> \tLN = ln\n> >>     endif\n> >>     endif\n> >> \n> >> might become possible, but you'd need to audit what is fed to $(LN)\n> >> at the locations the macro is used and make necessary adjustment\n> >> accordingly.  \"cp A ../B\" or \"ln A ../B\" will make a usable copy of\n> >> file A appear inside ../B directory, but \"ln -s A ../B\" will not,\n> >> and I didn't see if all uses of $(LN) was to give synonyms to what\n> >> is already installed, or some of them were truly installing from the\n> >> build location when I gave the \"something along this line\" example.\n> >\n> > Yes, the top-level Makefile seems to have a special branch for\n> > BUILT_INS, in which, we will create symlink for those builtin in\n> > libexecdr if NO_INSTALL_HARDLINKS is defined.\n> \n> Did you mean pieces like this?\n> \n> \tfor p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \\\n> \t\t$(RM) \"$$bindir/$$p\" && \\\n> \t\ttest -n \"$(INSTALL_SYMLINKS)\" && \\\n> \t\tln -s \"git$X\" \"$$bindir/$$p\" || \\\n> \t\t{ test -z \"$(NO_INSTALL_HARDLINKS)\" && \\\n> \t\t  ln \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n> \t\t  ln -s \"git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n> \t\t  cp \"$$bindir/git$X\" \"$$bindir/$$p\" || exit; } \\\n> \tdone && \\\n\nYes, I meant this piece.\n\n> The symlinks happen ONLY when INSTALL_SYMLINKS is asked for.\n\nNot what I understand from that code.\nWhen `INSTALL_SYMLINKS` is not asked, the shell will jump to this block:\n\n \t\t{ test -z \"$(NO_INSTALL_HARDLINKS)\" && \\\n \t\t  ln \"$$bindir/git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n \t\t  ln -s \"git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n \t\t  cp \"$$bindir/git$X\" \"$$bindir/$$p\" || exit; } \\\n\nWhen NO_INSTALL_HARDLINKS is asked, the shell will jump to last\n2 clauses:\n\n \t\t  ln -s \"git$X\" \"$$bindir/$$p\" 2>/dev/null || \\\n \t\t  cp \"$$bindir/git$X\" \"$$bindir/$$p\" || exit; } \\\n\nshell try to \"ln -s\" first, when it failed to symlink, cp will be used.\n\nIn fact, this's what we used for packaging in distro, we often ask for:\n\n\tNO_INSTALL_HARDLINKS\n\n> Not all filesystems support symbolic links,\n\nThis is correct, but most sane package manager will do the right thing.\n\n> hardlinks never suffer from\n> dangling link problem, and often they are cheaper.\n\nPart of the reason we don't ask for INSTALL_SYMLINKS,\nbecause with INSTALL_SYMLINKS, symlink will be make from\n$(libexecdir)/git to $(bindir)/git.\n\nBut, NO_INSTALL_HARDLINKS will only symlink inside $(libexecdir), e.g:\n\n\t$ ls -al $(/usr/bin/git --exec-path )/git\n\t-rwxr-xr-x 1 root root 3193704 2020-08-12 21:37 /usr/libexec/git-core/git\n\t$ ls -al $(/usr/bin/git --exec-path )/git-ls-files\n\tlrwxrwxrwx 1 root root 3 2020-08-12 21:37 /usr/libexec/git-core/git-ls-files -> git\n\nAnd those symlinks are packaged and managed by package manager,\nso, no, no dangling problem.\n\n\n-- \nDanh\n"}]}