]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - Makefile
setup: pass --reactor=poll to trial unless REACTOR variable is set, in which case...
[tahoe-lafs/tahoe-lafs.git] / Makefile
1
2 # NOTE: this Makefile requires GNU make
3
4 default: build
5
6 PYTHON=python
7 PATHSEP=$(shell $(PYTHON) -c 'import os ; print os.pathsep')
8 OSSEP=$(shell $(PYTHON) -c 'import os ; print os.sep')
9
10 ifneq ($(INCLUDE_DIRS),)
11 INCLUDE_DIRS_ARG = -I$(INCLUDE_DIRS)
12 endif
13 ifneq ($(LIBRARY_DIRS),)
14 LIBRARY_DIRS_ARG = -L$(LIBRARY_DIRS)
15 endif
16
17 PLAT = $(strip $(shell $(PYTHON) -c "import sys ; print sys.platform"))
18 ifeq ($(PLAT),win32)
19         # The platform is Windows with cygwin build tools and the native Python interpreter.
20         SUPPORT = $(shell cygpath -w $(shell pwd))\support
21         SUPPORTLIB := $(SUPPORT)\Lib\site-packages
22         SRCPATH := $(shell cygpath -w $(shell pwd)/src)
23         INNOSETUP := $(shell cygpath -au "$(PROGRAMFILES)/Inno Setup 5/Compil32.exe")
24 else
25         PYVER=$(shell $(PYTHON) misc/pyver.py)
26         SUPPORT = $(shell pwd)/support
27         SUPPORTLIB = $(SUPPORT)/lib/$(PYVER)/site-packages
28         SRCPATH := $(shell pwd)/src
29         CHECK_PYWIN32_DEP := 
30 endif
31
32 ifneq ($(REACTOR),)
33         REACTOROPT := --reactor=$(REACTOR)
34 else
35         REACTOROPT := --reactor=poll
36 endif
37
38 ifneq ($(PYTHONPATH),)
39         PP=PYTHONPATH="$(PYTHONPATH)$(PATHSEP)$(SUPPORTLIB)"
40 else
41         PP=PYTHONPATH="$(SUPPORTLIB)"
42 endif
43
44 TRIALCMD = $(shell PATH="${PATH}:${PWD}/support/bin" $(PP) $(PYTHON) misc/find_trial.py)
45 TRIAL=PATH="${PATH}:${PWD}/support/bin" PYTHONUNBUFFERED=1 $(TRIALCMD) --rterrors $(REACTOROPT)
46
47 .PHONY: make-version build
48
49 # The 'darcsver' setup.py command comes in the 'darcsver' package:
50 # http://pypi.python.org/pypi/darcsver It is necessary only if you want to
51 # automatically produce a new _version.py file from the current darcs history.
52 make-version:
53         $(PP) $(PYTHON) ./setup.py darcsver --count-all-patches
54
55 # We want src/allmydata/_version.py to be up-to-date, but it's a fairly
56 # expensive operation (about 6 seconds on a just-before-0.7.0 tree, probably
57 # because of the 332 patches since the last tag), and we've removed the need
58 # for an explicit 'build' step by removing the C code from src/allmydata and
59 # by running everything in place. It would be neat to do:
60 #
61 #src/allmydata/_version.py: _darcs/patches
62 #       $(MAKE) make-version
63 #
64 # since that would update the embedded version string each time new darcs
65 # patches were pulled, but 1) this would break non-darcs trees (i.e. building
66 # from an exported tarball), and 2) without an obligatory 'build' step this
67 # rule wouldn't be run frequently enought anyways.
68 #
69 # So instead, I'll just make sure that we update the version at least once
70 # when we first start using the tree, and again whenever an explicit
71 # 'make-version' is run, since then at least the developer has some means to
72 # update things. It would be nice if 'make clean' deleted any
73 # automatically-generated _version.py too, so that 'make clean; make all'
74 # could be useable as a "what the heck is going on, get me back to a clean
75 # state', but we need 'make clean' to work on non-darcs trees without
76 # destroying useful information.
77
78 .built:
79         $(MAKE) build
80
81 src/allmydata/_version.py:
82         $(MAKE) make-version
83
84 # c.f. ticket #455, there is a problem in the intersection of setuptools,
85 # twisted's setup.py, and nevow's setup.py . A Tahoe build, to satisfy its
86 # dependencies, may try to build both Twisted and Nevow. If both of these
87 # occur during the same invocation of 'setup.py develop', then the Nevow
88 # build will fail with an "ImportError: No module named components". Running
89 # the build a second time will succeed. Until there is a new version of
90 # setuptools which properly sandboxes sys.modules (or a new version of nevow
91 # which doesn't import twisted during its build, or a new version of twisted
92 # which doesn't import itself during its build), we just build tahoe twice
93 # and ignore the errors from the first pass.
94
95 build: src/allmydata/_version.py
96         -$(MAKE) build-once
97         $(MAKE) build-once
98
99 build-once:
100         mkdir -p "$(SUPPORTLIB)"
101         $(PP) $(PYTHON) ./setup.py develop --prefix="$(SUPPORT)"
102         chmod +x bin/tahoe
103         touch .built
104
105 # 'make install' will do the following:
106 #   build+install tahoe (probably to /usr/lib/pythonN.N/site-packages)
107 # 'make install PREFIX=/usr/local/stow/tahoe-N.N' will do the same, but to
108 # a different location
109
110 install: src/allmydata/_version.py
111 ifdef PREFIX
112         mkdir -p $(PREFIX)
113         $(PP) $(PYTHON) ./setup.py install \
114            --single-version-externally-managed \
115            --prefix=$(PREFIX) --record=./tahoe.files
116 else
117         $(PP) $(PYTHON) ./setup.py install \
118            --single-version-externally-managed
119 endif
120
121
122 # TESTING
123
124 .PHONY: signal-error-deps test test-figleaf figleaf-output
125
126
127 signal-error-deps:
128         @echo
129         @echo
130         @echo "ERROR: Not all of Tahoe's dependencies are in place.  Please see docs/install.html for help on installing dependencies."
131         @echo
132         @echo
133         exit 1
134
135 check-auto-deps:
136         @$(PP) $(PYTHON) -c 'import _auto_deps ; _auto_deps.require_auto_deps()' || $(MAKE) signal-error-deps
137
138 .checked-deps:
139         $(MAKE) check-auto-deps
140         touch .checked-deps
141
142 # you can use 'make test TEST=allmydata.test.test_introducer' to run just
143 # test_introducer. TEST=allmydata.test.test_client.Basic.test_permute works
144 # too.
145 TEST=allmydata
146
147 # use 'make test TRIALARGS=--reporter=bwverbose' from buildbot, to
148 # suppress the ansi color sequences
149
150 test: build src/allmydata/_version.py
151         $(PP) $(TRIAL) $(TRIALARGS) $(TEST)
152
153 quicktest: .built .checked-deps
154         $(PP) $(TRIAL) $(TRIALARGS) $(TEST)
155
156 test-figleaf: build src/allmydata/_version.py
157         rm -f .figleaf
158         $(PP) $(TRIAL) --reporter=bwverbose-figleaf $(TEST)
159
160 quicktest-figleaf: src/allmydata/_version.py
161         rm -f .figleaf
162         $(PP) $(TRIAL) --reporter=bwverbose-figleaf $(TEST)
163
164 figleaf-output:
165         $(PP) \
166          $(PYTHON) misc/figleaf2html -d coverage-html -r src -x misc/figleaf.excludes
167         @echo "now point your browser at coverage-html/index.html"
168
169 # after doing test-figleaf and figleaf-output, point your browser at
170 # coverage-html/index.html
171
172 .PHONY: upload-figleaf .figleaf.el pyflakes count-lines
173 .PHONY: check-memory check-memory-once clean
174
175 # 'upload-figleaf' is meant to be run with an UPLOAD_TARGET=host:/dir setting
176 ifdef UPLOAD_TARGET
177
178 ifndef UPLOAD_HOST
179 $(error UPLOAD_HOST must be set when using UPLOAD_TARGET)
180 endif
181 ifndef COVERAGEDIR
182 $(error COVERAGEDIR must be set when using UPLOAD_TARGET)
183 endif
184
185 upload-figleaf:
186         rsync -a coverage-html/ $(UPLOAD_TARGET)
187         ssh $(UPLOAD_HOST) make update-tahoe-figleaf COVERAGEDIR=$(COVERAGEDIR)
188 else
189 upload-figleaf:
190         echo "this target is meant to be run with UPLOAD_TARGET=host:/path/"
191         false
192 endif
193
194 .figleaf.el: .figleaf
195         $(PP) $(PYTHON) misc/figleaf2el.py .figleaf src
196
197 pyflakes:
198         $(PYTHON) -OOu `which pyflakes` src/allmydata |sort |uniq
199
200 count-lines:
201         @echo -n "files: "
202         @find src -name '*.py' |grep -v /build/ |wc --lines
203         @echo -n "lines: "
204         @cat `find src -name '*.py' |grep -v /build/` |wc --lines
205         @echo -n "TODO: "
206         @grep TODO `find src -name '*.py' |grep -v /build/` | wc --lines
207
208 check-memory: .built
209         rm -rf _test_memory
210         $(PP) \
211          $(PYTHON) src/allmydata/test/check_memory.py upload
212         $(PP) \
213          $(PYTHON) src/allmydata/test/check_memory.py upload-self
214         $(PP) \
215          $(PYTHON) src/allmydata/test/check_memory.py upload-POST
216         $(PP) \
217          $(PYTHON) src/allmydata/test/check_memory.py download
218         $(PP) \
219          $(PYTHON) src/allmydata/test/check_memory.py download-GET
220         $(PP) \
221          $(PYTHON) src/allmydata/test/check_memory.py download-GET-slow
222         $(PP) \
223          $(PYTHON) src/allmydata/test/check_memory.py receive
224
225 check-memory-once: .built
226         rm -rf _test_memory
227         $(PP) \
228          $(PYTHON) src/allmydata/test/check_memory.py $(MODE)
229
230 # The check-speed target uses a pre-established client node to run a canned
231 # set of performance tests against a test network that is also
232 # pre-established (probably on a remote machine). Provide it with the path to
233 # a local directory where this client node has been created (and populated
234 # with the necessary FURLs of the test network). This target will start that
235 # client with the current code and then run the tests. Afterwards it will
236 # stop the client.
237 #
238 # The 'sleep 5' is in there to give the new client a chance to connect to its
239 # storageservers, since check_speed.py has no good way of doing that itself.
240
241 check-speed: .built
242         if [ -z '$(TESTCLIENTDIR)' ]; then exit 1; fi
243         @echo "stopping any leftover client code"
244         -$(PYTHON) bin/tahoe stop $(TESTCLIENTDIR)
245         $(PYTHON) bin/tahoe start $(TESTCLIENTDIR)
246         sleep 5
247         $(PYTHON) src/allmydata/test/check_speed.py $(TESTCLIENTDIR)
248         $(PYTHON) bin/tahoe stop $(TESTCLIENTDIR)
249
250 # The check-grid target also uses a pre-established client node, along with a
251 # long-term directory that contains some well-known files. See the docstring
252 # in src/allmydata/test/check_grid.py to see how to set this up.
253 check-grid: .built
254         if [ -z '$(TESTCLIENTDIR)' ]; then exit 1; fi
255         $(PYTHON) src/allmydata/test/check_grid.py $(TESTCLIENTDIR) bin/tahoe
256
257 # 'make repl' is a simple-to-type command to get a Python interpreter loop
258 # from which you can type 'import allmydata'
259 repl:
260         $(PP) $(PYTHON)
261
262 test-darcs-boringfile:
263         $(MAKE)
264         $(PYTHON) misc/test-darcs-boringfile.py
265
266 test-clean:
267         find . |grep -vEe"allfiles.tmp|src/allmydata/_(version|auto_deps).py|src/allmydata_tahoe.egg-info" |sort >allfiles.tmp.old
268         $(MAKE)
269         $(MAKE) clean
270         find . |grep -vEe"allfiles.tmp|src/allmydata/_(version|auto_deps).py|src/allmydata_tahoe.egg-info" |sort >allfiles.tmp.new
271         diff allfiles.tmp.old allfiles.tmp.new
272
273 clean:
274         rm -rf build _trial_temp _test_memory .checked-deps .built
275         rm -f debian
276         rm -f `find src/allmydata -name '*.so' -or -name '*.pyc'`
277         rm -rf tahoe_deps.egg-info allmydata_tahoe.egg-info
278         rm -rf support dist
279         rm -rf setuptools*.egg *.pyc darcsver*.egg pyutil*.egg
280         rm -rf misc/dependencies/build misc/dependencies/temp
281         rm -rf misc/dependencies/tahoe_deps.egg-info
282
283 find-trailing-spaces:
284         $(PYTHON) misc/find-trailing-spaces.py -r src
285
286 # TARBALL GENERATION
287 .PHONY: tarballs upload-tarballs
288 tarballs:
289         $(MAKE) make-version
290         $(PYTHON) setup.py sdist --formats=bztar,gztar,zip
291 upload-tarballs:
292         for f in dist/allmydata-tahoe-*; do \
293          xfer-client --furlfile ~/.tahoe-tarball-upload.furl $$f; \
294         done
295
296 # DEBIAN PACKAGING
297
298 VER=$(shell $(PYTHON) misc/get-version.py)
299 DEBCOMMENTS="'make deb' build"
300
301 show-version:
302         @echo $(VER)
303
304 .PHONY: setup-deb deb-ARCH is-known-debian-arch
305 .PHONY: deb-etch deb-sid
306 .PHONY: deb-edgy deb-feisty deb-gutsy deb-hardy
307
308 deb-sid:
309         $(MAKE) deb-ARCH ARCH=sid
310 deb-feisty:
311         $(MAKE) deb-ARCH ARCH=feisty
312 # edgy uses the feisty control files for now
313 deb-edgy:
314         $(MAKE) deb-ARCH ARCH=edgy TAHOE_ARCH=feisty
315 # etch uses the feisty control files for now
316 deb-etch:
317         $(MAKE) deb-ARCH ARCH=etch TAHOE_ARCH=feisty
318 # same with gutsy, the process has been nicely stable for a while now
319 deb-gutsy:
320         $(MAKE) deb-ARCH ARCH=gutsy TAHOE_ARCH=feisty
321 deb-hardy:
322         $(MAKE) deb-ARCH ARCH=hardy TAHOE_ARCH=feisty
323
324 # we know how to handle the following debian architectures
325 KNOWN_DEBIAN_ARCHES := etch sid  edgy feisty gutsy hardy
326
327 ifeq ($(findstring x-$(ARCH)-x,$(foreach arch,$(KNOWN_DEBIAN_ARCHES),"x-$(arch)-x")),)
328 is-known-debian-arch:
329         @echo "ARCH must be set when using setup-deb or deb-ARCH"
330         @echo "I know how to handle:" $(KNOWN_DEBIAN_ARCHES)
331         false
332 else
333 is-known-debian-arch:
334         true
335 endif
336
337 ifndef TAHOE_ARCH
338 TAHOE_ARCH=$(ARCH)
339 endif
340
341 setup-deb: is-known-debian-arch
342         rm -f debian
343         ln -s misc/$(TAHOE_ARCH)/debian debian
344         chmod +x debian/rules
345
346 # etch (current debian stable) has python-simplejson-1.3, which doesn't 
347 #  support indent=
348 # sid (debian unstable) currently has python-simplejson 1.7.1
349 # edgy has 1.3, which doesn't support indent=
350 # feisty has 1.4, which supports indent= but emits a deprecation warning
351 # gutsy has 1.7.1
352 #
353 # we need 1.4 or newer
354
355 deb-ARCH: is-known-debian-arch setup-deb
356         fakeroot debian/rules binary
357         @echo
358         @echo "The newly built .deb packages are in the parent directory from here."
359
360 .PHONY: increment-deb-version
361 .PHONY: deb-edgy-head deb-feisty-head deb-gutsy-head deb-hardy-head
362 .PHONY: deb-etch-head deb-sid-head
363
364 # The buildbot runs the following targets after each change, to produce
365 # up-to-date tahoe .debs. These steps do not create .debs for anything else.
366
367 increment-deb-version: make-version
368         debchange --newversion $(VER) $(DEBCOMMENTS)
369 deb-sid-head:
370         $(MAKE) setup-deb ARCH=sid
371         $(MAKE) increment-deb-version
372         fakeroot debian/rules binary
373 deb-edgy-head:
374         $(MAKE) setup-deb ARCH=edgy TAHOE_ARCH=feisty
375         $(MAKE) increment-deb-version
376         fakeroot debian/rules binary
377 deb-feisty-head:
378         $(MAKE) setup-deb ARCH=feisty
379         $(MAKE) increment-deb-version
380         fakeroot debian/rules binary
381 deb-etch-head:
382         $(MAKE) setup-deb ARCH=etch TAHOE_ARCH=feisty
383         $(MAKE) increment-deb-version
384         fakeroot debian/rules binary
385 deb-gutsy-head:
386         $(MAKE) setup-deb ARCH=gutsy TAHOE_ARCH=feisty
387         $(MAKE) increment-deb-version
388         fakeroot debian/rules binary
389 deb-hardy-head:
390         $(MAKE) setup-deb ARCH=hardy TAHOE_ARCH=feisty
391         $(MAKE) increment-deb-version
392         fakeroot debian/rules binary
393
394 # These targets provide for windows native builds
395 .PHONY: windows-exe windows-installer windows-installer-upload
396
397 windows-exe: .built
398         cd windows && $(PP) $(PYTHON) setup.py py2exe
399
400 windows-installer: windows-exe
401         $(PP) $(PYTHON) misc/sub-ver.py windows/installer.tmpl >windows/installer.iss
402         cd windows && "$(INNOSETUP)" /cc installer.iss
403
404 windows-installer-upload:
405         chmod -R o+rx windows/dist/installer
406         rsync -av -e /usr/bin/ssh windows/dist/installer/ amduser@dev:/home/amduser/public_html/dist/tahoe/windows/
407
408 # These targets provide for mac native builds
409 .PHONY: mac-exe mac-upload mac-cleanup mac-dbg
410
411 mac-exe: .built
412         $(MAKE) -C mac clean
413         VERSION=$(VER) $(PP) $(MAKE) -C mac build
414
415 mac-dist:
416         VERSION=$(VER) $(MAKE) -C mac diskimage
417
418 mac-upload:
419         VERSION=$(VER) $(MAKE) -C mac upload UPLOAD_DEST=$(UPLOAD_DEST)
420
421 mac-cleanup:
422         VERSION=$(VER) $(MAKE) -C mac cleanup
423
424 mac-dbg:
425         cd mac && $(PP) $(PYTHON)w allmydata_tahoe.py
426
427 # This target runs a stats gatherer server
428 .PHONY: stats-gatherer-run
429 stats-gatherer-run:
430         cd stats_gatherer && $(PP) $(PYTHON) ../src/allmydata/stats.py