From: Dan Jacques <dnj@google.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, avarab@gmail.com, Johannes.Schindelin@gmx.de,
Dan Jacques <dnj@google.com>
Subject: [PATCH v6 2/3] Makefile: add Perl runtime prefix support
Date: Sun, 18 Mar 2018 22:50:45 -0400 [thread overview]
Message-ID: <20180319025046.58052-3-dnj@google.com> (raw)
In-Reply-To: <20180319025046.58052-1-dnj@google.com>
Add a new Makefile flag, RUNTIME_PREFIX_PERL, which, when enabled,
configures Perl scripts to locate the Git installation's Perl support
libraries by resolving against the script's path, rather than
hard-coding that path at build-time.
RUNTIME_PREFIX_PERL requires that system paths are expressed relative to
a common installation directory, and uses that relationship to locate
support files based on the known starting point of the script being
executed, much like RUNTIME_PREFIX does for the Git binary.
This change enables Git's Perl scripts to work when their Git installation
is relocated or moved to another system.
Signed-off-by: Dan Jacques <dnj@google.com>
Thanks-to: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Thanks-to: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Makefile | 67 +++++++++++++++++++++++-
perl/Git/I18N.pm | 2 +-
| 40 ++++++++++++++
3 files changed, 107 insertions(+), 2 deletions(-)
create mode 100644 perl/header_templates/runtime_prefix.template.pl
diff --git a/Makefile b/Makefile
index e479822ce..101a98a78 100644
--- a/Makefile
+++ b/Makefile
@@ -434,6 +434,13 @@ all::
#
# When cross-compiling, define HOST_CPU as the canonical name of the CPU on
# which the built Git will run (for instance "x86_64").
+#
+# Define RUNTIME_PREFIX to configure Git to resolve its ancillary tooling and
+# support files relative to the location of the runtime binary, rather than
+# hard-coding them into the binary. Git installations built with RUNTIME_PREFIX
+# can be moved to arbitrary filesystem locations. RUNTIME_PREFIX also causes
+# Perl scripts to use a modified entry point header allowing them to resolve
+# support files at runtime.
GIT-VERSION-FILE: FORCE
@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -471,6 +478,8 @@ ARFLAGS = rcs
# mandir
# infodir
# htmldir
+# localedir
+# perllibdir
# This can help installing the suite in a relocatable way.
prefix = $(HOME)
@@ -492,9 +501,12 @@ lib = lib
# DESTDIR =
pathsep = :
+gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir))
mandir_relative = $(patsubst $(prefix)/%,%,$(mandir))
infodir_relative = $(patsubst $(prefix)/%,%,$(infodir))
+localedir_relative = $(patsubst $(prefix)/%,%,$(localedir))
htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir))
+perllibdir_relative = $(patsubst $(prefix)/%,%,$(perllibdir))
export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir
@@ -1740,10 +1752,13 @@ mandir_relative_SQ = $(subst ','\'',$(mandir_relative))
infodir_relative_SQ = $(subst ','\'',$(infodir_relative))
perllibdir_SQ = $(subst ','\'',$(perllibdir))
localedir_SQ = $(subst ','\'',$(localedir))
+localedir_relative_SQ = $(subst ','\'',$(localedir_relative))
gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
+gitexecdir_relative_SQ = $(subst ','\'',$(gitexecdir_relative))
template_dir_SQ = $(subst ','\'',$(template_dir))
htmldir_relative_SQ = $(subst ','\'',$(htmldir_relative))
prefix_SQ = $(subst ','\'',$(prefix))
+perllibdir_relative_SQ = $(subst ','\'',$(perllibdir_relative))
gitwebdir_SQ = $(subst ','\'',$(gitwebdir))
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
@@ -1754,6 +1769,31 @@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
DIFF_SQ = $(subst ','\'',$(DIFF))
PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA))
+# RUNTIME_PREFIX's resolution logic requires resource paths to be expressed
+# relative to each other and share an installation path.
+#
+# This is a dependnecy in:
+# - Git's binary RUNTIME_PREFIX logic in (see "exec_cmd.c").
+# - The runtime prefix Perl header (see
+# "perl/header_templates/runtime_prefix.template.pl").
+ifdef RUNTIME_PREFIX
+
+ifneq ($(filter /%,$(firstword $(gitexecdir_relative))),)
+$(error RUNTIME_PREFIX requires a relative gitexecdir, not: $(gitexecdir))
+endif
+
+ifneq ($(filter /%,$(firstword $(localedir_relative))),)
+$(error RUNTIME_PREFIX requires a relative localedir, not: $(localedir))
+endif
+
+ifndef NO_PERL
+ifneq ($(filter /%,$(firstword $(perllibdir_relative))),)
+$(error RUNTIME_PREFIX requires a relative perllibdir, not: $(perllibdir))
+endif
+endif
+
+endif
+
# We must filter out any object files from $(GITLIBS),
# as it is typically used like:
#
@@ -1974,10 +2014,31 @@ git.res: git.rc GIT-VERSION-FILE
# This makes sure we depend on the NO_PERL setting itself.
$(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS
+# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX
+# since the locale directory is injected.
+perl_localedir_SQ = $(localedir_SQ)
+
ifndef NO_PERL
PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl
PERL_DEFINES = $(PERL_PATH_SQ):$(PERLLIB_EXTRA_SQ):$(perllibdir_SQ)
+PERL_DEFINES := $(PERL_PATH_SQ) $(PERLLIB_EXTRA_SQ) $(perllibdir_SQ)
+PERL_DEFINES += $(RUNTIME_PREFIX)
+
+# Support Perl runtime prefix. In this mode, a different header is installed
+# into Perl scripts.
+ifdef RUNTIME_PREFIX
+
+PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl
+
+# Don't export a fixed $(localedir) path; it will be resolved by the Perl header
+# at runtime.
+perl_localedir_SQ =
+
+endif
+
+PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)
+
$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1{' \
@@ -1990,6 +2051,7 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE
chmod +x $@+ && \
mv $@+ $@
+PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))
GIT-PERL-DEFINES: FORCE
@FLAGS='$(PERL_DEFINES)'; \
if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \
@@ -2005,6 +2067,9 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile
sed -e 's=@@PATHSEP@@=$(pathsep)=g' \
-e 's=@@INSTLIBDIR@@='$$INSTLIBDIR'=g' \
-e 's=@@PERLLIBDIR@@='$(perllibdir_SQ)'=g' \
+ -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \
+ -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \
+ -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \
$< >$@+ && \
mv $@+ $@
@@ -2328,7 +2393,7 @@ endif
perl/build/lib/%.pm: perl/%.pm
$(QUIET_GEN)mkdir -p $(dir $@) && \
- sed -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \
+ sed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \
-e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \
< $< > $@
diff --git a/perl/Git/I18N.pm b/perl/Git/I18N.pm
index dba96fff0..bfb4fb67a 100644
--- a/perl/Git/I18N.pm
+++ b/perl/Git/I18N.pm
@@ -18,7 +18,7 @@ our @EXPORT_OK = @EXPORT;
sub __bootstrap_locale_messages {
our $TEXTDOMAIN = 'git';
- our $TEXTDOMAINDIR = $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';
+ our $TEXTDOMAINDIR ||= $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';
require POSIX;
POSIX->import(qw(setlocale));
--git a/perl/header_templates/runtime_prefix.template.pl b/perl/header_templates/runtime_prefix.template.pl
new file mode 100644
index 000000000..a18913967
--- /dev/null
+++ b/perl/header_templates/runtime_prefix.template.pl
@@ -0,0 +1,40 @@
+# BEGIN RUNTIME_PREFIX generated code.
+#
+# This finds our Git::* libraries relative to the script's runtime path.
+sub __git_system_path {
+ my ($relpath) = @_;
+ my $gitexecdir_relative = '@@GITEXECDIR_REL@@';
+
+ # GIT_EXEC_PATH is supplied by `git` or the test suite.
+ my $exec_path = $ENV{GIT_EXEC_PATH};
+ if ($exec_path eq "") {
+ # This can happen if this script is being directly invoked instead of run
+ # by "git".
+ require FindBin;
+ $exec_path = $FindBin::Bin;
+ }
+
+ # Trim off the relative gitexecdir path to get the system path.
+ (my $prefix = $exec_path) =~ s=${gitexecdir_relative}$==;
+
+ require File::Spec;
+ return File::Spec->catdir($prefix, $relpath);
+}
+
+BEGIN {
+ use lib split /@@PATHSEP@@/,
+ (
+ $ENV{GITPERLLIB} ||
+ do {
+ my $perllibdir = __git_system_path('@@PERLLIBDIR_REL@@');
+ (-e $perllibdir) || die("Invalid system path ($relpath): $path");
+ $perllibdir;
+ }
+ );
+
+ # Export the system locale directory to the I18N module. The locale directory
+ # is only installed if NO_GETTEXT is set.
+ $Git::I18N::TEXTDOMAINDIR = __git_system_path('@@LOCALEDIR_REL@@');
+}
+
+# END RUNTIME_PREFIX generated code.
--
2.15.0.chromium12
next prev parent reply other threads:[~2018-03-19 2:51 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-19 2:50 [PATCH v6 0/3] RUNTIME_PREFIX relocatable Git Dan Jacques
2018-03-19 2:50 ` [PATCH v6 1/3] Makefile: generate Perl header from template file Dan Jacques
2018-03-19 3:07 ` Eric Sunshine
2018-03-19 2:50 ` Dan Jacques [this message]
2018-03-19 17:14 ` [PATCH v6 2/3] Makefile: add Perl runtime prefix support Junio C Hamano
2018-03-19 17:21 ` Daniel Jacques
2018-03-19 19:12 ` Ævar Arnfjörð Bjarmason
2018-03-19 19:14 ` Daniel Jacques
2018-03-19 19:17 ` Daniel Jacques
2018-03-19 20:41 ` Junio C Hamano
2018-03-19 19:21 ` Ævar Arnfjörð Bjarmason
2018-03-19 19:47 ` Daniel Jacques
2018-03-19 21:32 ` Martin Ågren
2018-03-19 22:07 ` Daniel Jacques
2018-03-19 2:50 ` [PATCH v6 3/3] exec_cmd: RUNTIME_PREFIX on some POSIX systems Dan Jacques
2018-03-19 17:24 ` Junio C Hamano
2018-03-19 17:30 ` Daniel Jacques
2018-03-19 19:27 ` Ævar Arnfjörð Bjarmason
2018-03-19 19:38 ` Daniel Jacques
2018-03-19 17:02 ` [PATCH v6 0/3] RUNTIME_PREFIX relocatable Git Junio C Hamano
2018-03-19 19:30 ` Ævar Arnfjörð Bjarmason
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180319025046.58052-3-dnj@google.com \
--to=dnj@google.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.