Git builds a static libgit.a, and many commands which link to libgit.a, resulting in many duplicate copies of the code in libgit.a. Add a USE_SHARED_LIBGIT flag to the Makefile (off by default), which builds and uses a shared library libgit.so instead. The existing objects in libgit.a reference the symbols git_version_string and git_usage_string, defined in git.c, but libgit does not include git.o, making the library not self-contained, and leading to linking errors when trying to use a shared library. Move those two symbols to help.c, where the references from libgit occur. This change does not install header files, versioned libraries, or anything else that would support actually using libgit.so from anything other than the installed git binaries. The built libgit.so exists solely for the benefit of the installed git binaries that link to it. Motivated by trying to install Git on a machine for which this makes the difference between remaining under quota and not. Signed-off-by: Josh Triplett <josh@xxxxxxxxxxxxxxx> --- Makefile | 31 ++++++++++++++++++++++++++----- git.c | 5 ----- help.c | 5 +++++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index a98e27a..db35b3b 100644 --- a/Makefile +++ b/Makefile @@ -124,6 +124,8 @@ all:: # If not set it defaults to the bare 'wish'. If it is set to the empty # string then NO_TCLTK will be forced (this is used by configure script). # +# Define USE_SHARED_LIBGIT to create and use a shared library libgit.so rather +# than a static library libgit.a. GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE @$(SHELL_PATH) ./GIT-VERSION-GEN @@ -146,6 +148,7 @@ STRIP ?= strip prefix = $(HOME) bindir = $(prefix)/bin gitexecdir = $(bindir) +libdir = $(prefix)/lib sharedir = $(prefix)/share template_dir = $(sharedir)/git-core/templates ifeq ($(prefix),/usr) @@ -290,7 +293,13 @@ endif export PERL_PATH +ifdef USE_SHARED_LIBGIT +LIB_FILE=libgit.so +LIBGIT=-L. -lgit +else LIB_FILE=libgit.a +LIBGIT=$(LIB_FILE) +endif XDIFF_LIB=xdiff/lib.a LIB_H = \ @@ -704,6 +713,7 @@ ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG)) DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) bindir_SQ = $(subst ','\'',$(bindir)) gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) +libdir_SQ = $(subst ','\'',$(libdir)) template_dir_SQ = $(subst ','\'',$(template_dir)) prefix_SQ = $(subst ','\'',$(prefix)) @@ -712,7 +722,7 @@ PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH)) TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH)) -LIBS = $(GITLIBS) $(EXTLIBS) +LIBS = $(LIBGIT) $(XDIFF_LIB) $(EXTLIBS) BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \ -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"' $(COMPAT_CFLAGS) @@ -721,6 +731,10 @@ LIB_OBJS += $(COMPAT_OBJS) ALL_CFLAGS += $(BASIC_CFLAGS) ALL_LDFLAGS += $(BASIC_LDFLAGS) +ifdef USE_SHARED_LIBGIT +ALL_CFLAGS += -fpic +endif + export TAR INSTALL DESTDIR SHELL_PATH @@ -747,16 +761,15 @@ gitk-wish: gitk GIT-GUI-VARS chmod +x $@+ && \ mv -f $@+ $@ -git.o: git.c common-cmds.h GIT-CFLAGS - $(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \ - $(ALL_CFLAGS) -c $(filter %.c,$^) +git.o: common-cmds.h git$X: git.o $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \ $(ALL_CFLAGS) -o $@ $(filter %.c,$^) git.o \ $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) -help.o: common-cmds.h +help.o: help.c common-cmds.h GIT-CFLAGS + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DGIT_VERSION='"$(GIT_VERSION)"' $< git-merge-subtree$X: git-merge-recursive$X $(QUIET_BUILT_IN)rm -f $@ && ln git-merge-recursive$X $@ @@ -908,7 +921,11 @@ $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) $(DIFF_OBJS): diffcore.h $(LIB_FILE): $(LIB_OBJS) +ifdef USE_SHARED_LIBGIT + $(QUIET_LINK)$(CC) -shared -o $@ $(LIB_OBJS) +else $(QUIET_AR)rm -f $@ && $(AR) rcs $@ $(LIB_OBJS) +endif XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \ xdiff/xmerge.o @@ -996,6 +1013,10 @@ install: all $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) git$X '$(DESTDIR_SQ)$(bindir_SQ)' +ifdef USE_SHARED_LIBGIT + $(INSTALL) -d -m755 $(DESTDIR_SQ)$(libdir_SQ) + $(INSTALL) $(LIB_FILE) $(DESTDIR_SQ)$(libdir_SQ) +endif $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(MAKE) -C perl prefix='$(prefix_SQ)' install ifndef NO_TCLTK diff --git a/git.c b/git.c index 29b55a1..1e24903 100644 --- a/git.c +++ b/git.c @@ -3,9 +3,6 @@ #include "cache.h" #include "quote.h" -const char git_usage_string[] = - "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]"; - static void prepend_to_path(const char *dir, int len) { const char *old_path = getenv("PATH"); @@ -206,8 +203,6 @@ static int handle_alias(int *argcp, const char ***argv) return ret; } -const char git_version_string[] = GIT_VERSION; - #define RUN_SETUP (1<<0) #define USE_PAGER (1<<1) /* diff --git a/help.c b/help.c index 1cd33ec..3f3ceeb 100644 --- a/help.c +++ b/help.c @@ -9,6 +9,11 @@ #include "common-cmds.h" #include <sys/ioctl.h> +const char git_usage_string[] = + "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]"; + +const char git_version_string[] = GIT_VERSION; + /* most GUI terminals set COLUMNS (although some don't export it) */ static int term_columns(void) { -- 1.5.2.2
Attachment:
signature.asc
Description: OpenPGP digital signature