blob: 7d53028b7aa95f01d68b4db18e788b0acc231734 (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# cgit top-level Makefile. cgit itself is compiled inside the bundled Git tree
# by source/cgit.mk, which this file invokes; everything else (docs, install,
# packaging, maintenance) is driven from here.

.DEFAULT_GOAL := all
.SUFFIXES:

# Project layout. Sources live in source/, web assets in assets/, Lua filters
# in extensions/, the bundled Git tree in libraries/git, and every generated
# file lands in build/. CGIT_ROOT reaches from the Git tree back to the root.
SRCDIR   = source
ASSETDIR = assets
EXTDIR   = extensions
GITDIR   = libraries/git
BUILDDIR = build
CGIT_ROOT = ../..

# Git release fetched by get-git when the submodule is not checked out. Keep in
# step with the submodule pin in .gitmodules.
GIT_VERSION = 2.54.0
GIT_URL = https://www.kernel.org/pub/software/scm/git/git-$(GIT_VERSION).tar.xz

# Compiled-in cgit defaults, overridable through cgit.conf. All carry the CGIT_
# prefix except CACHE_ROOT, inherited from upstream under that name.
CGIT_VERSION = v2.1.0
CGIT_SCRIPT_NAME = cgit.cgi
CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH)
CGIT_CONFIG = /etc/cgitrc
CACHE_ROOT = /var/cache/cgit

# Standard GNU-style install directories, lowercase so packaging can override
# them; filterdir is the one cgit-specific addition.
prefix = /usr/local
libdir = $(prefix)/lib
filterdir = $(libdir)/cgit/filters
docdir = $(prefix)/share/doc/cgit
htmldir = $(docdir)
mandir = $(prefix)/share/man

