summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile124
-rw-r--r--cgit.mk74
3 files changed, 80 insertions, 119 deletions
diff --git a/.gitignore b/.gitignore
index 487728b..8011b39 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
# Files I don't care to see in git-status/commit
cgit
cgit.conf
+CGIT-CFLAGS
VERSION
cgitrc.5
cgitrc.5.fo
diff --git a/Makefile b/Makefile
index 1127961..8c00190 100644
--- a/Makefile
+++ b/Makefile
@@ -23,13 +23,6 @@ DOC_MAN5 = $(patsubst %.txt,%,$(MAN5_TXT))
DOC_HTML = $(patsubst %.txt,%.html,$(MAN_TXT))
DOC_PDF = $(patsubst %.txt,%.pdf,$(MAN_TXT))
-# Define NO_STRCASESTR if you don't have strcasestr.
-#
-# Define NO_OPENSSL to disable linking with OpenSSL and use bundled SHA1
-# implementation (slower).
-#
-# Define NEEDS_LIBICONV if linking with libc is not enough (eg. Darwin).
-#
# Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.)
# do not support the 'size specifiers' introduced by C99, namely ll, hh,
# j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t).
@@ -39,22 +32,12 @@ DOC_PDF = $(patsubst %.txt,%.pdf,$(MAN_TXT))
#-include config.mak
#
-# Platform specific tweaks
-#
-
-VERSION: force-version
- @./gen-version.sh "$(CGIT_VERSION)"
--include VERSION
-
-uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
-uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
-uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
-
-#
# Let the user override the above settings.
#
-include cgit.conf
+export CGIT_SCRIPT_NAME CGIT_SCRIPT_PATH CGIT_DATA_PATH CGIT_CONFIG CACHE_ROOT
+
#
# Define a way to invoke make in subdirs quietly, shamelessly ripped
# from git.git
@@ -69,8 +52,6 @@ NO_SUBDIR = :
endif
ifndef V
- QUIET_CC = @echo ' ' CC $@;
- QUIET_LINK = @echo ' ' LINK $@;
QUIET_SUBDIR0 = +@subdir=
QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
$(MAKE) $(PRINT_DIR) -C $$subdir
@@ -78,107 +59,12 @@ ifndef V
export V
endif
-LDFLAGS ?=
-CFLAGS ?= -g -Wall
-CFLAGS += -Igit
-CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)'
-CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"'
-CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"'
-CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"'
-CFLAGS += -DCGIT_CACHE_ROOT='"$(CACHE_ROOT)"'
-
-ifeq ($(uname_O),Cygwin)
- NO_STRCASESTR = YesPlease
- NEEDS_LIBICONV = YesPlease
-endif
-
-ifeq ($(uname_S),$(filter $(uname_S),FreeBSD OpenBSD))
- # Apparantly libiconv is installed in /usr/local on BSD
- LDFLAGS += -L/usr/local/lib
- CFLAGS += -I/usr/local/include
- NEEDS_LIBICONV = yes
-endif
-
-GIT_OPTIONS = prefix=/usr NO_GETTEXT=1
-OBJECTS =
-
-ifdef NO_ICONV
- CFLAGS += -DNO_ICONV
-endif
-ifdef NO_STRCASESTR
- CFLAGS += -DNO_STRCASESTR
-endif
-ifdef NO_C99_FORMAT
- CFLAGS += -DNO_C99_FORMAT
-endif
-ifdef NO_OPENSSL
- CFLAGS += -DNO_OPENSSL
- GIT_OPTIONS += NO_OPENSSL=1
-else
- LDLIBS += -lcrypto
-endif
-
-ifdef NEEDS_LIBICONV
- LDLIBS += -liconv
-endif
-
-LDLIBS += git/libgit.a git/xdiff/lib.a -lz -lpthread
-
-OBJECTS += cgit.o
-OBJECTS += cache.o
-OBJECTS += cmd.o
-OBJECTS += configfile.o
-OBJECTS += html.o
-OBJECTS += parsing.o
-OBJECTS += scan-tree.o
-OBJECTS += shared.o
-OBJECTS += ui-atom.o
-OBJECTS += ui-blob.o
-OBJECTS += ui-clone.o
-OBJECTS += ui-commit.o
-OBJECTS += ui-diff.o
-OBJECTS += ui-log.o
-OBJECTS += ui-patch.o
-OBJECTS += ui-plain.o
-OBJECTS += ui-refs.o
-OBJECTS += ui-repolist.o
-OBJECTS += ui-shared.o
-OBJECTS += ui-snapshot.o
-OBJECTS += ui-ssdiff.o
-OBJECTS += ui-stats.o
-OBJECTS += ui-summary.o
-OBJECTS += ui-tag.o
-OBJECTS += ui-tree.o
-OBJECTS += vector.o
-
-dep_files := $(foreach f,$(OBJECTS),$(dir $f).deps/$(notdir $f).d)
-dep_dirs := $(addsuffix .deps,$(sort $(dir $OBJECTS)))
-
-$(dep_dirs):
- @mkdir -p $@
-
-missing_dep_dirs := $(filter-out $(wildcard $(dep_dirs)),$(dep_dirs))
-dep_file = $(dir $@).deps/$(notdir $@).d
-dep_args = -MF $(dep_file) -MMD -MP
-
.SUFFIXES:
-$(OBJECTS): %.o: %.c $(missing_dep_dirs)
- $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(CFLAGS) $<
-
-dep_files_present := $(wildcard $(dep_files))
-ifneq ($(dep_files_present),)
-include $(dep_files_present)
-endif
-
all:: cgit
-cgit: VERSION $(OBJECTS) libgit
- $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LDLIBS)
-
-libgit:
- $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 $(GIT_OPTIONS) libgit.a
- $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 $(GIT_OPTIONS) xdiff/lib.a
+cgit:
+ $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) -f ../cgit.mk ../cgit NO_CURL=1
test: all
$(QUIET_SUBDIR0)tests $(QUIET_SUBDIR1) all
@@ -259,7 +145,7 @@ get-git:
tags:
$(QUIET_TAGS)find . -name '*.[ch]' | xargs ctags
-.PHONY: all cgit get-git libgit force-version
+.PHONY: all cgit get-git
.PHONY: clean clean-doc cleanall
.PHONY: doc doc-html doc-man doc-pdf
.PHONY: install install-doc install-html install-man install-pdf
diff --git a/cgit.mk b/cgit.mk
new file mode 100644
index 0000000..4869c55
--- /dev/null
+++ b/cgit.mk
@@ -0,0 +1,74 @@
+# This Makefile is run in the "git" directory in order to re-use Git's
+# build variables and operating system detection. Hence all files in
+# CGit's directory must be prefixed with "../".
+include Makefile
+
+CGIT_PREFIX = ../
+
+# The CGIT_* variables are inherited when this file is called from the
+# main Makefile - they are defined there.
+
+$(CGIT_PREFIX)VERSION: force-version
+ @cd $(CGIT_PREFIX) && ./gen-version.sh "$(CGIT_VERSION)"
+-include $(CGIT_PREFIX)VERSION
+.PHONY: force-version
+
+# CGIT_CFLAGS is a separate variable so that we can track it separately
+# and avoid rebuilding all of Git when these variables change.
+CGIT_CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"'
+CGIT_CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"'
+CGIT_CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"'
+CGIT_CFLAGS += -DCGIT_CACHE_ROOT='"$(CACHE_ROOT)"'
+
+ifdef NO_C99_FORMAT
+ CFLAGS += -DNO_C99_FORMAT
+endif
+
+CGIT_OBJ_NAMES += cgit.o
+CGIT_OBJ_NAMES += cache.o
+CGIT_OBJ_NAMES += cmd.o
+CGIT_OBJ_NAMES += configfile.o
+CGIT_OBJ_NAMES += html.o
+CGIT_OBJ_NAMES += parsing.o
+CGIT_OBJ_NAMES += scan-tree.o
+CGIT_OBJ_NAMES += shared.o
+CGIT_OBJ_NAMES += ui-atom.o
+CGIT_OBJ_NAMES += ui-blob.o
+CGIT_OBJ_NAMES += ui-clone.o
+CGIT_OBJ_NAMES += ui-commit.o
+CGIT_OBJ_NAMES += ui-diff.o
+CGIT_OBJ_NAMES += ui-log.o
+CGIT_OBJ_NAMES += ui-patch.o
+CGIT_OBJ_NAMES += ui-plain.o
+CGIT_OBJ_NAMES += ui-refs.o
+CGIT_OBJ_NAMES += ui-repolist.o
+CGIT_OBJ_NAMES += ui-shared.o
+CGIT_OBJ_NAMES += ui-snapshot.o
+CGIT_OBJ_NAMES += ui-ssdiff.o
+CGIT_OBJ_NAMES += ui-stats.o
+CGIT_OBJ_NAMES += ui-summary.o
+CGIT_OBJ_NAMES += ui-tag.o
+CGIT_OBJ_NAMES += ui-tree.o
+CGIT_OBJ_NAMES += vector.o
+
+CGIT_OBJS := $(addprefix $(CGIT_PREFIX),$(CGIT_OBJ_NAMES))
+
+ifeq ($(wildcard $(CGIT_PREFIX).depend),)
+missing_dep_dirs += $(CGIT_PREFIX).depend
+endif
+
+$(CGIT_PREFIX).depend:
+ @mkdir -p $@
+
+$(CGIT_PREFIX)CGIT-CFLAGS: FORCE
+ @FLAGS='$(subst ','\'',$(CGIT_CFLAGS))'; \
+ if test x"$$FLAGS" != x"`cat ../CGIT-CFLAGS 2>/dev/null`" ; then \
+ echo 1>&2 " * new CGit build flags"; \
+ echo "$$FLAGS" >$(CGIT_PREFIX)CGIT-CFLAGS; \
+ fi
+
+$(CGIT_OBJS): %.o: %.c GIT-CFLAGS $(CGIT_PREFIX)CGIT-CFLAGS $(missing_dep_dirs)
+ $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $(CGIT_CFLAGS) $<
+
+$(CGIT_PREFIX)cgit: $(CGIT_OBJS) GIT-LDFLAGS $(GITLIBS)
+ $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
an class="o">*(struct refinfo **)a; struct refinfo *r2 = *(struct refinfo **)b; return strcmp(r1->refname, r2->refname); } static int cmp_branch_age(const void *a, const void *b) { struct refinfo *r1 = *(struct refinfo **)a; struct refinfo *r2 = *(struct refinfo **)b; return cmp_age(r1->commit->committer_date, r2->commit->committer_date); } static int get_ref_age(struct refinfo *ref) { if (!ref->object) return 0; switch (ref->object->type) { case OBJ_TAG: return ref->tag ? ref->tag->tagger_date : 0; case OBJ_COMMIT: return ref->commit ? ref->commit->committer_date : 0; } return 0; } static int cmp_tag_age(const void *a, const void *b) { struct refinfo *r1 = *(struct refinfo **)a; struct refinfo *r2 = *(struct refinfo **)b; return cmp_age(get_ref_age(r1), get_ref_age(r2)); } static int print_branch(struct refinfo *ref) { struct commitinfo *info = ref->commit; char *name = (char *)ref->refname; if (!info) return 1; html("<tr><td>"); cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL, ctx.qry.showmsg, 0); html("</td><td>"); if (ref->object->type == OBJ_COMMIT) { cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL); html("</td><td>"); cgit_open_filter(ctx.repo->email_filter, info->author_email, "refs"); html_txt(info->author); cgit_close_filter(ctx.repo->email_filter); html("</td><td colspan='2'>"); cgit_print_age(info->commit->date, -1, NULL); } else { html("</td><td></td><td>"); cgit_object_link(ref->object); } html("</td></tr>\n"); return 0; } static void print_tag_header(void) { html("<tr class='nohover'><th class='left'>Tag</th>" "<th class='left'>Download</th>" "<th class='left'>Author</th>" "<th class='left' colspan='2'>Age</th></tr>\n"); } static void print_tag_downloads(const struct cgit_repo *repo, const char *ref) { const struct cgit_snapshot_format* f; struct strbuf filename = STRBUF_INIT; const char *basename; int free_ref = 0; if (!ref || strlen(ref) < 1) return; basename = cgit_repobasename(repo->url); if (!starts_with(ref, basename)) { if ((ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1])) ref++; if (isdigit(ref[0])) { ref = fmtalloc("%s-%s", basename, ref); free_ref = 1; } } for (f = cgit_snapshot_formats; f->suffix; f++) { if (!(repo->snapshots & f->bit)) continue; strbuf_reset(&filename); strbuf_addf(&filename, "%s%s", ref, f->suffix); cgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL, filename.buf); html("&nbsp;&nbsp;"); } if (free_ref) free((char *)ref); strbuf_release(&filename); } static int print_tag(struct refinfo *ref) { struct tag *tag = NULL; struct taginfo *info = NULL; char *name = (char *)ref->refname; struct object *obj = ref->object; if (obj->type == OBJ_TAG) { tag = (struct tag *)obj; obj = tag->tagged; info = ref->tag; if (!tag || !info) return 1; } html("<tr><td>"); cgit_tag_link(name, NULL, NULL, name); html("</td><td>"); if (ctx.repo->snapshots && (obj->type == OBJ_COMMIT)) print_tag_downloads(ctx.repo, name); else cgit_object_link(obj); html("</td><td>"); if (info) { if (info->tagger) { cgit_open_filter(ctx.repo->email_filter, info->tagger_email, "refs"); html_txt(info->tagger); cgit_close_filter(ctx.repo->email_filter); } } else if (ref->object->type == OBJ_COMMIT) { cgit_open_filter(ctx.repo->email_filter, ref->commit->author_email, "refs"); html_txt(ref->commit->author); cgit_close_filter(ctx.repo->email_filter); } html("</td><td colspan='2'>"); if (info) { if (info->tagger_date > 0) cgit_print_age(info->tagger_date, -1, NULL); } else if (ref->object->type == OBJ_COMMIT) { cgit_print_age(ref->commit->commit->date, -1, NULL); } html("</td></tr>\n"); return 0; } static void print_refs_link(char *path) { html("<tr class='nohover'><td colspan='5'>"); cgit_refs_link("[...]", NULL, NULL, ctx.qry.head, NULL, path); html("</td></tr>"); } void cgit_print_branches(int maxcount) { struct reflist list; int i; html("<tr class='nohover'><th class='left'>Branch</th>" "<th class='left'>Commit message</th>" "<th class='left'>Author</th>" "<th class='left' colspan='2'>Age</th></tr>\n"); list.refs = NULL; list.alloc = list.count = 0; for_each_branch_ref(cgit_refs_cb, &list); if (ctx.repo->enable_remote_branches) for_each_remote_ref(cgit_refs_cb, &list); if (maxcount == 0 || maxcount > list.count) maxcount = list.count; qsort(list.refs, list.count, sizeof(*list.refs), cmp_branch_age); if (ctx.repo->branch_sort == 0) qsort(list.refs, maxcount, sizeof(*list.refs), cmp_ref_name); for (i = 0; i < maxcount; i++) print_branch(list.refs[i]); if (maxcount < list.count) print_refs_link("heads"); cgit_free_reflist_inner(&list); } void cgit_print_tags(int maxcount) { struct reflist list; int i; list.refs = NULL; list.alloc = list.count = 0; for_each_tag_ref(cgit_refs_cb, &list); if (list.count == 0) return; qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age); if (!maxcount) maxcount = list.count; else if (maxcount > list.count) maxcount = list.count; print_tag_header(); for (i = 0; i < maxcount; i++) print_tag(list.refs[i]); if (maxcount < list.count) print_refs_link("tags"); cgit_free_reflist_inner(&list); } void cgit_print_refs(void) { cgit_print_layout_start(); html("<table class='list nowrap'>"); if (ctx.qry.path && starts_with(ctx.qry.path, "heads")) cgit_print_branches(0); else if (ctx.qry.path && starts_with(ctx.qry.path, "tags")) cgit_print_tags(0); else { cgit_print_branches(0); html("<tr class='nohover'><td colspan='5'>&nbsp;</td></tr>"); cgit_print_tags(0); } html("</table>"); cgit_print_layout_end(); }