aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Makefile
blob: cf32c0aed1151323b4267fe5e60756770da42147 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
CGIT_VERSION = v0.7.2
CGIT_SCRIPT_NAME = cgit.cgi
CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
CGIT_CONFIG = /etc/cgitrc
CACHE_ROOT = /var/cache/cgit
SHA1_HEADER = <openssl/sha.h>
GIT_VER = 1.5.5.1
GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2

#
# Let the user override the above settings.
#
-include cgit.conf

#
# Define a way to invoke make in subdirs quietly, shamelessly ripped
# from git.git
#
QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
QUIET_SUBDIR1  =

ifneq ($(findstring $(MAKEFLAGS),w),w)
PRINT_DIR = --no-print-directory
else # "make -w"
NO_SUBDIR = :
endif

ifndef V
	QUIET_CC       = @echo '   ' CC $@;
	QUIET_MM       = @echo '   ' MM $@;
	QUIET_SUBDIR0  = +@subdir=
	QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
			 $(MAKE) $(PRINT_DIR) -C $$subdir
endif

#
# Define a pattern rule for automatic dependency building
#
%.d: %.c
	$(QUIET_MM)$(CC) $(CFLAGS) -MM $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@

#
# Define a pattern rule for silent object building
#
%.o: %.c
	$(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<


EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
OBJECTS =
OBJECTS += cache.o
OBJECTS += cgit.o
OBJECTS += cmd.o
OBJECTS += configfile.o
OBJECTS += html.o
OBJECTS += parsing.o
OBJECTS += shared.o
OBJECTS += ui-blob.o
OBJECTS += ui-commit.o
OBJECTS += ui-diff.o
OBJECTS += ui-log.o
OBJECTS += ui-patch.o
OBJECTS += ui-refs.o
OBJECTS += ui-repolist.o
OBJECTS += ui-shared.o
OBJECTS += ui-snapshot.o
OBJECTS += ui-summary.o
OBJECTS += ui-tag.o
OBJECTS += ui-tree.o

ifdef NEEDS_LIBICONV
	EXTLIBS += -liconv
endif


.PHONY: all git test install clean distclean emptycache force-version get-git

all: cgit git

VERSION: force-version
	@./gen-version.sh "$(CGIT_VERSION)"
-include VERSION


CFLAGS += -g -Wall -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)"'


cgit: $(OBJECTS)
	$(QUIET_CC)$(CC) $(CFLAGS) -o cgit $(OBJECTS) $(EXTLIBS)

$(OBJECTS): git/xdiff/lib.a git/libgit.a

cgit.o: VERSION

-include $(OBJECTS:.o=.d)

git/xdiff/lib.a: | git

git/libgit.a: | git

git:
	$(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) xdiff/lib.a
	$(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) libgit.a

test: all
	$(QUIET_SUBDIR0)tests $(QUIET_SUBDIR1) all

install: all
	mkdir -p $(DESTDIR)$(CGIT_SCRIPT_PATH)
	install cgit $(DESTDIR)$(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME)
	install cgit.css $(DESTDIR)$(CGIT_SCRIPT_PATH)/cgit.css
	install cgit.png $(DESTDIR)$(CGIT_SCRIPT_PATH)/cgit.png

uninstall:
	rm -f $(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME)
	rm -f $(CGIT_SCRIPT_PATH)/cgit.css
	rm -f $(CGIT_SCRIPT_PATH)/cgit.png

clean:
	rm -f cgit VERSION *.o *.d
	cd git && $(MAKE) clean

distclean: clean
	git clean -d -x
	cd git && git clean -d -x

