Skip to content

Commit 07d90ea

Browse files
danjacquesgitster
authored andcommitted
Makefile: add Perl runtime prefix support
Broaden the RUNTIME_PREFIX flag to configure Git's 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. Hard-coding at build time worked on previous RUNTIME_PREFIX configurations (i.e., Windows) because the Perl scripts were run within a virtual filesystem whose paths were consistent regardless of the location of the actual installation. This will no longer be the case for non-Windows RUNTIME_PREFIX users. When enabled, RUNTIME_PREFIX now requires Perl's system paths to be expressed relative to a common installation directory in the Makefile, 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, even when they are not in a virtual filesystem environment. Signed-off-by: Dan Jacques <[email protected]> Thanks-to: Ævar Arnfjörð Bjarmason <[email protected]> Thanks-to: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f6a0ad4 commit 07d90ea

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

Makefile

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,13 @@ all::
441441
#
442442
# When cross-compiling, define HOST_CPU as the canonical name of the CPU on
443443
# which the built Git will run (for instance "x86_64").
444+
#
445+
# Define RUNTIME_PREFIX to configure Git to resolve its ancillary tooling and
446+
# support files relative to the location of the runtime binary, rather than
447+
# hard-coding them into the binary. Git installations built with RUNTIME_PREFIX
448+
# can be moved to arbitrary filesystem locations. RUNTIME_PREFIX also causes
449+
# Perl scripts to use a modified entry point header allowing them to resolve
450+
# support files at runtime.
444451

445452
GIT-VERSION-FILE: FORCE
446453
@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -478,6 +485,8 @@ ARFLAGS = rcs
478485
# mandir
479486
# infodir
480487
# htmldir
488+
# localedir
489+
# perllibdir
481490
# This can help installing the suite in a relocatable way.
482491

483492
prefix = $(HOME)
@@ -502,7 +511,9 @@ bindir_relative = $(patsubst $(prefix)/%,%,$(bindir))
502511
mandir_relative = $(patsubst $(prefix)/%,%,$(mandir))
503512
infodir_relative = $(patsubst $(prefix)/%,%,$(infodir))
504513
gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir))
514+
localedir_relative = $(patsubst $(prefix)/%,%,$(localedir))
505515
htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir))
516+
perllibdir_relative = $(patsubst $(prefix)/%,%,$(perllibdir))
506517

507518
export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir
508519

@@ -1751,11 +1762,13 @@ mandir_relative_SQ = $(subst ','\'',$(mandir_relative))
17511762
infodir_relative_SQ = $(subst ','\'',$(infodir_relative))
17521763
perllibdir_SQ = $(subst ','\'',$(perllibdir))
17531764
localedir_SQ = $(subst ','\'',$(localedir))
1765+
localedir_relative_SQ = $(subst ','\'',$(localedir_relative))
17541766
gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
17551767
gitexecdir_relative_SQ = $(subst ','\'',$(gitexecdir_relative))
17561768
template_dir_SQ = $(subst ','\'',$(template_dir))
17571769
htmldir_relative_SQ = $(subst ','\'',$(htmldir_relative))
17581770
prefix_SQ = $(subst ','\'',$(prefix))
1771+
perllibdir_relative_SQ = $(subst ','\'',$(perllibdir_relative))
17591772
gitwebdir_SQ = $(subst ','\'',$(gitwebdir))
17601773

17611774
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
@@ -1766,6 +1779,31 @@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
17661779
DIFF_SQ = $(subst ','\'',$(DIFF))
17671780
PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA))
17681781

