{"thread":{"id":"48256","subject":"[PATCH v8 0/5] RUNTIME_PREFIX relocatable Git","startedAt":"2018-04-10T15:06:07Z","lastAt":"2018-04-11T07:15:33Z","messageCount":8,"participants":["Dan Jacques","Junio C Hamano","Ævar Arnfjörð Bjarmason"],"isPatch":true,"patchVersion":8,"patchTotal":5},"messages":[{"id":"344352","messageId":"20180410150546.38062-1-dnj@google.com","threadId":"48256","inReplyTo":null,"subject":"[PATCH v8 0/5] RUNTIME_PREFIX relocatable Git","fromName":"Dan Jacques","fromEmail":"dnj@google.com","sentAt":"2018-04-10T15:05:41Z","receivedAt":"2018-04-10T15:06:07Z","isPatch":true,"sender":{"key":"dnj@google.com","avatar":"https://avatars.githubusercontent.com/u/9965104?v=4"},"body":"This is a minor update based on comments from the v6 series.\nI'm hoping this set is good to go!\n\nThis patch set expands support for the RUNTIME_PREFIX configuration flag,\ncurrently only used on Windows builds, to include Linux, Darwin, and\nFreeBSD. When Git is built with RUNTIME_PREFIX enabled, it resolves its\nancillary paths relative to the runtime location of its executable\nrather than hard-coding them at compile-time, allowing a Git\ninstallation to be deployed to a path other than the one in which it\nwas built/installed.\n\nNote that RUNTIME_PREFIX is not currently used outside of Windows.\nThis patch set should not have an impact on default Git builds.\n\nPrevious threads:\nv1: https://public-inbox.org/git/20171116170523.28696-1-dnj@google.com/\nv2: https://public-inbox.org/git/20171119173141.4896-1-dnj@google.com/\nv3: https://public-inbox.org/git/20171127164055.93283-1-dnj@google.com/\nv4: https://public-inbox.org/git/20171129223807.91343-1-dnj@google.com/\nv5: https://public-inbox.org/git/20180108030239.92036-1-dnj@google.com/\nv5: https://public-inbox.org/git/20180108030239.92036-1-dnj@google.com/\nv6: https://public-inbox.org/git/20180319025046.58052-1-dnj@google.com/\nv7: https://public-inbox.org/git/20180325205120.17730-1-dnj@google.com/\n\nChanges in v8 from v7:\n\n- Add Johannes's Windows patch series to the end (see v7 thread).\n- Fix more typos and formatting nits.\n- Rebased on top of \"master\".\n\n\n=== Testing ===\n\nThe latest patch set is available for testing on my GitHub fork, including\n\"travis.ci\" testing. The \"runtime-prefix\" branch includes a \"config.mak\"\ncommit that enables runtime prefix for the Travis build; the\n\"runtime-prefix-no-config\" omits this file, testing this patch without\nruntime prefix enabled:\n- https://github.com/danjacques/git/tree/runtime-prefix\n- https://github.com/danjacques/git/tree/runtime-prefix-no-config\n- https://travis-ci.org/danjacques/git/branches\n\nBuilt/tested locally using this \"config.mak\" w/ autoconf:\n\n=== Example config.mak ===\n\n## (BEGIN config.mak)\n\nRUNTIME_PREFIX = YesPlease\nRUNTIME_PREFIX_PERL = YesPlease\ngitexecdir = libexec/git-core\ntemplate_dir = share/git-core/templates\nsysconfdir = etc\n\n## (END config.mak)\n\n=== Revision History ===\n\nChanges in v7 from v6:\n\n- Change Perl header based on avarab@'s suggestion.\n- Fix typos in commit messages and comments.\n\nChanges in v6 from v5:\n\n- Rebased on top of \"master\".\n- Updated commit messages.\n- Updated runtime prefix Perl header comment and code to clarify when and\n  why FindBin is used.\n- With Johannes' blessing on Git-for-Windows, folded \"RUNTIME_PREFIX_PERL\"\n  functionality into \"RUNTIME_PREFIX\".\n- Updated \"run-command\" test to accommodate RUNTIME_PREFIX trace messages.\n\nChanges in v5 from v4:\n\n- Rebase on top of \"next\", notably incorporating the\n  \"ab/simplify-perl-makefile\" branch.\n- Cleaner Makefile relative path enforcement.\n- Update Perl header template path now that the \"perl/\" directory has\n  fewer build-related files in it.\n- Update Perl runtime prefix header to use a general system path resolution\n  function.\n- Implemented the injection of the locale directory into Perl's\n  \"Git/I18N.pm\" module from the runtime prefix Perl script header.\n- Updated Perl's \"Git/I18N.pm\" module to accept injected locale directory.\n- Added more content to some comments.\n\n\nChanges in v4 from v3:\n\n- Incorporated some quoting and Makefile dependency fixes, courtesy of\n  <johannes.schindelin@gmx.de>.\n\nChanges in v3 from v2:\n\n- Broken into multiple patches now that Perl is isolated in its own\n  RUNTIME_PREFIX_PERL flag.\n- Working with avarab@, several changes to Perl script runtime prefix\n  support:\n  - Moved Perl header body content from Makefile into external template\n    file(s).\n  - Added generic \"perllibdir\" variable to override Perl installation\n    path.\n  - RUNTIME_PREFIX_PERL generated script header is more descriptive and\n    consistent with how the C version operates.\n  - Fixed Generated Perl header Makefile dependency, should rebuild\n    when dependent files and flags change.\n- Changed some of the new RUNTIME_PREFIX trace strings to use consistent\n  formatting and terminology.\n\nChanges in v2 from v1:\n\n- Added comments and formatting to improve readability of\n  platform-sepecific executable path resolution sleds in\n  `git_get_exec_path`.\n- Consolidated \"cached_exec_path\" and \"argv_exec_path\" globals\n  into \"exec_path_value\".\n- Use `strbuf_realpath` instead of `realpath` for procfs resolution.\n- Removed new environment variable exports. Git with RUNTIME_PREFIX no\n  longer exports or consumes any additional environment information.\n- Updated Perl script resolution strategy: rather than having Git export\n  the relative executable path to the Perl scripts, they now resolve\n  it independently when RUNTIME_PREFIX_PERL is enabled.\n- Updated resolution strategy for \"gettext()\": use system_path() instead\n  of special environment variable.\n- Added `sysctl` executable resolution support for BSDs that don't\n  mount \"procfs\" by default (most of them).\n\nDan Jacques (3):\n  Makefile: generate Perl header from template file\n  Makefile: add Perl runtime prefix support\n  exec_cmd: RUNTIME_PREFIX on some POSIX systems\n\nJohannes Schindelin (2):\n  exec_cmd: provide a new-style RUNTIME_PREFIX helper for Windows\n  mingw/msvc: use the new-style RUNTIME_PREFIX helper\n\n .gitignore                                       |   1 +\n Makefile                                         | 128 +++++++++--\n cache.h                                          |   1 +\n common-main.c                                    |   4 +-\n compat/mingw.c                                   |   5 +-\n config.mak.uname                                 |   9 +\n exec_cmd.c                                       | 258 ++++++++++++++++++++---\n exec_cmd.h                                       |   4 +-\n gettext.c                                        |   8 +-\n git.c                                            |   2 +-\n perl/Git/I18N.pm                                 |   2 +-\n perl/header_templates/fixed_prefix.template.pl   |   1 +\n perl/header_templates/runtime_prefix.template.pl |  42 ++++\n t/t0061-run-command.sh                           |   2 +-\n 14 files changed, 412 insertions(+), 55 deletions(-)\n create mode 100644 perl/header_templates/fixed_prefix.template.pl\n create mode 100644 perl/header_templates/runtime_prefix.template.pl\n\n-- \n2.15.0.chromium12\n\n"},{"id":"344353","messageId":"20180410150546.38062-2-dnj@google.com","threadId":"48256","inReplyTo":"20180410150546.38062-1-dnj@google.com","subject":"[PATCH v8 1/5] Makefile: generate Perl header from template file","fromName":"Dan Jacques","fromEmail":"dnj@google.com","sentAt":"2018-04-10T15:05:42Z","receivedAt":"2018-04-10T15:06:15Z","isPatch":true,"sender":{"key":"dnj@google.com","avatar":"https://avatars.githubusercontent.com/u/9965104?v=4"},"body":"Currently, the generated Perl script headers are emitted by commands in\nthe Makefile. This mechanism restricts options to introduce alternative\nheader content, needed by Perl runtime prefix support, and obscures the\norigin of the Perl script header.\n\nChange the Makefile to generate a header by processing a template file and\nmove the header content into the \"perl/\" subdirectory. The generated\nheader content will now be stored in the \"GIT-PERL-HEADER\" file. This\nallows the content of the Perl header to be controlled by changing the path\nof the template in the Makefile.\n\nSigned-off-by: Dan Jacques <dnj@google.com>\nThanks-to: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nThanks-to: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .gitignore                                     |  1 +\n Makefile                                       | 27 +++++++++++++++-----------\n perl/header_templates/fixed_prefix.template.pl |  1 +\n 3 files changed, 18 insertions(+), 11 deletions(-)\n create mode 100644 perl/header_templates/fixed_prefix.template.pl\n\ndiff --git a/.gitignore b/.gitignore\nindex 833ef3b0b..89bd7bd8a 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -3,6 +3,7 @@\n /GIT-LDFLAGS\n /GIT-PREFIX\n /GIT-PERL-DEFINES\n+/GIT-PERL-HEADER\n /GIT-PYTHON-VARS\n /GIT-SCRIPT-DEFINES\n /GIT-USER-AGENT\ndiff --git a/Makefile b/Makefile\nindex 96f6138f6..ec7cf5a0f 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1984,20 +1984,15 @@ git.res: git.rc GIT-VERSION-FILE\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n ifndef NO_PERL\n-$(SCRIPT_PERL_GEN):\n-\n+PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n PERL_DEFINES = $(PERL_PATH_SQ):$(PERLLIB_EXTRA_SQ):$(perllibdir_SQ)\n-$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-VERSION-FILE\n+\n+$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \t$(QUIET_GEN)$(RM) $@ $@+ && \\\n-\tINSTLIBDIR='$(perllibdir_SQ)' && \\\n-\tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n-\tINSTLIBDIR=\"$$INSTLIBDIR$${INSTLIBDIR_EXTRA:+:$$INSTLIBDIR_EXTRA}\" && \\\n \tsed -e '1{' \\\n \t    -e '\ts|#!.*perl|#!$(PERL_PATH_SQ)|' \\\n-\t    -e '\th' \\\n-\t    -e '\ts=.*=use lib (split(/$(pathsep)/, $$ENV{GITPERLLIB} || \"'\"$$INSTLIBDIR\"'\"));=' \\\n-\t    -e '\tH' \\\n-\t    -e '\tx' \\\n+\t    -e '\trGIT-PERL-HEADER' \\\n+\t    -e '\tG' \\\n \t    -e '}' \\\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t    $< >$@+ && \\\n@@ -2011,6 +2006,16 @@ GIT-PERL-DEFINES: FORCE\n \t\techo \"$$FLAGS\" >$@; \\\n \t    fi\n \n+GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n+\t$(QUIET_GEN)$(RM) $@ && \\\n+\tINSTLIBDIR='$(perllibdir_SQ)' && \\\n+\tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n+\tINSTLIBDIR=\"$$INSTLIBDIR$${INSTLIBDIR_EXTRA:+:$$INSTLIBDIR_EXTRA}\" && \\\n+\tsed -e 's=@@PATHSEP@@=$(pathsep)=g' \\\n+\t    -e 's=@@INSTLIBDIR@@='$$INSTLIBDIR'=g' \\\n+\t    -e 's=@@PERLLIBDIR@@='$(perllibdir_SQ)'=g' \\\n+\t    $< >$@+ && \\\n+\tmv $@+ $@\n \n .PHONY: gitweb\n gitweb:\n@@ -2788,7 +2793,7 @@ ifndef NO_TCLTK\n endif\n \t$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS\n \t$(RM) GIT-USER-AGENT GIT-PREFIX\n-\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PYTHON-VARS\n+\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS\n \n .PHONY: all install profile-clean clean strip\n .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell\ndiff --git a/perl/header_templates/fixed_prefix.template.pl b/perl/header_templates/fixed_prefix.template.pl\nnew file mode 100644\nindex 000000000..857b4391a\n--- /dev/null\n+++ b/perl/header_templates/fixed_prefix.template.pl\n@@ -0,0 +1 @@\n+use lib (split(/@@PATHSEP@@/, $ENV{GITPERLLIB} || '@@INSTLIBDIR@@'));\n-- \n2.15.0.chromium12\n\n"},{"id":"344354","messageId":"20180410150546.38062-3-dnj@google.com","threadId":"48256","inReplyTo":"20180410150546.38062-1-dnj@google.com","subject":"[PATCH v8 2/5] Makefile: add Perl runtime prefix support","fromName":"Dan Jacques","fromEmail":"dnj@google.com","sentAt":"2018-04-10T15:05:43Z","receivedAt":"2018-04-10T15:06:17Z","isPatch":true,"sender":{"key":"dnj@google.com","avatar":"https://avatars.githubusercontent.com/u/9965104?v=4"},"body":"Broaden the RUNTIME_PREFIX flag to configure Git's Perl scripts to\nlocate the Git installation's Perl support libraries by resolving\nagainst the script's path, rather than hard-coding that path at\nbuild-time. Hard-coding at build time worked on previous\nRUNTIME_PREFIX configurations (i.e., Windows) because the Perl\nscripts were run within a virtual filesystem whose paths were\nconsistent regardless of the location of the actual installation.\nThis will no longer be the case for non-Windows RUNTIME_PREFIX users.\n\nWhen enabled, RUNTIME_PREFIX now requires Perl's system paths to be\nexpressed relative to a common installation directory in the Makefile,\nand uses that relationship to locate support files based on the known\nstarting point of the script being executed, much like RUNTIME_PREFIX\ndoes for the Git binary.\n\nThis change enables Git's Perl scripts to work when their Git installation\nis relocated or moved to another system, even when they are not in a\nvirtual filesystem environment.\n\nSigned-off-by: Dan Jacques <dnj@google.com>\nThanks-to: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nThanks-to: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Makefile                                         | 65 +++++++++++++++++++++++-\n perl/Git/I18N.pm                                 |  2 +-\n perl/header_templates/runtime_prefix.template.pl | 42 +++++++++++++++\n 3 files changed, 107 insertions(+), 2 deletions(-)\n create mode 100644 perl/header_templates/runtime_prefix.template.pl\n\ndiff --git a/Makefile b/Makefile\nindex ec7cf5a0f..13fb0e19a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -441,6 +441,13 @@ all::\n #\n # When cross-compiling, define HOST_CPU as the canonical name of the CPU on\n # which the built Git will run (for instance \"x86_64\").\n+#\n+# Define RUNTIME_PREFIX to configure Git to resolve its ancillary tooling and\n+# support files relative to the location of the runtime binary, rather than\n+# hard-coding them into the binary. Git installations built with RUNTIME_PREFIX\n+# can be moved to arbitrary filesystem locations. RUNTIME_PREFIX also causes\n+# Perl scripts to use a modified entry point header allowing them to resolve\n+# support files at runtime.\n \n GIT-VERSION-FILE: FORCE\n \t@$(SHELL_PATH) ./GIT-VERSION-GEN\n@@ -478,6 +485,8 @@ ARFLAGS = rcs\n #   mandir\n #   infodir\n #   htmldir\n+#   localedir\n+#   perllibdir\n # This can help installing the suite in a relocatable way.\n \n prefix = $(HOME)\n@@ -502,7 +511,9 @@ bindir_relative = $(patsubst $(prefix)/%,%,$(bindir))\n mandir_relative = $(patsubst $(prefix)/%,%,$(mandir))\n infodir_relative = $(patsubst $(prefix)/%,%,$(infodir))\n gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir))\n+localedir_relative = $(patsubst $(prefix)/%,%,$(localedir))\n htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir))\n+perllibdir_relative = $(patsubst $(prefix)/%,%,$(perllibdir))\n \n export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir\n \n@@ -1748,11 +1759,13 @@ mandir_relative_SQ = $(subst ','\\'',$(mandir_relative))\n infodir_relative_SQ = $(subst ','\\'',$(infodir_relative))\n perllibdir_SQ = $(subst ','\\'',$(perllibdir))\n localedir_SQ = $(subst ','\\'',$(localedir))\n+localedir_relative_SQ = $(subst ','\\'',$(localedir_relative))\n gitexecdir_SQ = $(subst ','\\'',$(gitexecdir))\n gitexecdir_relative_SQ = $(subst ','\\'',$(gitexecdir_relative))\n template_dir_SQ = $(subst ','\\'',$(template_dir))\n htmldir_relative_SQ = $(subst ','\\'',$(htmldir_relative))\n prefix_SQ = $(subst ','\\'',$(prefix))\n+perllibdir_relative_SQ = $(subst ','\\'',$(perllibdir_relative))\n gitwebdir_SQ = $(subst ','\\'',$(gitwebdir))\n \n SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n@@ -1763,6 +1776,31 @@ TCLTK_PATH_SQ = $(subst ','\\'',$(TCLTK_PATH))\n DIFF_SQ = $(subst ','\\'',$(DIFF))\n PERLLIB_EXTRA_SQ = $(subst ','\\'',$(PERLLIB_EXTRA))\n \n+# RUNTIME_PREFIX's resolution logic requires resource paths to be expressed\n+# relative to each other and share an installation path.\n+#\n+# This is a dependency in:\n+# - Git's binary RUNTIME_PREFIX logic in (see \"exec_cmd.c\").\n+# - The runtime prefix Perl header (see\n+#   \"perl/header_templates/runtime_prefix.template.pl\").\n+ifdef RUNTIME_PREFIX\n+\n+ifneq ($(filter /%,$(firstword $(gitexecdir_relative))),)\n+$(error RUNTIME_PREFIX requires a relative gitexecdir, not: $(gitexecdir))\n+endif\n+\n+ifneq ($(filter /%,$(firstword $(localedir_relative))),)\n+$(error RUNTIME_PREFIX requires a relative localedir, not: $(localedir))\n+endif\n+\n+ifndef NO_PERL\n+ifneq ($(filter /%,$(firstword $(perllibdir_relative))),)\n+$(error RUNTIME_PREFIX requires a relative perllibdir, not: $(perllibdir))\n+endif\n+endif\n+\n+endif\n+\n # We must filter out any object files from $(GITLIBS),\n # as it is typically used like:\n #\n@@ -1983,10 +2021,31 @@ git.res: git.rc GIT-VERSION-FILE\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n+# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n+# since the locale directory is injected.\n+perl_localedir_SQ = $(localedir_SQ)\n+\n ifndef NO_PERL\n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n PERL_DEFINES = $(PERL_PATH_SQ):$(PERLLIB_EXTRA_SQ):$(perllibdir_SQ)\n \n+PERL_DEFINES := $(PERL_PATH_SQ) $(PERLLIB_EXTRA_SQ) $(perllibdir_SQ)\n+PERL_DEFINES += $(RUNTIME_PREFIX)\n+\n+# Support Perl runtime prefix. In this mode, a different header is installed\n+# into Perl scripts.\n+ifdef RUNTIME_PREFIX\n+\n+PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n+\n+# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n+# at runtime.\n+perl_localedir_SQ =\n+\n+endif\n+\n+PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n+\n $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \t$(QUIET_GEN)$(RM) $@ $@+ && \\\n \tsed -e '1{' \\\n@@ -1999,6 +2058,7 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n+PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n GIT-PERL-DEFINES: FORCE\n \t@FLAGS='$(PERL_DEFINES)'; \\\n \t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n@@ -2014,6 +2074,9 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n \tsed -e 's=@@PATHSEP@@=$(pathsep)=g' \\\n \t    -e 's=@@INSTLIBDIR@@='$$INSTLIBDIR'=g' \\\n \t    -e 's=@@PERLLIBDIR@@='$(perllibdir_SQ)'=g' \\\n+\t    -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \\\n+\t    -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \\\n+\t    -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \\\n \t    $< >$@+ && \\\n \tmv $@+ $@\n \n@@ -2337,7 +2400,7 @@ endif\n \n perl/build/lib/%.pm: perl/%.pm\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-\tsed -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \\\n+\tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n \t< $< > $@\n \ndiff --git a/perl/Git/I18N.pm b/perl/Git/I18N.pm\nindex dba96fff0..bfb4fb67a 100644\n--- a/perl/Git/I18N.pm\n+++ b/perl/Git/I18N.pm\n@@ -18,7 +18,7 @@ our @EXPORT_OK = @EXPORT;\n \n sub __bootstrap_locale_messages {\n \tour $TEXTDOMAIN = 'git';\n-\tour $TEXTDOMAINDIR = $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';\n+\tour $TEXTDOMAINDIR ||= $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';\n \n \trequire POSIX;\n \tPOSIX->import(qw(setlocale));\ndiff --git a/perl/header_templates/runtime_prefix.template.pl b/perl/header_templates/runtime_prefix.template.pl\nnew file mode 100644\nindex 000000000..9d28b3d86\n--- /dev/null\n+++ b/perl/header_templates/runtime_prefix.template.pl\n@@ -0,0 +1,42 @@\n+# BEGIN RUNTIME_PREFIX generated code.\n+#\n+# This finds our Git::* libraries relative to the script's runtime path.\n+sub __git_system_path {\n+\tmy ($relpath) = @_;\n+\tmy $gitexecdir_relative = '@@GITEXECDIR_REL@@';\n+\n+\t# GIT_EXEC_PATH is supplied by `git` or the test suite.\n+\tmy $exec_path;\n+\tif (exists $ENV{GIT_EXEC_PATH}) {\n+\t\t$exec_path = $ENV{GIT_EXEC_PATH};\n+\t} else {\n+\t\t# This can happen if this script is being directly invoked instead of run\n+\t\t# by \"git\".\n+\t\trequire FindBin;\n+\t\t$exec_path = $FindBin::Bin;\n+\t}\n+\n+\t# Trim off the relative gitexecdir path to get the system path.\n+\t(my $prefix = $exec_path) =~ s/\\Q$gitexecdir_relative\\E$//;\n+\n+\trequire File::Spec;\n+\treturn File::Spec->catdir($prefix, $relpath);\n+}\n+\n+BEGIN {\n+\tuse lib split /@@PATHSEP@@/,\n+\t(\n+\t\t$ENV{GITPERLLIB} ||\n+\t\tdo {\n+\t\t\tmy $perllibdir = __git_system_path('@@PERLLIBDIR_REL@@');\n+\t\t\t(-e $perllibdir) || die(\"Invalid system path ($relpath): $path\");\n+\t\t\t$perllibdir;\n+\t\t}\n+\t);\n+\n+\t# Export the system locale directory to the I18N module. The locale directory\n+\t# is only installed if NO_GETTEXT is set.\n+\t$Git::I18N::TEXTDOMAINDIR = __git_system_path('@@LOCALEDIR_REL@@');\n+}\n+\n+# END RUNTIME_PREFIX generated code.\n-- \n2.15.0.chromium12\n\n"},{"id":"344355","messageId":"20180410150546.38062-4-dnj@google.com","threadId":"48256","inReplyTo":"20180410150546.38062-1-dnj@google.com","subject":"[PATCH v8 3/5] exec_cmd: RUNTIME_PREFIX on some POSIX systems","fromName":"Dan Jacques","fromEmail":"dnj@google.com","sentAt":"2018-04-10T15:05:44Z","receivedAt":"2018-04-10T15:06:23Z","isPatch":true,"sender":{"key":"dnj@google.com","avatar":"https://avatars.githubusercontent.com/u/9965104?v=4"},"body":"Enable Git to resolve its own binary location using a variety of\nOS-specific and generic methods, including:\n\n- procfs via \"/proc/self/exe\" (Linux)\n- _NSGetExecutablePath (Darwin)\n- KERN_PROC_PATHNAME sysctl on BSDs.\n- argv0, if absolute (all, including Windows).\n\nThis is used to enable RUNTIME_PREFIX support for non-Windows systems,\nnotably Linux and Darwin. When configured with RUNTIME_PREFIX, Git will\ndo a best-effort resolution of its executable path and automatically use\nthis as its \"exec_path\" for relative helper and data lookups, unless\nexplicitly overridden.\n\nSmall incidental formatting cleanup of \"exec_cmd.c\".\n\nSigned-off-by: Dan Jacques <dnj@google.com>\nThanks-to: Robbie Iannucci <iannucci@google.com>\nThanks-to: Junio C Hamano <gitster@pobox.com>\n---\n Makefile               |  28 +++++-\n cache.h                |   1 +\n common-main.c          |   4 +-\n config.mak.uname       |   7 ++\n exec_cmd.c             | 236 +++++++++++++++++++++++++++++++++++++++++++------\n exec_cmd.h             |   4 +-\n gettext.c              |   8 +-\n git.c                  |   2 +-\n t/t0061-run-command.sh |   2 +-\n 9 files changed, 253 insertions(+), 39 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 13fb0e19a..960541e77 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -448,6 +448,18 @@ all::\n # can be moved to arbitrary filesystem locations. RUNTIME_PREFIX also causes\n # Perl scripts to use a modified entry point header allowing them to resolve\n # support files at runtime.\n+#\n+# When using RUNTIME_PREFIX, define HAVE_BSD_KERN_PROC_SYSCTL if your platform\n+# supports the KERN_PROC BSD sysctl function.\n+#\n+# When using RUNTIME_PREFIX, define PROCFS_EXECUTABLE_PATH if your platform\n+# mounts a \"procfs\" filesystem capable of resolving the path of the current\n+# executable. If defined, this must be the canonical path for the \"procfs\"\n+# current executable path.\n+#\n+# When using RUNTIME_PREFIX, define HAVE_NS_GET_EXECUTABLE_PATH if your platform\n+# supports calling _NSGetExecutablePath to retrieve the path of the running\n+# executable.\n \n GIT-VERSION-FILE: FORCE\n \t@$(SHELL_PATH) ./GIT-VERSION-GEN\n@@ -1671,10 +1683,23 @@ ifdef HAVE_BSD_SYSCTL\n \tBASIC_CFLAGS += -DHAVE_BSD_SYSCTL\n endif\n \n+ifdef HAVE_BSD_KERN_PROC_SYSCTL\n+\tBASIC_CFLAGS += -DHAVE_BSD_KERN_PROC_SYSCTL\n+endif\n+\n ifdef HAVE_GETDELIM\n \tBASIC_CFLAGS += -DHAVE_GETDELIM\n endif\n \n+ifneq ($(PROCFS_EXECUTABLE_PATH),)\n+\tprocfs_executable_path_SQ = $(subst ','\\'',$(PROCFS_EXECUTABLE_PATH))\n+\tBASIC_CFLAGS += '-DPROCFS_EXECUTABLE_PATH=\"$(procfs_executable_path_SQ)\"'\n+endif\n+\n+ifdef HAVE_NS_GET_EXECUTABLE_PATH\n+\tBASIC_CFLAGS += -DHAVE_NS_GET_EXECUTABLE_PATH\n+endif\n+\n ifeq ($(TCLTK_PATH),)\n NO_TCLTK = NoThanks\n endif\n@@ -2223,6 +2248,7 @@ endif\n exec_cmd.sp exec_cmd.s exec_cmd.o: GIT-PREFIX\n exec_cmd.sp exec_cmd.s exec_cmd.o: EXTRA_CPPFLAGS = \\\n \t'-DGIT_EXEC_PATH=\"$(gitexecdir_SQ)\"' \\\n+\t'-DGIT_LOCALE_PATH=\"$(localedir_relative_SQ)\"' \\\n \t'-DBINDIR=\"$(bindir_relative_SQ)\"' \\\n \t'-DPREFIX=\"$(prefix_SQ)\"'\n \n@@ -2240,7 +2266,7 @@ attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \\\n \n gettext.sp gettext.s gettext.o: GIT-PREFIX\n gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \\\n-\t-DGIT_LOCALE_PATH='\"$(localedir_SQ)\"'\n+\t-DGIT_LOCALE_PATH='\"$(localedir_relative_SQ)\"'\n \n http-push.sp http.sp http-walker.sp remote-curl.sp imap-send.sp: SPARSE_FLAGS += \\\n \t-DCURL_DISABLE_TYPECHECK\ndiff --git a/cache.h b/cache.h\nindex 6e45c1b53..4f8754969 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -428,6 +428,7 @@ static inline enum object_type object_type(unsigned int mode)\n #define GIT_ICASE_PATHSPECS_ENVIRONMENT \"GIT_ICASE_PATHSPECS\"\n #define GIT_QUARANTINE_ENVIRONMENT \"GIT_QUARANTINE_PATH\"\n #define GIT_OPTIONAL_LOCKS_ENVIRONMENT \"GIT_OPTIONAL_LOCKS\"\n+#define GIT_TEXT_DOMAIN_DIR_ENVIRONMENT \"GIT_TEXTDOMAINDIR\"\n \n /*\n  * Environment variable used in handshaking the wire protocol.\ndiff --git a/common-main.c b/common-main.c\nindex 7d716d5a5..b2e5a86df 100644\n--- a/common-main.c\n+++ b/common-main.c\n@@ -32,14 +32,14 @@ int main(int argc, const char **argv)\n \t */\n \tsanitize_stdfds();\n \n+\tgit_resolve_executable_dir(argv[0]);\n+\n \tgit_setup_gettext();\n \n \tinitialize_the_repository();\n \n \tattr_start();\n \n-\tgit_extract_argv0_path(argv[0]);\n-\n \trestore_sigpipe_to_default();\n \n \treturn cmd_main(argc, argv);\ndiff --git a/config.mak.uname b/config.mak.uname\nindex 6a1d0de0c..e1cfe5e5e 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -37,6 +37,7 @@ ifeq ($(uname_S),Linux)\n \tHAVE_GETDELIM = YesPlease\n \tSANE_TEXT_GREP=-a\n \tFREAD_READS_DIRECTORIES = UnfortunatelyYes\n+\tPROCFS_EXECUTABLE_PATH = /proc/self/exe\n endif\n ifeq ($(uname_S),GNU/kFreeBSD)\n \tHAVE_ALLOCA_H = YesPlease\n@@ -111,6 +112,7 @@ ifeq ($(uname_S),Darwin)\n \tBASIC_CFLAGS += -DPROTECT_HFS_DEFAULT=1\n \tHAVE_BSD_SYSCTL = YesPlease\n \tFREAD_READS_DIRECTORIES = UnfortunatelyYes\n+\tHAVE_NS_GET_EXECUTABLE_PATH = YesPlease\n endif\n ifeq ($(uname_S),SunOS)\n \tNEEDS_SOCKET = YesPlease\n@@ -205,6 +207,7 @@ ifeq ($(uname_S),FreeBSD)\n \tHAVE_PATHS_H = YesPlease\n \tGMTIME_UNRELIABLE_ERRORS = UnfortunatelyYes\n \tHAVE_BSD_SYSCTL = YesPlease\n+\tHAVE_BSD_KERN_PROC_SYSCTL = YesPlease\n \tPAGER_ENV = LESS=FRX LV=-c MORE=FRX\n \tFREAD_READS_DIRECTORIES = UnfortunatelyYes\n endif\n@@ -217,6 +220,8 @@ ifeq ($(uname_S),OpenBSD)\n \tBASIC_LDFLAGS += -L/usr/local/lib\n \tHAVE_PATHS_H = YesPlease\n \tHAVE_BSD_SYSCTL = YesPlease\n+\tHAVE_BSD_KERN_PROC_SYSCTL = YesPlease\n+\tPROCFS_EXECUTABLE_PATH = /proc/curproc/file\n endif\n ifeq ($(uname_S),MirBSD)\n \tNO_STRCASESTR = YesPlease\n@@ -235,6 +240,8 @@ ifeq ($(uname_S),NetBSD)\n \tUSE_ST_TIMESPEC = YesPlease\n \tHAVE_PATHS_H = YesPlease\n \tHAVE_BSD_SYSCTL = YesPlease\n+\tHAVE_BSD_KERN_PROC_SYSCTL = YesPlease\n+\tPROCFS_EXECUTABLE_PATH = /proc/curproc/exe\n endif\n ifeq ($(uname_S),AIX)\n \tDEFAULT_PAGER = more\ndiff --git a/exec_cmd.c b/exec_cmd.c\nindex ce192a2d6..38d52d90a 100644\n--- a/exec_cmd.c\n+++ b/exec_cmd.c\n@@ -2,24 +2,52 @@\n #include \"exec_cmd.h\"\n #include \"quote.h\"\n #include \"argv-array.h\"\n-#define MAX_ARGS\t32\n \n-static const char *argv_exec_path;\n+#if defined(RUNTIME_PREFIX)\n+\n+#if defined(HAVE_NS_GET_EXECUTABLE_PATH)\n+#include <mach-o/dyld.h>\n+#endif\n+\n+#if defined(HAVE_BSD_KERN_PROC_SYSCTL)\n+#include <sys/param.h>\n+#include <sys/types.h>\n+#include <sys/sysctl.h>\n+#endif\n+\n+#endif /* RUNTIME_PREFIX */\n+\n+#define MAX_ARGS 32\n+\n+static const char *system_prefix(void);\n \n #ifdef RUNTIME_PREFIX\n-static const char *argv0_path;\n+\n+/**\n+ * When using a runtime prefix, Git dynamically resolves paths relative to its\n+ * executable.\n+ *\n+ * The method for determining the path of the executable is highly\n+ * platform-specific.\n+ */\n+\n+/**\n+ * Path to the current Git executable. Resolved on startup by\n+ * 'git_resolve_executable_dir'.\n+ */\n+static const char *executable_dirname;\n \n static const char *system_prefix(void)\n {\n \tstatic const char *prefix;\n \n-\tassert(argv0_path);\n-\tassert(is_absolute_path(argv0_path));\n+\tassert(executable_dirname);\n+\tassert(is_absolute_path(executable_dirname));\n \n \tif (!prefix &&\n-\t    !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&\n-\t    !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&\n-\t    !(prefix = strip_path_suffix(argv0_path, \"git\"))) {\n+\t    !(prefix = strip_path_suffix(executable_dirname, GIT_EXEC_PATH)) &&\n+\t    !(prefix = strip_path_suffix(executable_dirname, BINDIR)) &&\n+\t    !(prefix = strip_path_suffix(executable_dirname, \"git\"))) {\n \t\tprefix = PREFIX;\n \t\ttrace_printf(\"RUNTIME_PREFIX requested, \"\n \t\t\t\t\"but prefix computation failed.  \"\n@@ -28,27 +56,179 @@ static const char *system_prefix(void)\n \treturn prefix;\n }\n \n-void git_extract_argv0_path(const char *argv0)\n+/*\n+ * Resolves the executable path from argv[0], only if it is absolute.\n+ *\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int git_get_exec_path_from_argv0(struct strbuf *buf, const char *argv0)\n {\n \tconst char *slash;\n \n \tif (!argv0 || !*argv0)\n-\t\treturn;\n+\t\treturn -1;\n \n \tslash = find_last_dir_sep(argv0);\n+\tif (slash) {\n+\t\ttrace_printf(\"trace: resolved executable path from argv0: %s\\n\",\n+\t\t\t     argv0);\n+\t\tstrbuf_add_absolute_path(buf, argv0);\n+\t\treturn 0;\n+\t}\n+\treturn -1;\n+}\n \n+#ifdef PROCFS_EXECUTABLE_PATH\n+/*\n+ * Resolves the executable path by examining a procfs symlink.\n+ *\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int git_get_exec_path_procfs(struct strbuf *buf)\n+{\n+\tif (strbuf_realpath(buf, PROCFS_EXECUTABLE_PATH, 0)) {\n+\t\ttrace_printf(\n+\t\t\t\"trace: resolved executable path from procfs: %s\\n\",\n+\t\t\tbuf->buf);\n+\t\treturn 0;\n+\t}\n+\treturn -1;\n+}\n+#endif /* PROCFS_EXECUTABLE_PATH */\n+\n+#ifdef HAVE_BSD_KERN_PROC_SYSCTL\n+/*\n+ * Resolves the executable path using KERN_PROC_PATHNAME BSD sysctl.\n+ *\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int git_get_exec_path_bsd_sysctl(struct strbuf *buf)\n+{\n+\tint mib[4];\n+\tchar path[MAXPATHLEN];\n+\tsize_t cb = sizeof(path);\n+\n+\tmib[0] = CTL_KERN;\n+\tmib[1] = KERN_PROC;\n+\tmib[2] = KERN_PROC_PATHNAME;\n+\tmib[3] = -1;\n+\tif (!sysctl(mib, 4, path, &cb, NULL, 0)) {\n+\t\ttrace_printf(\n+\t\t\t\"trace: resolved executable path from sysctl: %s\\n\",\n+\t\t\tpath);\n+\t\tstrbuf_addstr(buf, path);\n+\t\treturn 0;\n+\t}\n+\treturn -1;\n+}\n+#endif /* HAVE_BSD_KERN_PROC_SYSCTL */\n+\n+#ifdef HAVE_NS_GET_EXECUTABLE_PATH\n+/*\n+ * Resolves the executable path by querying Darwin application stack.\n+ *\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int git_get_exec_path_darwin(struct strbuf *buf)\n+{\n+\tchar path[PATH_MAX];\n+\tuint32_t size = sizeof(path);\n+\tif (!_NSGetExecutablePath(path, &size)) {\n+\t\ttrace_printf(\n+\t\t\t\"trace: resolved executable path from Darwin stack: %s\\n\",\n+\t\t\tpath);\n+\t\tstrbuf_addstr(buf, path);\n+\t\treturn 0;\n+\t}\n+\treturn -1;\n+}\n+#endif /* HAVE_NS_GET_EXECUTABLE_PATH */\n+\n+/*\n+ * Resolves the absolute path of the current executable.\n+ *\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int git_get_exec_path(struct strbuf *buf, const char *argv0)\n+{\n+\t/*\n+\t * Identifying the executable path is operating system specific.\n+\t * Selectively employ all available methods in order of preference,\n+\t * preferring highly-available authoritative methods over\n+\t * selectively-available or non-authoritative methods.\n+\t *\n+\t * All cases fall back on resolving against argv[0] if there isn't a\n+\t * better functional method. However, note that argv[0] can be\n+\t * used-supplied on many operating systems, and is not authoritative\n+\t * in those cases.\n+\t *\n+\t * Each of these functions returns 0 on success, so evaluation will stop\n+\t * after the first successful method.\n+\t */\n+\tif (\n+#ifdef HAVE_BSD_KERN_PROC_SYSCTL\n+\t\tgit_get_exec_path_bsd_sysctl(buf) &&\n+#endif /* HAVE_BSD_KERN_PROC_SYSCTL */\n+\n+#ifdef HAVE_NS_GET_EXECUTABLE_PATH\n+\t\tgit_get_exec_path_darwin(buf) &&\n+#endif /* HAVE_NS_GET_EXECUTABLE_PATH */\n+\n+#ifdef PROCFS_EXECUTABLE_PATH\n+\t\tgit_get_exec_path_procfs(buf) &&\n+#endif /* PROCFS_EXECUTABLE_PATH */\n+\n+\t\tgit_get_exec_path_from_argv0(buf, argv0)) {\n+\t\treturn -1;\n+\t}\n+\n+\tif (strbuf_normalize_path(buf)) {\n+\t\ttrace_printf(\"trace: could not normalize path: %s\\n\", buf->buf);\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void git_resolve_executable_dir(const char *argv0)\n+{\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tchar *resolved;\n+\tconst char *slash;\n+\n+\tif (git_get_exec_path(&buf, argv0)) {\n+\t\ttrace_printf(\n+\t\t\t\"trace: could not determine executable path from: %s\\n\",\n+\t\t\targv0);\n+\t\tstrbuf_release(&buf);\n+\t\treturn;\n+\t}\n+\n+\tresolved = strbuf_detach(&buf, NULL);\n+\tslash = find_last_dir_sep(resolved);\n \tif (slash)\n-\t\targv0_path = xstrndup(argv0, slash - argv0);\n+\t\tresolved[slash - resolved] = '\\0';\n+\n+\texecutable_dirname = resolved;\n+\ttrace_printf(\"trace: resolved executable dir: %s\\n\",\n+\t\t     executable_dirname);\n }\n \n #else\n \n+/*\n+ * When not using a runtime prefix, Git uses a hard-coded path.\n+ */\n static const char *system_prefix(void)\n {\n \treturn PREFIX;\n }\n \n-void git_extract_argv0_path(const char *argv0)\n+/*\n+ * This is called during initialization, but No work needs to be done here when\n+ * runtime prefix is not being used.\n+ */\n+void git_resolve_executable_dir(const char *argv0)\n {\n }\n \n@@ -65,32 +245,28 @@ char *system_path(const char *path)\n \treturn strbuf_detach(&d, NULL);\n }\n \n-void git_set_argv_exec_path(const char *exec_path)\n+static const char *exec_path_value;\n+\n+void git_set_exec_path(const char *exec_path)\n {\n-\targv_exec_path = exec_path;\n+\texec_path_value = exec_path;\n \t/*\n \t * Propagate this setting to external programs.\n \t */\n \tsetenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);\n }\n \n-\n-/* Returns the highest-priority, location to look for git programs. */\n+/* Returns the highest-priority location to look for git programs. */\n const char *git_exec_path(void)\n {\n-\tstatic char *cached_exec_path;\n-\n-\tif (argv_exec_path)\n-\t\treturn argv_exec_path;\n-\n-\tif (!cached_exec_path) {\n+\tif (!exec_path_value) {\n \t\tconst char *env = getenv(EXEC_PATH_ENVIRONMENT);\n \t\tif (env && *env)\n-\t\t\tcached_exec_path = xstrdup(env);\n+\t\t\texec_path_value = xstrdup(env);\n \t\telse\n-\t\t\tcached_exec_path = system_path(GIT_EXEC_PATH);\n+\t\t\texec_path_value = system_path(GIT_EXEC_PATH);\n \t}\n-\treturn cached_exec_path;\n+\treturn exec_path_value;\n }\n \n static void add_path(struct strbuf *out, const char *path)\n@@ -103,10 +279,12 @@ static void add_path(struct strbuf *out, const char *path)\n \n void setup_path(void)\n {\n+\tconst char *exec_path = git_exec_path();\n \tconst char *old_path = getenv(\"PATH\");\n \tstruct strbuf new_path = STRBUF_INIT;\n \n-\tadd_path(&new_path, git_exec_path());\n+\tgit_set_exec_path(exec_path);\n+\tadd_path(&new_path, exec_path);\n \n \tif (old_path)\n \t\tstrbuf_addstr(&new_path, old_path);\n@@ -125,7 +303,8 @@ const char **prepare_git_cmd(struct argv_array *out, const char **argv)\n \treturn out->argv;\n }\n \n-int execv_git_cmd(const char **argv) {\n+int execv_git_cmd(const char **argv)\n+{\n \tstruct argv_array nargv = ARGV_ARRAY_INIT;\n \n \tprepare_git_cmd(&nargv, argv);\n@@ -140,8 +319,7 @@ int execv_git_cmd(const char **argv) {\n \treturn -1;\n }\n \n-\n-int execl_git_cmd(const char *cmd,...)\n+int execl_git_cmd(const char *cmd, ...)\n {\n \tint argc;\n \tconst char *argv[MAX_ARGS + 1];\ndiff --git a/exec_cmd.h b/exec_cmd.h\nindex ff0b48048..2522453cd 100644\n--- a/exec_cmd.h\n+++ b/exec_cmd.h\n@@ -3,8 +3,8 @@\n \n struct argv_array;\n \n-extern void git_set_argv_exec_path(const char *exec_path);\n-extern void git_extract_argv0_path(const char *path);\n+extern void git_set_exec_path(const char *exec_path);\n+extern void git_resolve_executable_dir(const char *path);\n extern const char *git_exec_path(void);\n extern void setup_path(void);\n extern const char **prepare_git_cmd(struct argv_array *out, const char **argv);\ndiff --git a/gettext.c b/gettext.c\nindex db727ea02..6b64d5c2e 100644\n--- a/gettext.c\n+++ b/gettext.c\n@@ -2,7 +2,8 @@\n  * Copyright (c) 2010 Ævar Arnfjörð Bjarmason\n  */\n \n-#include \"git-compat-util.h\"\n+#include \"cache.h\"\n+#include \"exec_cmd.h\"\n #include \"gettext.h\"\n #include \"strbuf.h\"\n #include \"utf8.h\"\n@@ -157,10 +158,11 @@ static void init_gettext_charset(const char *domain)\n \n void git_setup_gettext(void)\n {\n-\tconst char *podir = getenv(\"GIT_TEXTDOMAINDIR\");\n+\tconst char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);\n \n \tif (!podir)\n-\t\tpodir = GIT_LOCALE_PATH;\n+\t\tpodir = system_path(GIT_LOCALE_PATH);\n+\n \tbindtextdomain(\"git\", podir);\n \tsetlocale(LC_MESSAGES, \"\");\n \tsetlocale(LC_TIME, \"\");\ndiff --git a/git.c b/git.c\nindex 3a8989371..48432f9fb 100644\n--- a/git.c\n+++ b/git.c\n@@ -83,7 +83,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)\n \t\t */\n \t\tif (skip_prefix(cmd, \"--exec-path\", &cmd)) {\n \t\t\tif (*cmd == '=')\n-\t\t\t\tgit_set_argv_exec_path(cmd + 1);\n+\t\t\t\tgit_set_exec_path(cmd + 1);\n \t\t\telse {\n \t\t\t\tputs(git_exec_path());\n \t\t\t\texit(0);\ndiff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh\nindex 24c92b6cd..1009595d6 100755\n--- a/t/t0061-run-command.sh\n+++ b/t/t0061-run-command.sh\n@@ -145,7 +145,7 @@ test_trace () {\n \texpect=\"$1\"\n \tshift\n \tGIT_TRACE=1 test-run-command \"$@\" run-command true 2>&1 >/dev/null | \\\n-\t\tsed 's/.* run_command: //' >actual &&\n+\t\tsed -e 's/.* run_command: //' -e '/trace: .*/d' >actual &&\n \techo \"$expect true\" >expect &&\n \ttest_cmp expect actual\n }\n-- \n2.15.0.chromium12\n\n"},{"id":"344356","messageId":"20180410150546.38062-5-dnj@google.com","threadId":"48256","inReplyTo":"20180410150546.38062-1-dnj@google.com","subject":"[PATCH v8 4/5] exec_cmd: provide a new-style RUNTIME_PREFIX helper for Windows","fromName":"Dan Jacques","fromEmail":"dnj@google.com","sentAt":"2018-04-10T15:05:45Z","receivedAt":"2018-04-10T15:06:28Z","isPatch":true,"sender":{"key":"dnj@google.com","avatar":"https://avatars.githubusercontent.com/u/9965104?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThe RUNTIME_PREFIX feature comes from Git for Windows, but it was\nenhanced to allow support for other platforms. While changing the\noriginal idea, the concept was also improved by not forcing argv[0] to\nbe adjusted.\n\nLet's allow the same for Windows by implementing a helper just as for\nthe other platforms.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Makefile   |  8 ++++++++\n exec_cmd.c | 22 ++++++++++++++++++++++\n 2 files changed, 30 insertions(+)\n\ndiff --git a/Makefile b/Makefile\nindex 960541e77..8fc5559c7 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -460,6 +460,10 @@ all::\n # When using RUNTIME_PREFIX, define HAVE_NS_GET_EXECUTABLE_PATH if your platform\n # supports calling _NSGetExecutablePath to retrieve the path of the running\n # executable.\n+#\n+# When using RUNTIME_PREFIX, define HAVE_WPGMPTR if your platform offers\n+# the global variable _wpgmptr containing the absolute path of the current\n+# executable (this is the case on Windows).\n \n GIT-VERSION-FILE: FORCE\n \t@$(SHELL_PATH) ./GIT-VERSION-GEN\n@@ -1700,6 +1704,10 @@ ifdef HAVE_NS_GET_EXECUTABLE_PATH\n \tBASIC_CFLAGS += -DHAVE_NS_GET_EXECUTABLE_PATH\n endif\n \n+ifdef HAVE_WPGMPTR\n+\tBASIC_CFLAGS += -DHAVE_WPGMPTR\n+endif\n+\n ifeq ($(TCLTK_PATH),)\n NO_TCLTK = NoThanks\n endif\ndiff --git a/exec_cmd.c b/exec_cmd.c\nindex 38d52d90a..6e114f8b3 100644\n--- a/exec_cmd.c\n+++ b/exec_cmd.c\n@@ -144,6 +144,24 @@ static int git_get_exec_path_darwin(struct strbuf *buf)\n }\n #endif /* HAVE_NS_GET_EXECUTABLE_PATH */\n \n+#ifdef HAVE_WPGMPTR\n+/*\n+ * Resolves the executable path by using the global variable _wpgmptr.\n+ *\n+ * Returns 0 on success, -1 on failure.\n+ */\n+static int git_get_exec_path_wpgmptr(struct strbuf *buf)\n+{\n+\tint len = wcslen(_wpgmptr) * 3 + 1;\n+\tstrbuf_grow(buf, len);\n+\tlen = xwcstoutf(buf->buf, _wpgmptr, len);\n+\tif (len < 0)\n+\t\treturn -1;\n+\tbuf->len += len;\n+\treturn 0;\n+}\n+#endif /* HAVE_WPGMPTR */\n+\n /*\n  * Resolves the absolute path of the current executable.\n  *\n@@ -178,6 +196,10 @@ static int git_get_exec_path(struct strbuf *buf, const char *argv0)\n \t\tgit_get_exec_path_procfs(buf) &&\n #endif /* PROCFS_EXECUTABLE_PATH */\n \n+#ifdef HAVE_WPGMPTR\n+\t\tgit_get_exec_path_wpgmptr(buf) &&\n+#endif /* HAVE_WPGMPTR */\n+\n \t\tgit_get_exec_path_from_argv0(buf, argv0)) {\n \t\treturn -1;\n \t}\n-- \n2.15.0.chromium12\n\n"},{"id":"344357","messageId":"20180410150546.38062-6-dnj@google.com","threadId":"48256","inReplyTo":"20180410150546.38062-1-dnj@google.com","subject":"[PATCH v8 5/5] mingw/msvc: use the new-style RUNTIME_PREFIX helper","fromName":"Dan Jacques","fromEmail":"dnj@google.com","sentAt":"2018-04-10T15:05:46Z","receivedAt":"2018-04-10T15:06:29Z","isPatch":true,"sender":{"key":"dnj@google.com","avatar":"https://avatars.githubusercontent.com/u/9965104?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThis change also allows us to stop overriding argv[0] with the absolute\npath of the executable, allowing us to preserve e.g. the case of the\nexecutable's file name.\n\nThis fixes https://github.com/git-for-windows/git/issues/1496 partially.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c   | 5 ++---\n config.mak.uname | 2 ++\n 2 files changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex a67872bab..6ded1c859 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -2221,7 +2221,7 @@ void mingw_startup(void)\n \t\tdie_startup();\n \n \t/* determine size of argv and environ conversion buffer */\n-\tmaxlen = wcslen(_wpgmptr);\n+\tmaxlen = wcslen(wargv[0]);\n \tfor (i = 1; i < argc; i++)\n \t\tmaxlen = max(maxlen, wcslen(wargv[i]));\n \tfor (i = 0; wenv[i]; i++)\n@@ -2241,8 +2241,7 @@ void mingw_startup(void)\n \tbuffer = malloc_startup(maxlen);\n \n \t/* convert command line arguments and environment to UTF-8 */\n-\t__argv[0] = wcstoutfdup_startup(buffer, _wpgmptr, maxlen);\n-\tfor (i = 1; i < argc; i++)\n+\tfor (i = 0; i < argc; i++)\n \t\t__argv[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen);\n \tfor (i = 0; wenv[i]; i++)\n \t\tenviron[i] = wcstoutfdup_startup(buffer, wenv[i], maxlen);\ndiff --git a/config.mak.uname b/config.mak.uname\nindex e1cfe5e5e..a6e734c5d 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -357,6 +357,7 @@ ifeq ($(uname_S),Windows)\n \tSNPRINTF_RETURNS_BOGUS = YesPlease\n \tNO_SVN_TESTS = YesPlease\n \tRUNTIME_PREFIX = YesPlease\n+\tHAVE_WPGMPTR = YesWeDo\n \tNO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease\n \tNO_NSEC = YesPlease\n \tUSE_WIN32_MMAP = YesPlease\n@@ -506,6 +507,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))\n \tNO_SVN_TESTS = YesPlease\n \tNO_PERL_MAKEMAKER = YesPlease\n \tRUNTIME_PREFIX = YesPlease\n+\tHAVE_WPGMPTR = YesWeDo\n \tNO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease\n \tNO_NSEC = YesPlease\n \tUSE_WIN32_MMAP = YesPlease\n-- \n2.15.0.chromium12\n\n"},{"id":"344442","messageId":"xmqqvacy4621.fsf@gitster-ct.c.googlers.com","threadId":"48256","inReplyTo":"20180410150546.38062-1-dnj@google.com","subject":"Re: [PATCH v8 0/5] RUNTIME_PREFIX relocatable Git","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-04-11T06:21:10Z","receivedAt":"2018-04-11T06:21:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Jacques <dnj@google.com> writes:\n\n> This is a minor update based on comments from the v6 series.\n> I'm hoping this set is good to go!\n>\n> This patch set expands support for the RUNTIME_PREFIX configuration flag,\n> currently only used on Windows builds, to include Linux, Darwin, and\n> FreeBSD. When Git is built with RUNTIME_PREFIX enabled, it resolves its\n> ancillary paths relative to the runtime location of its executable\n> rather than hard-coding them at compile-time, allowing a Git\n> installation to be deployed to a path other than the one in which it\n> was built/installed.\n>\n> Note that RUNTIME_PREFIX is not currently used outside of Windows.\n> This patch set should not have an impact on default Git builds.\n>\n> Previous threads:\n> v1: https://public-inbox.org/git/20171116170523.28696-1-dnj@google.com/\n> v2: https://public-inbox.org/git/20171119173141.4896-1-dnj@google.com/\n> v3: https://public-inbox.org/git/20171127164055.93283-1-dnj@google.com/\n> v4: https://public-inbox.org/git/20171129223807.91343-1-dnj@google.com/\n> v5: https://public-inbox.org/git/20180108030239.92036-1-dnj@google.com/\n> v5: https://public-inbox.org/git/20180108030239.92036-1-dnj@google.com/\n> v6: https://public-inbox.org/git/20180319025046.58052-1-dnj@google.com/\n> v7: https://public-inbox.org/git/20180325205120.17730-1-dnj@google.com/\n>\n> Changes in v8 from v7:\n>\n> - Add Johannes's Windows patch series to the end (see v7 thread).\n\nWonderful.  That gives me one less separate topic to worry about ;-)\n\n> - Fix more typos and formatting nits.\n> - Rebased on top of \"master\".\n\n"},{"id":"344445","messageId":"87k1teb4et.fsf@evledraar.gmail.com","threadId":"48256","inReplyTo":"20180410150546.38062-1-dnj@google.com","subject":"Re: [PATCH v8 0/5] RUNTIME_PREFIX relocatable Git","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-04-11T07:14:50Z","receivedAt":"2018-04-11T07:15:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Apr 10 2018, Dan Jacques wrote:\n\n> This is a minor update based on comments from the v6 series.\n> I'm hoping this set is good to go!\n\nThis looks to me. Thanks!\n\n> - Rebased on top of \"master\".\n\nProbably useful for others to have the interdiff between this and\nv7. Here it is:\n    \n    $ git tbdiff origin/master b329fde5a6 2b1ed6a79a\n    1: 776c7d6083 = 1: 4943ec6581 Makefile: generate Perl header from template file\n    2: 0cded81572 ! 2: 29223250da Makefile: add Perl runtime prefix support\n        @@ -52,10 +52,9 @@\n    \n          prefix = $(HOME)\n         @@\n        - \n          mandir_relative = $(patsubst $(prefix)/%,%,$(mandir))\n          infodir_relative = $(patsubst $(prefix)/%,%,$(infodir))\n        -+gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir))\n        + gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir))\n         +localedir_relative = $(patsubst $(prefix)/%,%,$(localedir))\n          htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir))\n         +perllibdir_relative = $(patsubst $(prefix)/%,%,$(perllibdir))\n        @@ -68,7 +67,7 @@\n          localedir_SQ = $(subst ','\\'',$(localedir))\n         +localedir_relative_SQ = $(subst ','\\'',$(localedir_relative))\n          gitexecdir_SQ = $(subst ','\\'',$(gitexecdir))\n        -+gitexecdir_relative_SQ = $(subst ','\\'',$(gitexecdir_relative))\n        + gitexecdir_relative_SQ = $(subst ','\\'',$(gitexecdir_relative))\n          template_dir_SQ = $(subst ','\\'',$(template_dir))\n          htmldir_relative_SQ = $(subst ','\\'',$(htmldir_relative))\n          prefix_SQ = $(subst ','\\'',$(prefix))\n    3: a0e41f5f41 ! 3: 5220baf80e exec_cmd: RUNTIME_PREFIX on some POSIX systems\n        @@ -109,6 +109,8 @@\n         +  \n            git_setup_gettext();\n    \n        +   initialize_the_repository();\n        + \n            attr_start();\n    \n         -  git_extract_argv0_path(argv[0]);\n    4: b25be6e56d = 4: 57dcc5203e exec_cmd: provide a new-style RUNTIME_PREFIX helper for Windows\n    5: b329fde5a6 = 5: 2b1ed6a79a mingw/msvc: use the new-style RUNTIME_PREFIX helper\n"}]}