1#
2# Makefile for bowtie, bowtie-build, bowtie-inspect
3#
4
5prefix = /usr/local
6bindir = $(prefix)/bin
7
8ARCH = $(shell uname -m)
9INC = $(if $(RELEASE_BUILD),-I$(CURDIR)/.include) -I third_party
10LIBS = $(LDFLAGS) $(if $(RELEASE_BUILD),-L$(CURDIR)/.lib) -lz -lpthread
11HEADERS = $(wildcard *.h)
12BOWTIE_MM = 1
13BOWTIE_SHARED_MEM = 1
14EXTRA_FLAGS =
15EXTRA_CFLAGS =
16EXTRA_CXXFLAGS =
17CFLAGS += $(EXTRA_CFLAGS)
18CXXFLAGS += $(EXTRA_CXXFLAGS)
19WARNING_FLAGS = -Wall -Wno-unused-parameter -Wno-reorder
20
21RELEASE_DEPENDENCIES = $(if $(RELEASE_BUILD),static-libs)
22
23# Detect Cygwin or MinGW
24WINDOWS =
25CYGWIN =
26MINGW =
27ifneq (,$(findstring CYGWIN,$(shell uname)))
28    WINDOWS = 1
29    CYGWIN = 1
30    # POSIX memory-mapped files not currently supported on Windows
31    BOWTIE_MM = 0
32    BOWTIE_SHARED_MEM = 0
33else
34    ifneq (,$(findstring MINGW,$(shell uname)))
35	WINDOWS = 1
36	MINGW = 1
37	# POSIX memory-mapped files not currently supported on Windows
38	BOWTIE_MM = 0
39	BOWTIE_SHARED_MEM = 0
40    endif
41endif
42
43MACOS =
44ifneq (,$(findstring Darwin,$(shell uname)))
45    MACOS = 1
46	ifneq (,$(findstring 13,$(shell uname -r)))
47		override EXTRA_FLAGS += -stdlib=libstdc++
48	endif
49	ifeq (1, $(RELEASE_BUILD))
50		EXTRA_FLAGS += -mmacosx-version-min=10.9
51	endif
52endif
53
54LINUX =
55ifneq (,$(findstring Linux,$(shell uname)))
56    LINUX = 1
57    override EXTRA_FLAGS += -Wl,--hash-style=both
58 endif
59
60MM_DEF =
61ifeq (1,$(BOWTIE_MM))
62    MM_DEF = -DBOWTIE_MM
63endif
64SHMEM_DEF =
65ifeq (1,$(BOWTIE_SHARED_MEM))
66    SHMEM_DEF = -DBOWTIE_SHARED_MEM
67endif
68
69ifeq (1,$(MINGW))
70	override EXTRA_FLAGS += -static-libgcc -static-libstdc++
71endif
72
73POPCNT_CAPABILITY ?= 1
74ifeq (aarch64,$(shell uname -m))
75	POPCNT_CAPABILITY=0
76endif
77ifeq (1, $(POPCNT_CAPABILITY))
78    override EXTRA_FLAGS += -DPOPCNT_CAPABILITY
79endif
80
81PREFETCH_LOCALITY = 2
82PREF_DEF = -DPREFETCH_LOCALITY=$(PREFETCH_LOCALITY)
83
84
85SEARCH_LIBS =
86BUILD_LIBS =
87INSPECT_LIBS =
88
89ifeq (1,$(MINGW))
90    BUILD_LIBS =
91    INSPECT_LIBS =
92endif
93
94ifeq (1,$(WITH_THREAD_PROFILING))
95	override EXTRA_FLAGS += -DPER_THREAD_TIMING=1
96endif
97
98OTHER_CPPS = ccnt_lut.cpp ref_read.cpp alphabet.cpp shmem.cpp \
99             edit.cpp ebwt.cpp bt2_locks.cpp
100
101ifeq (1,$(WITH_QUEUELOCK))
102	NO_SPINLOCK = 1
103	override EXTRA_FLAGS += -DWITH_QUEUELOCK
104endif
105
106ifeq (1,$(NO_SPINLOCK))
107$(info $(NO_SPINLOCK))
108	override EXTRA_FLAGS += -DNO_SPINLOCK
109endif
110
111ifeq (1,$(WITH_FINE_TIMER))
112	override EXTRA_FLAGS += -DUSE_FINE_TIMER=1
113endif
114
115ifeq (1,$(WITH_COHORTLOCK))
116	override EXTRA_FLAGS += -DWITH_COHORTLOCK=1
117	OTHER_CPPS += cohort.cpp cpu_numa_info.cpp
118endif
119
120OTHER_CPPS += tinythread.cpp
121
122SEARCH_CPPS = qual.cpp pat.cpp ebwt_search_util.cpp ref_aligner.cpp \
123              log.cpp hit_set.cpp sam.cpp \
124              hit.cpp
125SEARCH_CPPS_MAIN = $(SEARCH_CPPS) bowtie_main.cpp
126
127BUILD_CPPS =
128BUILD_CPPS_MAIN = $(BUILD_CPPS) bowtie_build_main.cpp
129
130SEARCH_FRAGMENTS = $(wildcard search_*_phase*.c)
131VERSION = $(shell cat VERSION)
132
133BITS=32
134ifeq (1,$(shell echo __LP64__ | $(CC) -P -E - | tr -d '\n'))
135	BITS=64
136endif
137# msys will always be 32 bit so look at the cpu arch instead.
138ifneq (,$(findstring AMD64,$(PROCESSOR_ARCHITEW6432)))
139	ifeq (1,$(MINGW))
140		BITS=64
141	endif
142endif
143
144ifeq (32,$(BITS))
145    $(error bowtie2 compilation requires a 64-bit platform )
146endif
147
148DEBUG_FLAGS = -O0 -g3
149RELEASE_FLAGS =
150NOASSERT_FLAGS = -DNDEBUG
151FILE_FLAGS = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
152
153BIN_LIST = bowtie-build-s \
154           bowtie-build-l \
155           bowtie-align-s \
156           bowtie-align-l \
157           bowtie-inspect-s \
158           bowtie-inspect-l
159BIN_LIST_AUX = bowtie-build-s-debug \
160               bowtie-build-l-debug \
161               bowtie-align-s-debug \
162               bowtie-align-l-debug \
163               bowtie-inspect-s-debug \
164               bowtie-inspect-l-debug
165
166GENERAL_LIST = $(wildcard scripts/*.sh) \
167               $(wildcard scripts/*.pl) \
168               $(wildcard scripts/*.py) \
169               $(wildcard indexes/e_coli*) \
170               $(wildcard genomes/NC_008253.fna) \
171               $(wildcard reads/e_coli_1000.*) \
172               $(wildcard reads/e_coli_1000_*) \
173               bowtie \
174               bowtie-build \
175               bowtie-inspect \
176               doc/manual.html \
177               doc/README \
178               doc/style.css \
179               reads/e_coli_10000snp.fa \
180               reads/e_coli_10000snp.fq \
181               $(PTHREAD_PKG) \
182               AUTHORS \
183               LICENSE \
184               NEWS \
185               MANUAL \
186               MANUAL.markdown \
187               TUTORIAL \
188               VERSION
189
190SRC_PKG_LIST = $(wildcard *.h) \
191               $(wildcard *.hh) \
192               $(wildcard *.c) \
193               $(wildcard *.cpp) \
194               $(wildcard third_party/*.h) \
195               $(wildcard third_party/*.hh) \
196               $(wildcard third_party/*.c) \
197               $(wildcard third_party/*.cpp) \
198               doc/strip_markdown.pl \
199               Makefile \
200               $(GENERAL_LIST)
201
202BIN_PKG_LIST = $(GENERAL_LIST)
203
204all: $(BIN_LIST)
205
206allall: $(BIN_LIST) $(BIN_LIST_AUX)
207
208
209DATE_FMT = %Y-%m-%dT%H:%M:%S
210ifdef SOURCE_DATE_EPOCH
211    BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+$(DATE_FMT)" 2>/dev/null || date -u "+$(DATE_FMT)")
212    BUILD_HOST := reproduciblebuild
213else
214    BUILD_DATE ?= $(shell date "+$(DATE_FMT)")
215    BUILD_HOST ?= `hostname`
216endif
217DEFS=-fno-strict-aliasing \
218     -DBOWTIE_VERSION="\"`cat VERSION`\"" \
219     -DBUILD_HOST="\"$(BUILD_HOST)\"" \
220     -DBUILD_TIME="\"$(BUILD_DATE)\"" \
221     -DCOMPILER_VERSION="\"`$(CXX) -v 2>&1 | tail -1`\"" \
222     $(FILE_FLAGS) \
223     $(PTHREAD_DEF) \
224     $(PREF_DEF) \
225     $(MM_DEF) \
226     $(SHMEM_DEF)
227
228ALL_FLAGS = $(EXTRA_FLAGS) $(CXXFLAGS)
229DEBUG_DEFS = -DCOMPILER_OPTIONS="\"$(DEBUG_FLAGS) $(EXTRA_FLAGS) $(CFLAGS) $(CXXFLAGS)\""
230RELEASE_DEFS = -DCOMPILER_OPTIONS="\"$(RELEASE_FLAGS) $(EXTRA_FLAGS) $(CFLAGS) $(CXXFLAGS)\""
231
232#
233# bowtie-build targets
234#
235
236bowtie-build-s: ebwt_build.cpp $(OTHER_CPPS) $(HEADERS)
237	$(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(ALL_FLAGS)  \
238		$(DEFS) $(NOASSERT_FLAGS) $(WARNING_FLAGS) \
239		$(INC) \
240		-o $@ $< \
241		$(OTHER_CPPS) $(BUILD_CPPS_MAIN) \
242		$(LIBS) $(BUILD_LIBS)
243
244bowtie-build-l: ebwt_build.cpp $(OTHER_CPPS) $(HEADERS)
245	$(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(ALL_FLAGS)  \
246		$(DEFS) -DBOWTIE_64BIT_INDEX $(NOASSERT_FLAGS) $(WARNING_FLAGS) \
247		$(INC) \
248		-o $@ $< \
249		$(OTHER_CPPS) $(BUILD_CPPS_MAIN) \
250		$(LIBS) $(BUILD_LIBS)
251
252bowtie-build_prof: ebwt_build.cpp $(OTHER_CPPS) $(HEADERS)
253	$(CXX) $(RELEASE_FLAGS) -pg -p -g3 $(RELEASE_DEFS) $(ALL_FLAGS) \
254		$(DEFS) $(NOASSERT_FLAGS) $(WARNING_FLAGS) \
255		$(INC) \
256		-o $@ $< \
257		$(OTHER_CPPS) $(BUILD_CPPS_MAIN) \
258		$(LIBS) $(BUILD_LIBS)
259
260bowtie-build-s-debug: ebwt_build.cpp $(OTHER_CPPS) $(HEADERS)
261	$(CXX) $(DEBUG_FLAGS) $(DEBUG_DEFS) $(ALL_FLAGS) \
262		$(DEFS) $(WARNING_FLAGS) \
263		$(INC) \
264		-o $@ $< \
265		$(OTHER_CPPS) $(BUILD_CPPS_MAIN) \
266		$(LIBS) $(BUILD_LIBS)
267
268bowtie-build-l-debug: ebwt_build.cpp $(OTHER_CPPS) $(HEADERS)
269	$(CXX) $(DEBUG_FLAGS) $(DEBUG_DEFS) $(ALL_FLAGS) \
270		$(DEFS) -DBOWTIE_64BIT_INDEX $(WARNING_FLAGS) \
271		$(INC) \
272		-o $@ $< \
273		$(OTHER_CPPS) $(BUILD_CPPS_MAIN) \
274		$(LIBS) $(BUILD_LIBS)
275
276#
277# bowtie targets
278#
279
280bowtie-align-s: ebwt_search.cpp $(SEARCH_CPPS) $(OTHER_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS)
281	$(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(ALL_FLAGS) \
282		$(DEFS) $(NOASSERT_FLAGS) $(WARNING_FLAGS) \
283		$(INC) \
284		-o $@ $< \
285		$(OTHER_CPPS) $(SEARCH_CPPS_MAIN) \
286		$(LIBS) $(SEARCH_LIBS)
287
288bowtie-align-l: ebwt_search.cpp $(SEARCH_CPPS) $(OTHER_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS)
289	$(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(ALL_FLAGS) \
290		$(DEFS) $(NOASSERT_FLAGS) -DBOWTIE_64BIT_INDEX $(WARNING_FLAGS) \
291		$(INC) \
292		-o $@ $< \
293		$(OTHER_CPPS) $(SEARCH_CPPS_MAIN) \
294		$(LIBS) $(SEARCH_LIBS)
295
296bowtie_prof: ebwt_search.cpp $(SEARCH_CPPS) $(OTHER_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS)
297	$(CXX) $(RELEASE_FLAGS) \
298		$(RELEASE_DEFS) -pg -p -g3 $(ALL_FLAGS) \
299		$(DEFS) $(NOASSERT_FLAGS) $(WARNING_FLAGS) \
300		$(INC) \
301		-o $@ $< \
302		$(OTHER_CPPS) $(SEARCH_CPPS_MAIN) \
303		$(LIBS) $(SEARCH_LIBS)
304
305bowtie-align-s-debug: ebwt_search.cpp $(SEARCH_CPPS) $(OTHER_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS)
306	$(CXX) $(DEBUG_FLAGS) \
307		$(DEBUG_DEFS) $(ALL_FLAGS) \
308		$(DEFS) $(WARNING_FLAGS) \
309		$(INC) \
310		-o $@ $< \
311		$(OTHER_CPPS) $(SEARCH_CPPS_MAIN) \
312		$(LIBS) $(SEARCH_LIBS)
313
314bowtie-align-l-debug: ebwt_search.cpp $(SEARCH_CPPS) $(OTHER_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS)
315	$(CXX) $(DEBUG_FLAGS) \
316		$(DEBUG_DEFS) $(ALL_FLAGS) \
317		$(DEFS) -DBOWTIE_64BIT_INDEX $(WARNING_FLAGS) \
318		$(INC) \
319		-o $@ $< \
320		$(OTHER_CPPS) $(SEARCH_CPPS_MAIN) \
321		$(LIBS) $(SEARCH_LIBS)
322
323#
324# bowtie-inspect targets
325#
326
327bowtie-inspect-s: bowtie_inspect.cpp $(HEADERS) $(OTHER_CPPS)
328	$(CXX) $(RELEASE_FLAGS) \
329		$(RELEASE_DEFS) $(ALL_FLAGS) \
330		$(DEFS) $(WARNING_FLAGS) \
331		$(INC) -I . \
332		-o $@ $< \
333		$(OTHER_CPPS) \
334		$(LIBS)
335
336bowtie-inspect-l: bowtie_inspect.cpp $(HEADERS) $(OTHER_CPPS)
337	$(CXX) $(RELEASE_FLAGS) \
338		$(RELEASE_DEFS) $(ALL_FLAGS) \
339		$(DEFS) -DBOWTIE_64BIT_INDEX $(WARNING_FLAGS) \
340		$(INC) -I . \
341		-o $@ $< \
342		$(OTHER_CPPS) \
343		$(LIBS)
344
345bowtie-inspect-s-debug: bowtie_inspect.cpp $(HEADERS) $(OTHER_CPPS)
346	$(CXX) $(DEBUG_FLAGS) \
347		$(DEBUG_DEFS) $(ALL_FLAGS) \
348		$(DEFS) $(WARNING_FLAGS) \
349		$(INC) -I . \
350		-o $@ $< \
351		$(OTHER_CPPS) \
352		$(LIBS)
353
354bowtie-inspect-l-debug: bowtie_inspect.cpp $(HEADERS) $(OTHER_CPPS)
355	$(CXX) $(DEBUG_FLAGS) \
356		$(DEBUG_DEFS) $(ALL_FLAGS) \
357		$(DEFS) -DBOWTIE_64BIT_INDEX $(WARNING_FLAGS) \
358		$(INC) -I . \
359		-o $@ $< \
360		$(OTHER_CPPS) \
361		$(LIBS)
362
363bowtie-src.zip: $(SRC_PKG_LIST)
364	chmod a+x scripts/*.sh scripts/*.pl
365	mkdir .src.tmp
366	mkdir .src.tmp/bowtie-$(VERSION)-src
367	zip -r tmp.zip $(SRC_PKG_LIST)
368	mv tmp.zip .src.tmp/bowtie-$(VERSION)-src
369	cd .src.tmp/bowtie-$(VERSION)-src ; unzip tmp.zip ; rm -f tmp.zip
370	cd .src.tmp ; zip -r bowtie-$(VERSION)-src.zip bowtie-$(VERSION)-src
371	cp .src.tmp/bowtie-$(VERSION)-src.zip .
372	rm -rf .src.tmp
373
374bowtie-bin.zip: $(RELEASE_DEPENDENCIES) $(BIN_PKG_LIST) $(BIN_LIST) $(BIN_LIST_AUX)
375	$(eval PKG_DIR=bowtie-$(VERSION)-$(if $(MACOS),macos,$(if $(MINGW),mingw,linux))-$(ARCH))
376	chmod a+x scripts/*.sh scripts/*.pl
377	rm -rf .bin.tmp
378	mkdir .bin.tmp
379	mkdir -p .bin.tmp/$(PKG_DIR)
380	if [ -f bowtie-align-s.exe ] ; then \
381		zip tmp.zip $(BIN_PKG_LIST) $(addsuffix .exe,$(BIN_LIST) $(BIN_LIST_AUX)) ; \
382	else \
383		zip tmp.zip $(BIN_PKG_LIST) $(BIN_LIST) $(BIN_LIST_AUX) ; \
384	fi
385	mv tmp.zip .bin.tmp/$(PKG_DIR)
386	cd .bin.tmp/$(PKG_DIR) ; unzip tmp.zip ; rm -f tmp.zip
387	cd .bin.tmp ; zip -r $(PKG_DIR).zip $(PKG_DIR)
388	cp .bin.tmp/$(PKG_DIR).zip .
389	rm -rf .bin.tmp
390
391.PHONY: doc
392doc: doc/manual.html MANUAL
393
394doc/manual.html: MANUAL.markdown
395	echo "<h1>Table of Contents</h1>" > .tmp.head
396	pandoc -B .tmp.head \
397	       --ascii \
398	       --css style.css -o $@ \
399	       --from markdown --to HTML \
400	       --metadata title:"Bowtie Manual" \
401	       --table-of-contents $^
402
403MANUAL: MANUAL.markdown
404	perl doc/strip_markdown.pl < $^ > $@
405
406.PHONY: install
407install: all
408	mkdir -p $(DESTDIR)$(bindir)
409	for file in $(BIN_LIST) bowtie-inspect bowtie-build bowtie ; do \
410		cp -f $$file $(DESTDIR)$(bindir) ; \
411	done
412
413.PHONY: simple-test
414simple-test: allall perl-deps
415	eval `perl -I $(CURDIR)/.perllib.tmp/lib/perl5 -Mlocal::lib=$(CURDIR)/.perllib.tmp` ; \
416	./scripts/test/simple_tests.pl --bowtie=./bowtie --bowtie-build=./bowtie-build
417
418.PHONY: random-test
419random-test: all perl-deps
420	eval `perl -I $(CURDIR)/.perllib.tmp/lib/perl5 -Mlocal::lib=$(CURDIR)/.perllib.tmp` ; \
421	./scripts/test/random_bowtie_tests.sh $(*-command-variables-*-)
422
423.PHONY: perl-deps
424perl-deps:
425	if [ ! -e .perllib.tmp ]; then \
426		DL=$$([ `which wget` ] && echo "wget -O-" || echo "curl -L") ; \
427		mkdir .perllib.tmp ; \
428		$$DL http://cpanmin.us | perl - -l $(CURDIR)/.perllib.tmp App::cpanminus local::lib ; \
429		eval `perl -I $(CURDIR)/.perllib.tmp/lib/perl5 -Mlocal::lib=$(CURDIR)/.perllib.tmp` ; \
430		cpanm --force Math::Random Clone Test::Deep Sys::Info -n --quiet; \
431	fi
432
433static-libs:
434	if [ ! -d $(CURDIR)/.lib ]; then \
435		mkdir $(CURDIR)/.lib ; \
436	fi ; \
437	if [ ! -d $(CURDIR)/.include ]; then \
438		mkdir $(CURDIR)/.include ; \
439	fi ;
440	if [ `uname` == "Darwin" ]; then \
441		export CFLAGS=-mmacosx-version-min=10.9 ; \
442		export CXXFLAGS=-mmacosx-version-min=10.9 ; \
443	fi ; \
444	DL=$$([ `which wget` ] && echo "wget --no-check-certificate --content-disposition" || echo "curl -LJkO") ; \
445	cd /tmp ; \
446	$$DL https://zlib.net/zlib-1.2.11.tar.gz && tar xzf zlib-1.2.11.tar.gz && cd zlib-1.2.11 ; \
447	$(if $(MINGW), mingw32-make -f win32/Makefile.gcc, ./configure --static && make) && cp libz.a $(CURDIR)/.lib && cp zconf.h zlib.h $(CURDIR)/.include ;
448
449.PHONY: clean
450clean:
451	rm -f $(BIN_LIST) $(BIN_LIST_AUX) \
452	bowtie_prof \
453	$(addsuffix .exe,$(BIN_LIST) $(BIN_LIST_AUX) bowtie_prof) \
454	bowtie-src.zip bowtie-bin.zip
455	rm -f *.core
456	rm -f bowtie-align-s-master* bowtie-align-s-no-io*
457	rm -rf .lib .include
458