# Files installed into the data path and the filter dir. One list each drives
# both install and uninstall, so the two can never drift apart.
ASSETS       = cgit.css cgit.js cgit.png favicon.ico robots.txt
FILTER_FILES = $(notdir $(wildcard $(EXTDIR)/*.lua))

# Extra files and whole trees the dist target bundles into the release tarball,
# alongside the binary and the assets above.
DIST_DOCS  = cgitrc.5.txt README.txt LICENSE.txt AUTHORS
DIST_TREES = $(EXTDIR) examples
DIST_NAME  = cgit-$(CGIT_VERSION)
DIST_DIR   = $(BUILDDIR)/$(DIST_NAME)

# The man-page source (*.5.txt) sits at the project root and is rendered into
# build/. Only one man section exists, so DOC_* derive straight from MAN5_TXT.
MAN5_TXT = $(wildcard *.5.txt)
DOC_MAN5 = $(patsubst %.txt,$(BUILDDIR)/%,$(MAN5_TXT))
DOC_HTML = $(patsubst %.txt,$(BUILDDIR)/%.html,$(MAN5_TXT))

INSTALL = install
COPYTREE = cp -r
ASCIIDOC = asciidoc
ASCIIDOC_EXTRA =
ASCIIDOC_HTML = xhtml11
ASCIIDOC_COMMON = $(ASCIIDOC) $(ASCIIDOC_EXTRA)
TXT_TO_HTML = $(ASCIIDOC_COMMON) -b $(ASCIIDOC_HTML)

# Reuse Git's platform detection, then let the user override any of the settings
# above through cgit.conf. Both includes must stay after the defaults.
-include $(GITDIR)/config.mak.uname
-include cgit.conf

export CGIT_VERSION CGIT_SCRIPT_NAME CGIT_SCRIPT_PATH CGIT_DATA_PATH CGIT_CONFIG CACHE_ROOT

all: cgit

# cgit is compiled inside the bundled Git tree so it can reuse Git's build
# machinery (see source/cgit.mk). Objects and the binary go to build/.
cgit:
	+@$(MAKE) -C $(GITDIR) -f $(CGIT_ROOT)/$(SRCDIR)/cgit.mk \
		$(CGIT_ROOT)/$(BUILDDIR)/cgit $(EXTRA_GIT_TARGETS) NO_CURL=1 NO_OPENSSL=1

sparse:
	+@$(MAKE) -C $(GITDIR) -f $(CGIT_ROOT)/$(SRCDIR)/cgit.mk \
		NO_CURL=1 NO_OPENSSL=1 cgit-sparse

test: cgit-with-git
	+@$(MAKE) -C tests all

# The test helpers link against a fully built Git tree, so this asks the
# sub-make for Git's own `all` alongside cgit.
cgit-with-git:
	+@$(MAKE) cgit EXTRA_GIT_TARGETS=all

doc: doc-man doc-html
doc-man: $(DOC_MAN5)
doc-html: $(DOC_HTML)

$(DOC_MAN5): $(BUILDDIR)/%.5 : %.5.txt
	@mkdir -p $(BUILDDIR)
	a2x -f manpage -D $(BUILDDIR) $<

$(DOC_HTML): $(BUILDDIR)/%.html : %.txt
	@mkdir -p $(BUILDDIR)
	$(TXT_TO_HTML) -o $@ $<

install: all
	$(INSTALL) -m 0755 -d $(DESTDIR)$(CGIT_SCRIPT_PATH)
	$(INSTALL) -m 0755 $(BUILDDIR)/cgit $(DESTDIR)$(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME)
	$(INSTALL) -m 0755 -d $(DESTDIR)$(CGIT_DATA_PATH)
	$(INSTALL) -m 0644 $(addprefix $(ASSETDIR)/,$(ASSETS)) $(DESTDIR)$(CGIT_DATA_PATH)
	$(INSTALL) -m 0755 -d $(DESTDIR)$(filterdir)
	$(INSTALL) -m 0644 $(EXTDIR)/*.lua $(DESTDIR)$(filterdir)

install-doc: install-man install-html

install-man: doc-man
	$(INSTALL) -m 0755 -d $(DESTDIR)$(mandir)/man5
	$(INSTALL) -m 0644 $(DOC_MAN5) $(DESTDIR)$(mandir)/man5

install-html: doc-html
	$(INSTALL) -m 0755 -d $(DESTDIR)$(htmldir)
	$(INSTALL) -m 0644 $(DOC_HTML) $(DESTDIR)$(htmldir)

uninstall:
	$(RM) $(DESTDIR)$(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME)
	$(RM) $(addprefix $(DESTDIR)$(CGIT_DATA_PATH)/,$(ASSETS))
	$(RM) $(addprefix $(DESTDIR)$(filterdir)/,$(FILTER_FILES))

uninstall-doc: uninstall-man uninstall-html

uninstall-man:
	@for i in $(notdir $(DOC_MAN5)); do \
	    rm -fv $(DESTDIR)$(mandir)/man5/$$i; \
	done

uninstall-html:
	@for i in $(notdir $(DOC_HTML)); do \
	    rm -fv $(DESTDIR)$(htmldir)/$$i; \
	done

# Stage a release tarball under build/ from an already-built binary. It has no
# `all` prerequisite on purpose, so tools/release-build.sh keeps ownership of
# the hardening flags rather than triggering a plain rebuild here.
dist:
	@test -f $(BUILDDIR)/cgit || { echo 'build/cgit missing, run make first' >&2; exit 1; }
	$(RM) -r $(DIST_DIR)
	$(INSTALL) -m 0755 -d $(DIST_DIR)
	$(INSTALL) -m 0755 $(BUILDDIR)/cgit $(DIST_DIR)/$(CGIT_SCRIPT_NAME)
	$(INSTALL) -m 0644 $(addprefix $(ASSETDIR)/,$(ASSETS)) $(DIST_DIR)
	$(INSTALL) -m 0644 $(DIST_DOCS) $(DIST_DIR)
	$(COPYTREE) $(DIST_TREES) $(DIST_DIR)
	tar czf $(DIST_DIR).tar.gz -C $(BUILDDIR) $(DIST_NAME)

# Compiled output lives under build/; the test suite writes into tests/, so
# cleaning removes both. The tests descent is guarded because tests/Makefile
# includes git's config.mak.uname, which needs the submodule present.
clean:
	$(RM) -r $(BUILDDIR)
	@if test -e $(GITDIR)/config.mak.uname; then $(MAKE) -C tests clean; fi

cleanall: clean
	@if test -e $(GITDIR)/Makefile; then $(MAKE) -C $(GITDIR) clean; fi

# Fetch a Git release tarball for builds without the submodule checked out.
get-git:
	mkdir -p $(dir $(GITDIR))
	curl -L $(GIT_URL) | tar -xJf - && rm -rf $(GITDIR) && mv git-$(GIT_VERSION) $(GITDIR)

tags:
	@mkdir -p $(BUILDDIR)
	find $(SRCDIR) -name '*.[ch]' | xargs ctags -f $(BUILDDIR)/tags

# Grouped to mirror the order of the targets above.
.PHONY: all cgit cgit-with-git sparse test
.PHONY: doc doc-man doc-html
.PHONY: install install-doc install-man install-html
.PHONY: uninstall uninstall-doc uninstall-man uninstall-html
.PHONY: dist clean cleanall get-git tags