Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
239 lines (220 loc) · 10.5 KB
/
Copy pathMakefile
File metadata and controls
239 lines (220 loc) · 10.5 KB
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
CC= gcc
CFLAGS= -std=c99 -g -Wall -O3
CPPFLAGS=
LDFLAGS=
INCLUDES=
LOBJS= kommon.o kalloc.o bwt.o l2bit.o options.o seed.o map-algo.o lchain.o align.o pe.o cs.o format.o \
ksw2_extz2_sse.o $(EXTD2_OBJS) ksw2_ll_sse.o regime.o
AOBJS= kthread.o libsais.o libsais64.o index.o bseq.o fr_fastq.o map-main.o fastmap.o
MALLOC_O= mimalloc.o
PROG= minibwa
LIBS= -lpthread -lz -lm
ARCH= $(shell uname -m)
omp= $(shell printf '\043include <omp.h>\nint main(){return 0;}' | $(CC) -x c -fopenmp -o /dev/null - 2>/dev/null && echo "1" || echo "0")
ifneq ($(asan),)
override CFLAGS+=-fsanitize=address
override LDFLAGS+=-fsanitize=address
override LIBS+=-ldl
endif
ifeq ($(omp),1)
override CPPFLAGS+=-DLIBSAIS_OPENMP
override CFLAGS+=-fopenmp
override LIBS+=-fopenmp
endif
ifneq ($(gpl),0)
AOBJS+=QSufSort.o bwtgen.o
override CPPFLAGS+=-DUSE_GPL
endif
ifeq ($(mimalloc),0)
MALLOC_O=
override CPPFLAGS+=-DHAVE_KALLOC
endif
ifeq ($(ARCH), x86_64)
override CFLAGS+=-msse4.2 -mpopcnt
endif
# Dual-gap extension (ksw_extd2): a dispatcher chooses AVX-512BW / AVX2 / SSE4.2
# at RUNTIME via __builtin_cpu_supports (one portable binary). The wide kernels
# only accelerate the gap-fill path; everything else delegates to the original
# 128-bit kernel (built as ksw2_extd2_ref.o). Non-x86 uses the original directly.
ifeq ($(ARCH), x86_64)
EXTD2_OBJS= ksw2_extd2_dispatch.o ksw2_extd2_ref.o ksw2_extd2_avx2.o ksw2_extd2_avx512.o
else
EXTD2_OBJS= ksw2_extd2_dispatch.o ksw2_extd2_ref.o
endif
# ===================== B2: compile-optional cp_occ seeding backend =========
# `make B2=1` links b2idx.o (minibwa's seeding leaves re-expressed over
# bwa-mem2/bwa-mem3's cp_occ FM-index) against a pre-built bwa-mem3 libbwa.a.
# b2idx.cpp is C++ (FMI_search is C++) and MUST be compiled with the same ISA
# shim macros / include path bwa-mem3 used to build libbwa.a or the FMI_search
# struct ABI mismatches. Override BWAMEM3_DIR to point at that checkout.
#
# Without B2=1: no b2idx.o, no libbwa.a link, no MB_HAVE_B2 -- native build is
# byte-for-byte the same command line as before this guard existed.
LINK = $(CC)
LINK_FLAGS = $(CFLAGS)
B2OBJS =
B3_LDLIBS =
ifeq ($(B2),1)
override CPPFLAGS += -DMB_HAVE_B2
CXX ?= c++
BWAMEM3_DIR ?= ../bwa-mem3/main
# Fail fast with a clear message rather than an obscure -I / missing-libbwa.a
# error deep in the build. Only evaluated under B2=1, so a stock `make` is
# unaffected. Flush-left: a leading tab would make `$(error)` a recipe line.
ifeq (,$(wildcard $(BWAMEM3_DIR)/libbwa.a))
$(error B2=1 needs a pre-built bwa-mem3: no libbwa.a under BWAMEM3_DIR ($(BWAMEM3_DIR)); set BWAMEM3_DIR to a checkout containing libbwa.a)
endif
# Phase-2 reference reconstruction: l2bit.c's l2b_from_bns (built via the
# generic .c.o rule, not the b2idx.o-specific one below) needs bwa-mem3's
# bntseq.h directly under MB_HAVE_B2, so extend INCLUDES for every .c
# compile in a B2 build. Harmless for TUs that don't include it.
override INCLUDES += -I$(BWAMEM3_DIR)/src
UNAME_S := $(shell uname -s)
ifneq (,$(filter arm64 aarch64,$(ARCH)))
B3_ARCH_FLAGS = -DAPPLE_SILICON=1 -DCACHE_LINE_BYTES=128 \
-D__SSE__=1 -D__SSE2__=1 -D__SSE3__=1 -D__SSSE3__=1 \
-D__SSE4_1__=1 -D__SSE4_2__=1 -I$(BWAMEM3_DIR)/ext/sse2neon
else
B3_ARCH_FLAGS =
endif
# libbwa.a's FMI_search.o references libsais_build_fm_index(), which in
# turn needs libsais{,64}_gsa_omp -- present in bwa-mem3's own libsais.o /
# libsais64.o but NOT baked into libbwa.a itself, so link them explicitly.
B3_LIBSAIS = $(BWAMEM3_DIR)/ext/libsais/src/libsais.o $(BWAMEM3_DIR)/ext/libsais/src/libsais64.o
ifeq ($(UNAME_S),Darwin)
LIBDEFLATE_PREFIX := $(shell brew --prefix libdeflate 2>/dev/null)
ifneq (,$(wildcard /opt/homebrew/opt/libomp/lib/libomp.dylib))
B3_OMP = -L/opt/homebrew/opt/libomp/lib -lomp
else
B3_OMP = -lomp
endif
B3_FRAMEWORKS = -framework Accelerate
B3_EXTRA = -L$(LIBDEFLATE_PREFIX)/lib -ldeflate
else
B3_OMP = -fopenmp
B3_FRAMEWORKS =
B3_EXTRA = -ldeflate
ifneq (,$(wildcard /usr/local/lib64/libdeflate.*))
B3_EXTRA += -L/usr/local/lib64
endif
endif
# zlib-ng: src/fast_reader.c's plain-gzip decode path is a direct (zng_*)
# dependency of libbwa.a as of the combined B1+B2 bwa-mem3 -- the older
# bwa-mem3 checkout the b2idx prototype was validated against predates
# this, so it isn't in the prototype's Makefile. Use the vendored static
# archive bwa-mem3 itself builds (ext/zlib-ng/build/libz-ng.a).
B3_ZLIBNG = $(BWAMEM3_DIR)/ext/zlib-ng/build/libz-ng.a
B3_LDLIBS = $(BWAMEM3_DIR)/libbwa.a $(BWAMEM3_DIR)/ext/htslib/libhts.a $(B3_LIBSAIS) \
$(B3_ZLIBNG) $(B3_OMP) $(B3_FRAMEWORKS) $(B3_EXTRA)
B2OBJS = b2idx.o
LINK = $(CXX)
# Intentionally empty (native builds use LINK_FLAGS = $(CFLAGS)): under B2=1
# the CFLAGS bits that matter at link are carried elsewhere -- any -fsanitize
# rides in via $(LDFLAGS), and OpenMP/arch libs via $(B3_LDLIBS)/$(B3_OMP) --
# so folding $(CFLAGS) in here would only re-add compile-only flags (and could
# duplicate -fopenmp against the C++ linker). See the link recipe below.
LINK_FLAGS =
# bwa-mem3's libbwa.a pulls in its own libsais (needs the gsa_omp variant
# above); linking minibwa's libsais.o/libsais64.o too would duplicate
# symbols, so drop them from AOBJS. (`map` never builds an index, so this
# only affects the unused `index` subcommand under a B2 build.)
AOBJS := $(filter-out libsais
8000
.o libsais64.o,$(AOBJS))
endif
# ===========================================================================
# ===================== build-mode guard =====================================
# LOBJS/AOBJS/main.o are compiled with $(CPPFLAGS), which gains -DMB_HAVE_B2
# only under B2=1. The object names do not encode that flag, so toggling
# `make` <-> `make B2=1` without `make clean` would reuse stale objects and
# silently drop the cp_occ backend (the binary still links and runs, just with
# no sa*-b2 regime). Record the current mode in a stamp file, rewritten only
# when the mode actually changes; every $(CPPFLAGS) object depends on it, so a
# mode flip refreshes the stamp's mtime and forces those objects to recompile.
# force_build_mode is the first target rule in the file; without an explicit
# default goal, GNU make would otherwise silently adopt it as the thing a
# bare `make`/`make B2=1` builds instead of `all`.
.DEFAULT_GOAL := all
BUILD_MODE := $(if $(filter 1,$(B2)),b2,native)
.PHONY: force_build_mode
force_build_mode:
.build-mode: force_build_mode
@[ "$$(cat $@ 2>/dev/null)" = "$(BUILD_MODE)" ] || echo "$(BUILD_MODE)" > $@
$(LOBJS) $(AOBJS) main.o: .build-mode
# ===========================================================================
.SUFFIXES:.c .o
.PHONY:all clean depend test
.c.o:
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $< -o $@
all:$(PROG)
# --- ksw_extd2 runtime ISA dispatch (keep below the default `all` target) ---
# original 128-bit ksw_extd2 under a private symbol (full-featured fallback)
ksw2_extd2_ref.o:ksw2_extd2_sse.c ksw2.h
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -Dksw_extd2_sse=extd2_ref_impl ksw2_extd2_sse.c -o $@
# runtime dispatcher (defines ksw_extd2_sse)
ksw2_extd2_dispatch.o:ksw2_extd2_dispatch.c ksw2.h
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) ksw2_extd2_dispatch.c -o $@
ifeq ($(ARCH), x86_64)
ksw2_extd2_avx2.o:ksw2_extd2_wide.c ksw2_wide_simd.h ksw2.h
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -mavx2 -Dksw_extd2_sse=ksw_extd2_avx2 ksw2_extd2_wide.c -o $@
ksw2_extd2_avx512.o:ksw2_extd2_wide.c ksw2_wide_simd.h ksw2.h
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -mavx512bw -Dksw_extd2_sse=ksw_extd2_avx512 ksw2_extd2_wide.c -o $@
endif
b2idx.o:b2idx.cpp b2idx.h bwt.h kalloc.h $(BWAMEM3_DIR)/src/fmi_seed_api.h $(BWAMEM3_DIR)/src/bntseq.h
$(CXX) -c -std=c++14 -O3 -g -Wall $(B3_ARCH_FLAGS) -I$(BWAMEM3_DIR)/src -I. $< -o $@
mimalloc.o:
$(CC) -c -std=gnu11 -O3 -Wall -Wextra -DNDEBUG -DMI_MALLOC_OVERRIDE -DMI_OSX_INTERPOSE=1 -DMI_OSX_ZONE=1 -Imimalloc mimalloc/static.c -o $@
libminibwa.a:$(LOBJS)
$(AR) -csru $@ $(LOBJS)
minibwa:libminibwa.a $(MALLOC_O) $(AOBJS) $(B2OBJS) main.o
# $(LIBS) (-lz ...) MUST follow $(B3_LDLIBS): static libhts.a in there needs zlib
# resolved after it, or the B2 link fails on undefined zlib symbols. Native builds
# have an empty $(B3_LDLIBS), so this is just $(LIBS) at the end as before.
$(LINK) $(LINK_FLAGS) $(LDFLAGS) $(MALLOC_O) $(AOBJS) $(B2OBJS) main.o -o $@ -L. -lminibwa $(B3_LDLIBS) $(LIBS)
# Run the ALT liftover-group suite. Each script builds its own fixtures, but several
# drive the api-test helpers, which live in their own Makefile and are not part of `all`
# -- without them those scripts fail on a fresh checkout. Set MB_STOCK to a stock
# minibwa to enable the no-.alt byte-identity comparisons; they are skipped without it.
test:minibwa
$(MAKE) -C api-test
@if [ -z "$$MB_STOCK" ]; then \
echo "NOTE: MB_STOCK unset -> the no-.alt byte-identity-vs-stock comparisons are SKIPPED."; \
echo " Set MB_STOCK=<path to a stock minibwa> to exercise that invariant."; \
fi
@fail=0; for t in test/altlg/test-*.sh; do \
printf '%s: ' "$$t"; \
if sh "$$t" > /tmp/altlg-log.$$$$ 2>&1; then echo PASS; \
else echo FAIL; cat /tmp/altlg-log.$$$$; fail=1; fi; \
rm -f /tmp/altlg-log.$$$$; \
done; exit $$fail
clean:
rm -fr *.o a.out $(PROG) *~ *.a *.dSYM .build-mode
depend:
(LC_ALL=C; export LC_ALL; makedepend -Y -- $(CFLAGS) $(DFLAGS) -- *.c *.cpp)
# DO NOT DELETE
QSufSort.o: QSufSort.h
align.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h kalloc.h ksw2.h
bseq.o: bseq.h fr_fastq.h kommon.h
fr_fastq.o: fr_fastq.h
bwt.o: kommon.h kalloc.h bwt.h
bwtgen.o: QSufSort.h
cs.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h kalloc.h
fastmap.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h ketopt.h kseq.h
fastmap.o: kalloc.h
format.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h
index.o: libsais.h libsais64.h kommon.h ketopt.h mbpriv.h minibwa.h l2bit.h
index.o: bwt.h bseq.h
kalloc.o: kalloc.h
kommon.o: kommon.h
ksw2_extz2_sse.o: ksw2.h
ksw2_ll_sse.o: ksw2.h
kthread.o: kthread.h
l2bit.o: kommon.h l2bit.h kseq.h
lchain.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h kalloc.h ksort.h
libsais.o: libsais.h
libsais64.o: libsais.h libsais64.h
main.o: kommon.h mbpriv.h minibwa.h l2bit.h bwt.h bseq.h ketopt.h
map-algo.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h kalloc.h ksort.h
map-main.o: kommon.h mbpriv.h minibwa.h l2bit.h bwt.h bseq.h kalloc.h
map-main.o: kthread.h ketopt.h kseq.h
options.o: minibwa.h
pe.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h kalloc.h ksw2.h
seed.o: mbpriv.h minibwa.h l2bit.h bwt.h kommon.h bseq.h kalloc.h ksort.h