emptycache:
	rm -rf $(DESTDIR)$(CACHE_ROOT)/*

get-git:
	curl $(GIT_URL) | tar -xj && rm -rf git && mv git-$(GIT_VER) git
>t; if (get_repo_modtime(repo, &t)) cgit_print_age(t, -1, NULL); } int is_match(struct cgit_repo *repo) { if (!ctx.qry.search) return 1; if (repo->url && strcasestr(repo->url, ctx.qry.search)) return 1; if (repo->name && strcasestr(repo->name, ctx.qry.search)) return 1; if (repo->desc && strcasestr(repo->desc, ctx.qry.search)) return 1; if (repo->owner && strcasestr(repo->owner, ctx.qry.search)) return 1; return 0; } int is_in_url(struct cgit_repo *repo) { if (!ctx.qry.url) return 1; if (repo->url && !prefixcmp(repo->url, ctx.qry.url)) return 1; return 0; } void print_sort_header(const char *title, const char *sort) { htmlf("<th class='left'><a href='./?s=%s", sort); if (ctx.qry.search) { html("&q="); html_url_arg(ctx.qry.search); } htmlf("'>%s</a></th>", title); } void print_header(int columns) { html("<tr class='nohover'>"); print_sort_header("Name", "name"); print_sort_header("Description", "desc"); print_sort_header("Owner", "owner"); print_sort_header("Idle", "idle"); if (ctx.cfg.enable_index_links) html("<th class='left'>Links</th>"); html("</tr>\n"); } void print_pager(int items, int pagelen, char *search) { int i; html("<div class='pager'>"); for(i = 0; i * pagelen < items; i++) cgit_index_link(fmt("[%d]", i+1), fmt("Page %d", i+1), NULL, search, i * pagelen); html("</div>"); } static int cmp(const char *s1, const char *s2) { if (s1 && s2) return strcmp(s1, s2); if (s1 && !s2) return -1; if (s2 && !s1) return 1; return 0; } static int sort_name(const void *a, const void *b) { const struct cgit_repo *r1 = a; const struct cgit_repo *r2 = b; return cmp(r1->name, r2->name); } static int sort_desc(const void *a, const void *b) { const struct cgit_repo *r1 = a; const struct cgit_repo *r2 = b; return cmp(r1->desc, r2->desc); } static int sort_owner(const void *a, const void *b) { const struct cgit_repo *r1 = a; const struct cgit_repo *r2 = b; return cmp(r1->owner, r2->owner); } static int sort_idle(const void *a, const void *b) { const struct cgit_repo *r1 = a; const struct cgit_repo *r2 = b; time_t t1, t2; t1 = t2 = 0; get_repo_modtime(r1, &t1); get_repo_modtime(r2, &t2); return t2 - t1; } struct sortcolumn { const char *name; int (*fn)(const void *a, const void *b); }; struct sortcolumn sortcolumn[] = { {"name", sort_name}, {"desc", sort_desc}, {"owner", sort_owner}, {"idle", sort_idle}, {NULL, NULL} }; int sort_repolist(char *field) { struct sortcolumn *column; for (column = &sortcolumn[0]; column->name; column++) { if (strcmp(field, column->name)) continue; qsort(cgit_repolist.repos, cgit_repolist.count, sizeof(struct cgit_repo), column->fn); return 1; } return 0; } void cgit_print_repolist() { int i, columns = 4, hits = 0, header = 0; char *last_group = NULL; int sorted = 0; if (ctx.cfg.enable_index_links) columns++; ctx.page.title = ctx.cfg.root_title; cgit_print_http_headers(&ctx); cgit_print_docstart(&ctx); cgit_print_pageheader(&ctx); if (ctx.cfg.index_header) html_include(ctx.cfg.index_header); if(ctx.qry.sort) sorted = sort_repolist(ctx.qry.sort); html("<table summary='repository list' class='list nowrap'>"); for (i=0; i<cgit_repolist.count; i++) { ctx.repo = &cgit_repolist.repos[i]; if (!(is_match(ctx.repo) && is_in_url(ctx.repo))) continue; hits++; if (hits <= ctx.qry.ofs) continue; if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count) continue; if (!header++) print_header(columns); if (!sorted && ((last_group == NULL && ctx.repo->group != NULL) || (last_group != NULL && ctx.repo->group == NULL) || (last_group != NULL && ctx.repo->group != NULL && strcmp(ctx.repo->group, last_group)))) { htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>", columns); html_txt(ctx.repo->group); html("</td></tr>"); last_group = ctx.repo->group; } htmlf("<tr><td class='%s'>", !sorted && ctx.repo->group ? "sublevel-repo" : "toplevel-repo"); cgit_summary_link(ctx.repo->name, ctx.repo->name, NULL, NULL); html("</td><td>"); html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL); html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc); html_link_close(); html("</td><td>"); html_txt(ctx.repo->owner); html("</td><td>"); print_modtime(ctx.repo); html("</td>"); if (ctx.cfg.enable_index_links) { html("<td>"); cgit_summary_link("summary", NULL, "button", NULL); cgit_log_link("log", NULL, "button", NULL, NULL, NULL, 0, NULL, NULL, ctx.qry.showmsg); cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL); html("</td>"); } html("</tr>\n"); } html("</table>"); if (!hits) cgit_print_error("No repositories found"); else if (hits > ctx.cfg.max_repo_count) print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search); cgit_print_docend(); } void cgit_print_site_readme() { if (ctx.cfg.root_readme) html_include(ctx.cfg.root_readme); }