1782+
# RUNTIME_PREFIX's resolution logic requires resource paths to be expressed
1783+
# relative to each other and share an installation path.
1784+
#
1785+
# This is a dependency in:
1786+
# - Git's binary RUNTIME_PREFIX logic in (see "exec_cmd.c").
1787+
# - The runtime prefix Perl header (see
1788+
# "perl/header_templates/runtime_prefix.template.pl").
1789+
ifdef RUNTIME_PREFIX
1790+
1791+
ifneq ($(filter /%,$(firstword $(gitexecdir_relative))),)
1792+
$(error RUNTIME_PREFIX requires a relative gitexecdir, not: $(gitexecdir))
1793+
endif
1794+
1795+
ifneq ($(filter /%,$(firstword $(localedir_relative))),)
1796+
$(error RUNTIME_PREFIX requires a relative localedir, not: $(localedir))
1797+
endif
1798+
1799+
ifndef NO_PERL
1800+
ifneq ($(filter /%,$(firstword $(perllibdir_relative))),)
1801+
$(error RUNTIME_PREFIX requires a relative perllibdir, not: $(perllibdir))
1802+
endif
1803+
endif
1804+
1805+
endif
1806+
17691807
# We must filter out any object files from $(GITLIBS),
17701808
# as it is typically used like:
17711809
#
@@ -1986,10 +2024,31 @@ git.res: git.rc GIT-VERSION-FILE
19862024
# This makes sure we depend on the NO_PERL setting itself.
19872025
$(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS
19882026

2027+
# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX
2028+
# since the locale directory is injected.
2029+
perl_localedir_SQ = $(localedir_SQ)
2030+
19892031
ifndef NO_PERL
19902032
PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl
19912033
PERL_DEFINES = $(PERL_PATH_SQ):$(PERLLIB_EXTRA_SQ):$(perllibdir_SQ)
19922034

2035+
PERL_DEFINES := $(PERL_PATH_SQ) $(PERLLIB_EXTRA_SQ) $(perllibdir_SQ)
2036+
PERL_DEFINES += $(RUNTIME_PREFIX)
2037+
2038+
# Support Perl runtime prefix. In this mode, a different header is installed
2039+
# into Perl scripts.
2040+
ifdef RUNTIME_PREFIX
2041+
2042+
PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl
2043+
2044+
# Don't export a fixed $(localedir) path; it will be resolved by the Perl header
2045+
# at runtime.
2046+
perl_localedir_SQ =
2047+
2048+
endif
2049+
2050+
PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)
2051+
19932052
$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE
19942053
$(QUIET_GEN)$(RM) $@ $@+ && \
19952054
sed -e '1{' \
@@ -2002,6 +2061,7 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE
20022061
chmod +x $@+ && \
20032062
mv $@+ $@
20042063

2064+
PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))
20052065
GIT-PERL-DEFINES: FORCE
20062066
@FLAGS='$(PERL_DEFINES)'; \
20072067
if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \
@@ -2017,6 +2077,9 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile
20172077
sed -e 's=@@PATHSEP@@=$(pathsep)=g' \
20182078
-e 's=@@INSTLIBDIR@@='$$INSTLIBDIR'=g' \
20192079
-e 's=@@PERLLIBDIR@@='$(perllibdir_SQ)'=g' \
2080+
-e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \
2081+
-e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \
2082+
-e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \
20202083
$< >$@+ && \
20212084
mv $@+ $@
20222085

@@ -2340,7 +2403,7 @@ endif
23402403

23412404
perl/build/lib/%.pm: perl/%.pm
23422405
$(QUIET_GEN)mkdir -p $(dir $@) && \
2343-
sed -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \
2406+
sed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \
23442407
-e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \
23452408
< $< > $@
23462409

perl/Git/I18N.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ our @EXPORT_OK = @EXPORT;
1818

1919
sub __bootstrap_locale_messages {
2020
our $TEXTDOMAIN = 'git';
21-
our $TEXTDOMAINDIR = $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';
21+
our $TEXTDOMAINDIR ||= $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';
2222

2323
require POSIX;
2424
POSIX->import(qw(setlocale));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# BEGIN RUNTIME_PREFIX generated code.
2+
#
3+
# This finds our Git::* libraries relative to the script's runtime path.
4+
sub __git_system_path {
5+
my ($relpath) = @_;
6+
my $gitexecdir_relative = '@@GITEXECDIR_REL@@';
7+
8+
# GIT_EXEC_PATH is supplied by `git` or the test suite.
9+
my $exec_path;
10+
if (exists $ENV{GIT_EXEC_PATH}) {
11+
$exec_path = $ENV{GIT_EXEC_PATH};
12+
} else {
13+
# This can happen if this script is being directly invoked instead of run
14+
# by "git".
15+
require FindBin;
16+
$exec_path = $FindBin::Bin;
17+
}
18+
19+
# Trim off the relative gitexecdir path to get the system path.
20+
(my $prefix = $exec_path) =~ s/\Q$gitexecdir_relative\E$//;
21+
22+
require File::Spec;
23+
return File::Spec->catdir($prefix, $relpath);
24+
}
25+
26+
BEGIN {
27+
use lib split /@@PATHSEP@@/,
28+
(
29+
$ENV{GITPERLLIB} ||
30+
do {
31+
my $perllibdir = __git_system_path('@@PERLLIBDIR_REL@@');
32+
(-e $perllibdir) || die("Invalid system path ($relpath): $path");
33+
$perllibdir;
34+
}
35+
);
36+
37+
# Export the system locale directory to the I18N module. The locale directory
38+
# is only installed if NO_GETTEXT is set.
39+
$Git::I18N::TEXTDOMAINDIR = __git_system_path('@@LOCALEDIR_REL@@');
40+
}
41+
42+
# END RUNTIME_PREFIX generated code.

0 commit comments

Comments
 (0)