1# Makefile for htslib, a C library for high-throughput sequencing data formats.
2#
3#    Copyright (C) 2013-2020 Genome Research Ltd.
4#
5#    Author: John Marshall <jm18@sanger.ac.uk>
6#
7# Permission is hereby granted, free of charge, to any person obtaining a copy
8# of this software and associated documentation files (the "Software"), to deal
9# in the Software without restriction, including without limitation the rights
10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11# copies of the Software, and to permit persons to whom the Software is
12# furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included in
15# all copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23# DEALINGS IN THE SOFTWARE.
24
25CC     = gcc
26AR     = ar
27RANLIB = ranlib
28
29# Default libraries to link if configure is not used
30htslib_default_libs = -lz -lm -lbz2 -llzma -lcurl
31
32CPPFLAGS =
33# TODO: make the 64-bit support for VCF optional via configure, for now add -DVCF_ALLOW_INT64
34#       to CFLAGS manually, here or in config.mk if the latter exists.
35# TODO: probably update cram code to make it compile cleanly with -Wc++-compat
36# For testing strict C99 support add -std=c99 -D_XOPEN_SOURCE=600
37#CFLAGS   = -g -Wall -O2 -pedantic -std=c99 -D_XOPEN_SOURCE=600
38CFLAGS   = -g -Wall -O2 -fvisibility=hidden
39EXTRA_CFLAGS_PIC = -fpic
40LDFLAGS  = -fvisibility=hidden
41LIBS     = $(htslib_default_libs)
42
43prefix      = /usr/local
44exec_prefix = $(prefix)
45bindir      = $(exec_prefix)/bin
46includedir  = $(prefix)/include
47libdir      = $(exec_prefix)/lib
48libexecdir  = $(exec_prefix)/libexec
49datarootdir = $(prefix)/share
50mandir      = $(datarootdir)/man
51man1dir     = $(mandir)/man1
52man5dir     = $(mandir)/man5
53man7dir     = $(mandir)/man7
54pkgconfigdir= $(libdir)/pkgconfig
55
56MKDIR_P = mkdir -p
57INSTALL = install -p
58INSTALL_DATA    = $(INSTALL) -m 644
59INSTALL_DIR     = $(MKDIR_P) -m 755
60INSTALL_LIB     = $(INSTALL_DATA)
61INSTALL_MAN     = $(INSTALL_DATA)
62INSTALL_PROGRAM = $(INSTALL)
63
64# Set by config.mk if plugins are enabled
65plugindir =
66
67BUILT_PROGRAMS = \
68	bgzip \
69	htsfile \
70	tabix
71
72BUILT_TEST_PROGRAMS = \
73	test/hts_endian \
74	test/fieldarith \
75	test/hfile \
76	test/pileup \
77	test/plugins-dlhts \
78	test/sam \
79	test/test_bgzf \
80	test/test_kfunc \
81	test/test_kstring \
82	test/test_realn \
83	test/test-regidx \
84	test/test_str2int \
85	test/test_view \
86	test/test_index \
87	test/test-vcf-api \
88	test/test-vcf-sweep \
89	test/test-bcf-sr \
90	test/fuzz/hts_open_fuzzer.o \
91	test/test-bcf-translate \
92	test/test-parse-reg
93
94BUILT_THRASH_PROGRAMS = \
95	test/thrash_threads1 \
96	test/thrash_threads2 \
97	test/thrash_threads3 \
98	test/thrash_threads4 \
99	test/thrash_threads5 \
100	test/thrash_threads6 \
101	test/thrash_threads7
102
103all: lib-static lib-shared $(BUILT_PROGRAMS) plugins $(BUILT_TEST_PROGRAMS) \
104     htslib_static.mk htslib-uninstalled.pc
105
106ALL_CPPFLAGS = -I. $(CPPFLAGS)
107
108HTSPREFIX =
109include htslib_vars.mk
110
111# If not using GNU make, you need to copy the version number from version.sh
112# into here.
113PACKAGE_VERSION := $(shell ./version.sh)
114
115LIBHTS_SOVERSION = 3
116MACH_O_COMPATIBILITY_VERSION = $(LIBHTS_SOVERSION)
117
118# $(NUMERIC_VERSION) is for items that must have a numeric X.Y.Z string
119# even if this is a dirty or untagged Git working tree.
120NUMERIC_VERSION := $(shell ./version.sh numeric)
121
122# Force version.h to be remade if $(PACKAGE_VERSION) has changed.
123version.h: $(if $(wildcard version.h),$(if $(findstring "$(PACKAGE_VERSION)",$(shell cat version.h)),,force))
124
125version.h:
126	echo '#define HTS_VERSION_TEXT "$(PACKAGE_VERSION)"' > $@
127
128print-version:
129	@echo $(PACKAGE_VERSION)
130
131show-version:
132	@echo PACKAGE_VERSION = $(PACKAGE_VERSION)
133	@echo NUMERIC_VERSION = $(NUMERIC_VERSION)
134
135.SUFFIXES: .bundle .c .cygdll .dll .o .pico .so
136
137.c.o:
138	$(CC) $(CFLAGS) $(ALL_CPPFLAGS) -c -o $@ $<
139
140.c.pico:
141	$(CC) $(CFLAGS) $(ALL_CPPFLAGS) $(EXTRA_CFLAGS_PIC) -c -o $@ $<
142
143
144LIBHTS_OBJS = \
145	kfunc.o \
146	knetfile.o \
147	kstring.o \
148	bcf_sr_sort.o \
149	bgzf.o \
150	errmod.o \
151	faidx.o \
152	header.o \
153	hfile.o \
154	hfile_net.o \
155	hts.o \
156	hts_os.o\
157	md5.o \
158	multipart.o \
159	probaln.o \
160	realn.o \
161	regidx.o \
162	region.o \
163	sam.o \
164	synced_bcf_reader.o \
165	vcf_sweep.o \
166	tbx.o \
167	textutils.o \
168	thread_pool.o \
169	vcf.o \
170	vcfutils.o \
171	cram/cram_codecs.o \
172	cram/cram_decode.o \
173	cram/cram_encode.o \
174	cram/cram_external.o \
175	cram/cram_index.o \
176	cram/cram_io.o \
177	cram/cram_samtools.o \
178	cram/cram_stats.o \
179	cram/mFILE.o \
180	cram/open_trace_file.o \
181	cram/pooled_alloc.o \
182	cram/rANS_static.o \
183	cram/string_alloc.o \
184	$(NONCONFIGURE_OBJS)
185
186# Without configure we wish to have a rich set of default figures,
187# but we still need conditional inclusion as we wish to still
188# support ./configure --disable-blah.
189NONCONFIGURE_OBJS = hfile_libcurl.o
190
191PLUGIN_EXT  =
192PLUGIN_OBJS =
193
194cram_h = cram/cram.h $(cram_samtools_h) $(header_h) $(cram_structs_h) $(cram_io_h) cram/cram_encode.h cram/cram_decode.h cram/cram_stats.h cram/cram_codecs.h cram/cram_index.h $(htslib_cram_h)
195cram_io_h = cram/cram_io.h $(cram_misc_h)
196cram_misc_h = cram/misc.h
197cram_os_h = cram/os.h $(htslib_hts_endian_h)
198cram_samtools_h = cram/cram_samtools.h $(htslib_sam_h)
199cram_structs_h = cram/cram_structs.h $(htslib_thread_pool_h) $(htslib_cram_h) cram/string_alloc.h cram/mFILE.h $(htslib_khash_h)
200cram_open_trace_file_h = cram/open_trace_file.h cram/mFILE.h
201bcf_sr_sort_h = bcf_sr_sort.h $(htslib_synced_bcf_reader_h) $(htslib_kbitset_h)
202header_h = header.h cram/string_alloc.h cram/pooled_alloc.h $(htslib_khash_h) $(htslib_kstring_h) $(htslib_sam_h)
203hfile_internal_h = hfile_internal.h $(htslib_hts_defs_h) $(htslib_hfile_h) $(textutils_internal_h)
204hts_internal_h = hts_internal.h $(htslib_hts_h) $(textutils_internal_h)
205sam_internal_h = sam_internal.h $(htslib_sam_h)
206textutils_internal_h = textutils_internal.h $(htslib_kstring_h)
207thread_pool_internal_h = thread_pool_internal.h $(htslib_thread_pool_h)
208
209
210# To be effective, config.mk needs to appear after most Makefile variables are
211# set but before most rules appear, so that it can both use previously-set
212# variables in its own rules' prerequisites and also update variables for use
213# in later rules' prerequisites.
214
215# If your make doesn't accept -include, change this to 'include' if you are
216# using the configure script or just comment the line out if you are not.
217-include config.mk
218
219# Usually config.h is generated by running configure or config.status,
220# but if those aren't used create a default config.h here.
221config.h:
222	echo '/* Default config.h generated by Makefile */' > $@
223	echo '#define HAVE_LIBBZ2 1' >> $@
224	echo '#define HAVE_LIBLZMA 1' >> $@
225	echo '#ifndef __APPLE__' >> $@
226	echo '#define HAVE_LZMA_H 1' >> $@
227	echo '#endif' >> $@
228	echo '#define HAVE_DRAND48 1' >> $@
229	echo '#define HAVE_LIBCURL 1' >> $@
230
231# And similarly for htslib.pc.tmp ("pkg-config template").  No dependency
232# on htslib.pc.in listed, as if that file is newer the usual way to regenerate
233# this target is via configure or config.status rather than this rule.
234htslib.pc.tmp:
235	sed -e '/^static_libs=/s/@static_LIBS@/$(htslib_default_libs)/;s#@[^-][^@]*@##g' htslib.pc.in > $@
236
237# Create a makefile fragment listing the libraries and LDFLAGS needed for
238# static linking.  This can be included by projects that want to build
239# and link against the htslib source tree instead of an installed library.
240htslib_static.mk: htslib.pc.tmp
241	sed -n '/^static_libs=/s/[^=]*=/HTSLIB_static_LIBS = /p;/^static_ldflags=/s/[^=]*=/HTSLIB_static_LDFLAGS = /p' $< > $@
242
243
244lib-static: libhts.a
245
246# $(shell), :=, and ifeq/.../endif are GNU Make-specific.  If you don't have
247# GNU Make, comment out the parts of these conditionals that don't apply.
248ifneq "$(origin PLATFORM)" "file"
249PLATFORM := $(shell uname -s)
250endif
251ifeq "$(PLATFORM)" "Darwin"
252SHLIB_FLAVOUR = dylib
253lib-shared: libhts.dylib
254else ifeq "$(findstring CYGWIN,$(PLATFORM))" "CYGWIN"
255SHLIB_FLAVOUR = cygdll
256lib-shared: cyghts-$(LIBHTS_SOVERSION).dll
257else ifeq "$(findstring MSYS,$(PLATFORM))" "MSYS"
258SHLIB_FLAVOUR = dll
259lib-shared: hts-$(LIBHTS_SOVERSION).dll
260else ifeq "$(findstring MINGW,$(PLATFORM))" "MINGW"
261SHLIB_FLAVOUR = dll
262lib-shared: hts-$(LIBHTS_SOVERSION).dll
263else
264SHLIB_FLAVOUR = so
265lib-shared: libhts.so
266endif
267
268BUILT_PLUGINS = $(PLUGIN_OBJS:.o=$(PLUGIN_EXT))
269
270plugins: $(BUILT_PLUGINS)
271
272
273libhts.a: $(LIBHTS_OBJS)
274	@-rm -f $@
275	$(AR) -rc $@ $(LIBHTS_OBJS)
276	-$(RANLIB) $@
277
278print-config:
279	@echo LDFLAGS = $(LDFLAGS)
280	@echo LIBHTS_OBJS = $(LIBHTS_OBJS)
281	@echo LIBS = $(LIBS)
282	@echo PLATFORM = $(PLATFORM)
283
284# The target here is libhts.so, as that is the built file that other rules
285# depend upon and that is used when -lhts appears in other program's recipes.
286# As a byproduct invisible to make, libhts.so.NN is also created, as it is the
287# file used at runtime (when $LD_LIBRARY_PATH includes the build directory).
288
289libhts.so: $(LIBHTS_OBJS:.o=.pico)
290	$(CC) -shared -Wl,-soname,libhts.so.$(LIBHTS_SOVERSION) $(LDFLAGS) -o $@ $(LIBHTS_OBJS:.o=.pico) $(LIBS) -lpthread
291	ln -sf $@ libhts.so.$(LIBHTS_SOVERSION)
292
293# Similarly this also creates libhts.NN.dylib as a byproduct, so that programs
294# when run can find this uninstalled shared library (when $DYLD_LIBRARY_PATH
295# includes this project's build directory).
296
297libhts.dylib: $(LIBHTS_OBJS)
298	$(CC) -dynamiclib -install_name $(libdir)/libhts.$(LIBHTS_SOVERSION).dylib -current_version $(NUMERIC_VERSION) -compatibility_version $(MACH_O_COMPATIBILITY_VERSION) $(LDFLAGS) -o $@ $(LIBHTS_OBJS) $(LIBS)
299	ln -sf $@ libhts.$(LIBHTS_SOVERSION).dylib
300
301cyghts-$(LIBHTS_SOVERSION).dll libhts.dll.a: $(LIBHTS_OBJS)
302	$(CC) -shared -Wl,--out-implib=libhts.dll.a -Wl,--enable-auto-import $(LDFLAGS) -o $@ -Wl,--whole-archive $(LIBHTS_OBJS) -Wl,--no-whole-archive $(LIBS) -lpthread
303
304hts-$(LIBHTS_SOVERSION).dll hts.dll.a: $(LIBHTS_OBJS)
305	$(CC) -shared -Wl,--out-implib=hts.dll.a -Wl,--enable-auto-import -Wl,--exclude-all-symbols $(LDFLAGS) -o $@ -Wl,--whole-archive $(LIBHTS_OBJS) -Wl,--no-whole-archive $(LIBS) -lpthread
306
307# Target to allow htslib.mk to build all the object files before it
308# links the shared and static libraries.
309hts-object-files: $(LIBHTS_OBJS)
310	touch $@
311
312%.so: %.pico libhts.so
313	$(CC) -shared -Wl,-E $(LDFLAGS) -o $@ $< libhts.so $(LIBS) -lpthread
314
315%.bundle: %.o libhts.dylib
316	$(CC) -bundle -Wl,-undefined,dynamic_lookup $(LDFLAGS) -o $@ $< libhts.dylib $(LIBS)
317
318%.cygdll: %.o libhts.dll.a
319	$(CC) -shared $(LDFLAGS) -o $@ $< libhts.dll.a $(LIBS)
320
321%.dll: %.o hts.dll.a
322	$(CC) -shared $(LDFLAGS) -o $@ $< hts.dll.a $(LIBS)
323
324
325bgzf.o bgzf.pico: bgzf.c config.h $(htslib_hts_h) $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_thread_pool_h) $(htslib_hts_endian_h) cram/pooled_alloc.h $(hts_internal_h) $(htslib_khash_h)
326errmod.o errmod.pico: errmod.c config.h $(htslib_hts_h) $(htslib_ksort_h) $(htslib_hts_os_h)
327kstring.o kstring.pico: kstring.c config.h $(htslib_kstring_h)
328knetfile.o knetfile.pico: knetfile.c config.h $(htslib_hts_log_h) $(htslib_knetfile_h)
329header.o header.pico: header.c config.h $(textutils_internal_h) $(header_h)
330hfile.o hfile.pico: hfile.c config.h $(htslib_hfile_h) $(hfile_internal_h) $(htslib_kstring_h) $(hts_internal_h) $(htslib_khash_h)
331hfile_gcs.o hfile_gcs.pico: hfile_gcs.c config.h $(htslib_hts_h) $(htslib_kstring_h) $(hfile_internal_h)
332hfile_libcurl.o hfile_libcurl.pico: hfile_libcurl.c config.h $(hfile_internal_h) $(htslib_hts_h) $(htslib_kstring_h) $(htslib_khash_h)
333hfile_net.o hfile_net.pico: hfile_net.c config.h $(hfile_internal_h) $(htslib_knetfile_h)
334hfile_s3_write.o hfile_s3_write.pico: hfile_s3_write.c config.h $(hfile_internal_h) $(htslib_hts_h) $(htslib_kstring_h) $(htslib_khash_h)
335hfile_s3.o hfile_s3.pico: hfile_s3.c config.h $(hfile_internal_h) $(htslib_hts_h) $(htslib_kstring_h)
336hts.o hts.pico: hts.c config.h $(htslib_hts_h) $(htslib_bgzf_h) $(cram_h) $(htslib_hfile_h) $(htslib_hts_endian_h) version.h $(hts_internal_h) $(hfile_internal_h) $(sam_internal_h) $(htslib_hts_os_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_ksort_h) $(htslib_tbx_h)
337hts_os.o hts_os.pico: hts_os.c config.h $(htslib_hts_defs_h) os/rand.c
338vcf.o vcf.pico: vcf.c config.h $(htslib_vcf_h) $(htslib_bgzf_h) $(htslib_tbx_h) $(htslib_hfile_h) $(hts_internal_h) $(htslib_khash_str2int_h) $(htslib_kstring_h) $(htslib_sam_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_hts_endian_h)
339sam.o sam.pico: sam.c config.h $(htslib_hts_defs_h) $(htslib_sam_h) $(htslib_bgzf_h) $(cram_h) $(hts_internal_h) $(sam_internal_h) $(htslib_hfile_h) $(htslib_hts_endian_h) $(header_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_kstring_h)
340tbx.o tbx.pico: tbx.c config.h $(htslib_tbx_h) $(htslib_bgzf_h) $(htslib_hts_endian_h) $(hts_internal_h) $(htslib_khash_h)
341faidx.o faidx.pico: faidx.c config.h $(htslib_bgzf_h) $(htslib_faidx_h) $(htslib_hfile_h) $(htslib_khash_h) $(htslib_kstring_h) $(hts_internal_h)
342bcf_sr_sort.o bcf_sr_sort.pico: bcf_sr_sort.c config.h $(bcf_sr_sort_h) $(htslib_khash_str2int_h) $(htslib_kbitset_h)
343synced_bcf_reader.o synced_bcf_reader.pico: synced_bcf_reader.c config.h $(htslib_synced_bcf_reader_h) $(htslib_kseq_h) $(htslib_khash_str2int_h) $(htslib_bgzf_h) $(htslib_thread_pool_h) $(bcf_sr_sort_h)
344vcf_sweep.o vcf_sweep.pico: vcf_sweep.c config.h $(htslib_vcf_sweep_h) $(htslib_bgzf_h)
345vcfutils.o vcfutils.pico: vcfutils.c config.h $(htslib_vcfutils_h) $(htslib_kbitset_h)
346kfunc.o kfunc.pico: kfunc.c config.h $(htslib_kfunc_h)
347regidx.o regidx.pico: regidx.c config.h $(htslib_hts_h) $(htslib_kstring_h) $(htslib_kseq_h) $(htslib_khash_str2int_h) $(htslib_regidx_h) $(hts_internal_h)
348region.o region.pico: region.c config.h $(htslib_hts_h) $(htslib_khash_h)
349md5.o md5.pico: md5.c config.h $(htslib_hts_h) $(htslib_hts_endian_h)
350multipart.o multipart.pico: multipart.c config.h $(htslib_kstring_h) $(hts_internal_h) $(hfile_internal_h)
351plugin.o plugin.pico: plugin.c config.h $(hts_internal_h) $(htslib_kstring_h)
352probaln.o probaln.pico: probaln.c config.h $(htslib_hts_h)
353realn.o realn.pico: realn.c config.h $(htslib_hts_h) $(htslib_sam_h)
354textutils.o textutils.pico: textutils.c config.h $(htslib_hfile_h) $(htslib_kstring_h) $(htslib_sam_h) $(hts_internal_h)
355
356cram/cram_codecs.o cram/cram_codecs.pico: cram/cram_codecs.c config.h $(cram_h)
357cram/cram_decode.o cram/cram_decode.pico: cram/cram_decode.c config.h $(cram_h) $(cram_os_h) $(htslib_hts_h)
358cram/cram_encode.o cram/cram_encode.pico: cram/cram_encode.c config.h $(cram_h) $(cram_os_h) $(sam_internal_h) $(htslib_hts_h) $(htslib_hts_endian_h)
359cram/cram_external.o cram/cram_external.pico: cram/cram_external.c config.h $(htslib_hfile_h) $(cram_h)
360cram/cram_index.o cram/cram_index.pico: cram/cram_index.c config.h $(htslib_bgzf_h) $(htslib_hfile_h) $(hts_internal_h) $(cram_h) $(cram_os_h)
361cram/cram_io.o cram/cram_io.pico: cram/cram_io.c config.h os/lzma_stub.h $(cram_h) $(cram_os_h) $(htslib_hts_h) $(cram_open_trace_file_h) cram/rANS_static.h $(htslib_hfile_h) $(htslib_bgzf_h) $(htslib_faidx_h) $(hts_internal_h)
362cram/cram_samtools.o cram/cram_samtools.pico: cram/cram_samtools.c config.h $(cram_h) $(htslib_sam_h) $(sam_internal_h)
363cram/cram_stats.o cram/cram_stats.pico: cram/cram_stats.c config.h $(cram_h) $(cram_os_h)
364cram/mFILE.o cram/mFILE.pico: cram/mFILE.c config.h $(htslib_hts_log_h) $(cram_os_h) cram/mFILE.h
365cram/open_trace_file.o cram/open_trace_file.pico: cram/open_trace_file.c config.h $(cram_os_h) $(cram_open_trace_file_h) $(cram_misc_h) $(htslib_hfile_h) $(htslib_hts_log_h) $(htslib_hts_h)
366cram/pooled_alloc.o cram/pooled_alloc.pico: cram/pooled_alloc.c config.h cram/pooled_alloc.h $(cram_misc_h)
367cram/rANS_static.o cram/rANS_static.pico: cram/rANS_static.c config.h cram/rANS_static.h cram/rANS_byte.h
368cram/string_alloc.o cram/string_alloc.pico: cram/string_alloc.c config.h cram/string_alloc.h
369thread_pool.o thread_pool.pico: thread_pool.c config.h $(thread_pool_internal_h) $(htslib_hts_log_h)
370
371
372bgzip: bgzip.o libhts.a
373	$(CC) $(LDFLAGS) -o $@ bgzip.o libhts.a $(LIBS) -lpthread
374
375htsfile: htsfile.o libhts.a
376	$(CC) $(LDFLAGS) -o $@ htsfile.o libhts.a $(LIBS) -lpthread
377
378tabix: tabix.o libhts.a
379	$(CC) $(LDFLAGS) -o $@ tabix.o libhts.a $(LIBS) -lpthread
380
381bgzip.o: bgzip.c config.h $(htslib_bgzf_h) $(htslib_hts_h)
382htsfile.o: htsfile.c config.h $(htslib_hfile_h) $(htslib_hts_h) $(htslib_sam_h) $(htslib_vcf_h)
383tabix.o: tabix.c config.h $(htslib_tbx_h) $(htslib_sam_h) $(htslib_vcf_h) $(htslib_kseq_h) $(htslib_bgzf_h) $(htslib_hts_h) $(htslib_regidx_h) $(htslib_hts_defs_h) $(htslib_hts_log_h)
384
385# Maintainer source code checks
386# - copyright boilerplate presence
387# - tab and trailing space detection
388maintainer-check:
389	test/maintainer/check_copyright.pl .
390	test/maintainer/check_spaces.pl .
391
392# For tests that might use it, set $REF_PATH explicitly to use only reference
393# areas within the test suite (or set it to ':' to use no reference areas).
394#
395# If using MSYS, avoid poor shell expansion via:
396#    MSYS2_ARG_CONV_EXCL="*" make check
397check test: $(BUILT_PROGRAMS) $(BUILT_TEST_PROGRAMS) $(BUILT_PLUGINS)
398	test/hts_endian
399	test/test_kfunc
400	test/test_kstring
401	test/test_str2int
402	test/fieldarith test/fieldarith.sam
403	test/hfile
404	HTS_PATH=. test/with-shlib.sh test/plugins-dlhts -g ./libhts.$(SHLIB_FLAVOUR)
405	HTS_PATH=. test/with-shlib.sh test/plugins-dlhts -l ./libhts.$(SHLIB_FLAVOUR)
406	test/test_bgzf test/bgziptest.txt
407	test/test-parse-reg -t test/colons.bam
408	cd test/tabix && ./test-tabix.sh tabix.tst
409	cd test/mpileup && ./test-pileup.sh mpileup.tst
410	REF_PATH=: test/sam test/ce.fa test/faidx.fa test/fastqs.fq
411	test/test-regidx
412	cd test && REF_PATH=: ./test.pl $${TEST_OPTS:-}
413
414test/hts_endian: test/hts_endian.o
415	$(CC) $(LDFLAGS) -o $@ test/hts_endian.o $(LIBS)
416
417test/fuzz/hts_open_fuzzer: test/fuzz/hts_open_fuzzer.o
418	$(CC) $(LDFLAGS) -o $@ test/fuzz/hts_open_fuzzer.o libhts.a $(LIBS) -lpthread
419
420test/fieldarith: test/fieldarith.o libhts.a
421	$(CC) $(LDFLAGS) -o $@ test/fieldarith.o libhts.a $(LIBS) -lpthread
422
423test/hfile: test/hfile.o libhts.a
424	$(CC) $(LDFLAGS) -o $@ test/hfile.o libhts.a $(LIBS) -lpthread
425
426test/pileup: test/pileup.o libhts.a
427	$(CC) $(LDFLAGS) -o $@ test/pileup.o libhts.a $(LIBS) -lpthread
428
429test/plugins-dlhts: test/plugins-dlhts.o
430	$(CC) $(LDFLAGS) -o $@ test/plugins-dlhts.o $(LIBS)
431
432test/sam: test/sam.o libhts.a
433	$(CC) $(LDFLAGS) -o $@ test/sam.o libhts.a $(LIBS) -lpthread
434
435test/test_bgzf: test/test_bgzf.o libhts.a
436	$(CC) $(LDFLAGS) -o $@ test/test_bgzf.o libhts.a -lz $(LIBS) -lpthread
437
438test/test_kfunc: test/test_kfunc.o libhts.a
439	$(CC) $(LDFLAGS) -o $@ test/test_kfunc.o libhts.a -lz $(LIBS) -lpthread
440
441test/test_kstring: test/test_kstring.o libhts.a
442	$(CC) $(LDFLAGS) -o $@ test/test_kstring.o libhts.a -lz $(LIBS) -lpthread
443
444test/test_realn: test/test_realn.o libhts.a
445	$(CC) $(LDFLAGS) -o $@ test/test_realn.o libhts.a $(LIBS) -lpthread
446
447test/test-regidx: test/test-regidx.o libhts.a
448	$(CC) $(LDFLAGS) -o $@ test/test-regidx.o libhts.a $(LIBS) -lpthread
449
450test/test-parse-reg: test/test-parse-reg.o libhts.a
451	$(CC) $(LDFLAGS) -o $@ test/test-parse-reg.o libhts.a $(LIBS) -lpthread
452
453test/test_str2int: test/test_str2int.o libhts.a
454	$(CC) $(LDFLAGS) -o $@ test/test_str2int.o libhts.a $(LIBS) -lpthread
455
456test/test_view: test/test_view.o libhts.a
457	$(CC) $(LDFLAGS) -o $@ test/test_view.o libhts.a $(LIBS) -lpthread
458
459test/test_index: test/test_index.o libhts.a
460	$(CC) $(LDFLAGS) -o $@ test/test_index.o libhts.a $(LIBS) -lpthread
461
462test/test-vcf-api: test/test-vcf-api.o libhts.a
463	$(CC) $(LDFLAGS) -o $@ test/test-vcf-api.o libhts.a $(LIBS) -lpthread
464
465test/test-vcf-sweep: test/test-vcf-sweep.o libhts.a
466	$(CC) $(LDFLAGS) -o $@ test/test-vcf-sweep.o libhts.a $(LIBS) -lpthread
467
468test/test-bcf-sr: test/test-bcf-sr.o libhts.a
469	$(CC) $(LDFLAGS) -o $@ test/test-bcf-sr.o libhts.a -lz $(LIBS) -lpthread
470
471test/test-bcf-translate: test/test-bcf-translate.o libhts.a
472	$(CC) $(LDFLAGS) -o $@ test/test-bcf-translate.o libhts.a -lz $(LIBS) -lpthread
473
474test/hts_endian.o: test/hts_endian.c config.h $(htslib_hts_endian_h)
475test/fuzz/hts_open_fuzzer.o: test/fuzz/hts_open_fuzzer.c config.h $(htslib_hfile_h) $(htslib_hts_h) $(htslib_sam_h) $(htslib_vcf_h)
476test/fieldarith.o: test/fieldarith.c config.h $(htslib_sam_h)
477test/hfile.o: test/hfile.c config.h $(htslib_hfile_h) $(htslib_hts_defs_h) $(htslib_kstring_h)
478test/pileup.o: test/pileup.c config.h $(htslib_sam_h) $(htslib_kstring_h)
479test/plugins-dlhts.o: test/plugins-dlhts.c config.h
480test/sam.o: test/sam.c config.h $(htslib_hts_defs_h) $(htslib_sam_h) $(htslib_faidx_h) $(htslib_khash_h) $(htslib_hts_log_h)
481test/test_bgzf.o: test/test_bgzf.c config.h $(htslib_bgzf_h) $(htslib_hfile_h) $(hfile_internal_h)
482test/test_kfunc.o: test/test_kfunc.c config.h $(htslib_kfunc_h)
483test/test_kstring.o: test/test_kstring.c config.h $(htslib_kstring_h)
484test/test-parse-reg.o: test/test-parse-reg.c config.h $(htslib_hts_h) $(htslib_sam_h)
485test/test_realn.o: test/test_realn.c config.h $(htslib_hts_h) $(htslib_sam_h) $(htslib_faidx_h)
486test/test-regidx.o: test/test-regidx.c config.h $(htslib_kstring_h) $(htslib_regidx_h) $(htslib_hts_defs_h) $(textutils_internal_h)
487test/test_str2int.o: test/test_str2int.c config.h $(textutils_internal_h)
488test/test_view.o: test/test_view.c config.h $(cram_h) $(htslib_sam_h) $(htslib_vcf_h) $(htslib_hts_log_h)
489test/test_index.o: test/test_index.c config.h $(htslib_sam_h) $(htslib_vcf_h)
490test/test-vcf-api.o: test/test-vcf-api.c config.h $(htslib_hts_h) $(htslib_vcf_h) $(htslib_kstring_h) $(htslib_kseq_h)
491test/test-vcf-sweep.o: test/test-vcf-sweep.c config.h $(htslib_vcf_sweep_h)
492test/test-bcf-sr.o: test/test-bcf-sr.c config.h $(htslib_synced_bcf_reader_h)
493test/test-bcf-translate.o: test/test-bcf-translate.c config.h $(htslib_vcf_h)
494
495
496test/thrash_threads1: test/thrash_threads1.o libhts.a
497	$(CC) $(LDFLAGS) -o $@ test/thrash_threads1.o libhts.a -lz $(LIBS) -lpthread
498
499test/thrash_threads2: test/thrash_threads2.o libhts.a
500	$(CC) $(LDFLAGS) -o $@ test/thrash_threads2.o libhts.a -lz $(LIBS) -lpthread
501
502test/thrash_threads3: test/thrash_threads3.o libhts.a
503	$(CC) $(LDFLAGS) -o $@ test/thrash_threads3.o libhts.a -lz $(LIBS) -lpthread
504
505test/thrash_threads4: test/thrash_threads4.o libhts.a
506	$(CC) $(LDFLAGS) -o $@ test/thrash_threads4.o libhts.a -lz $(LIBS) -lpthread
507
508test/thrash_threads5: test/thrash_threads5.o libhts.a
509	$(CC) $(LDFLAGS) -o $@ test/thrash_threads5.o libhts.a -lz $(LIBS) -lpthread
510
511test/thrash_threads6: test/thrash_threads6.o libhts.a
512	$(CC) $(LDFLAGS) -o $@ test/thrash_threads6.o libhts.a -lz $(LIBS) -lpthread
513
514test/thrash_threads7: test/thrash_threads7.o libhts.a
515	$(CC) $(LDFLAGS) -o $@ test/thrash_threads7.o libhts.a -lz $(LIBS) -lpthread
516
517test_thrash: $(BUILT_THRASH_PROGRAMS)
518
519# Test to ensure the functions in the header files are exported by the shared
520# library.  This currently works by comparing the output from ctags on
521# the headers with the list of functions exported by the shared library.
522# Note that functions marked as exported in the .c files and not the public
523# headers will be missed by this test.
524test-shlib-exports: header-exports.txt shlib-exports-$(SHLIB_FLAVOUR).txt
525	@echo "Checking shared library exports"
526	@if test ! -s header-exports.txt ; then echo "Error: header-exports.txt empty" ; false ; fi
527	@if test ! -s shlib-exports-$(SHLIB_FLAVOUR).txt ; then echo "Error: shlib-exports-$(SHLIB_FLAVOUR).txt empty" ; false ; fi
528	@! comm -23 header-exports.txt shlib-exports-$(SHLIB_FLAVOUR).txt | grep . || \
529	( echo "Error: Found unexported symbols (listed above)" ; false )
530
531# Extract symbols that should be exported from public headers using ctags
532# Filter out macros in htslib/hts_defs.h, and knet_win32_ functions that
533# aren't needed on non-Windows platforms.
534header-exports.txt: test/header_syms.pl htslib/*.h
535	test/header_syms.pl htslib/*.h | sort -u -o $@
536
537shlib-exports-so.txt: libhts.so
538	nm -D -g libhts.so | awk '$$2 == "T" { print $$3 }' | sort -u -o $@
539
540shlib-exports-dylib.txt: libhts.dylib
541	nm -Ug libhts.dylib | awk '$$2 == "T" { sub("^_", "", $$3); print $$3 }' | sort -u -o $@
542
543shlib-exports-dll.txt: hts.dll.a
544	nm -g hts.dll.a | awk '$$2 == "T" { print $$3 }' | sort -u -o $@
545
546install: libhts.a $(BUILT_PROGRAMS) $(BUILT_PLUGINS) installdirs install-$(SHLIB_FLAVOUR) install-pkgconfig
547	$(INSTALL_PROGRAM) $(BUILT_PROGRAMS) $(DESTDIR)$(bindir)
548	if test -n "$(BUILT_PLUGINS)"; then $(INSTALL_PROGRAM) $(BUILT_PLUGINS) $(DESTDIR)$(plugindir); fi
549	$(INSTALL_DATA) htslib/*.h $(DESTDIR)$(includedir)/htslib
550	$(INSTALL_DATA) libhts.a $(DESTDIR)$(libdir)/libhts.a
551	$(INSTALL_MAN) bgzip.1 htsfile.1 tabix.1 $(DESTDIR)$(man1dir)
552	$(INSTALL_MAN) faidx.5 sam.5 vcf.5 $(DESTDIR)$(man5dir)
553	$(INSTALL_MAN) htslib-s3-plugin.7 $(DESTDIR)$(man7dir)
554
555installdirs:
556	$(INSTALL_DIR) $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(includedir)/htslib $(DESTDIR)$(libdir) $(DESTDIR)$(man1dir) $(DESTDIR)$(man5dir) $(DESTDIR)$(man7dir) $(DESTDIR)$(pkgconfigdir)
557	if test -n "$(plugindir)"; then $(INSTALL_DIR) $(DESTDIR)$(plugindir); fi
558
559# After installation, the real file in $(libdir) will be libhts.so.X.Y.Z,
560# with symlinks libhts.so (used via -lhts during linking of client programs)
561# and libhts.so.NN (used by client executables at runtime).
562
563install-so: libhts.so installdirs
564	$(INSTALL_LIB) libhts.so $(DESTDIR)$(libdir)/libhts.so.$(PACKAGE_VERSION)
565	ln -sf libhts.so.$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libhts.so
566	ln -sf libhts.so.$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libhts.so.$(LIBHTS_SOVERSION)
567
568install-cygdll: cyghts-$(LIBHTS_SOVERSION).dll installdirs
569	$(INSTALL_PROGRAM) cyghts-$(LIBHTS_SOVERSION).dll $(DESTDIR)$(bindir)/cyghts-$(LIBHTS_SOVERSION).dll
570	$(INSTALL_PROGRAM) libhts.dll.a $(DESTDIR)$(libdir)/libhts.dll.a
571
572install-dll: hts-$(LIBHTS_SOVERSION).dll installdirs
573	$(INSTALL_PROGRAM) hts-$(LIBHTS_SOVERSION).dll $(DESTDIR)$(bindir)/hts-$(LIBHTS_SOVERSION).dll
574	$(INSTALL_PROGRAM) hts.dll.a $(DESTDIR)$(libdir)/hts.dll.a
575
576install-dylib: libhts.dylib installdirs
577	$(INSTALL_PROGRAM) libhts.dylib $(DESTDIR)$(libdir)/libhts.$(PACKAGE_VERSION).dylib
578	ln -sf libhts.$(PACKAGE_VERSION).dylib $(DESTDIR)$(libdir)/libhts.dylib
579	ln -sf libhts.$(PACKAGE_VERSION).dylib $(DESTDIR)$(libdir)/libhts.$(LIBHTS_SOVERSION).dylib
580
581# Substitute these pseudo-autoconf variables only at install time
582# so that "make install prefix=/prefix/path" etc continue to work.
583install-pkgconfig: htslib.pc.tmp installdirs
584	sed -e 's#@-includedir@#$(includedir)#g;s#@-libdir@#$(libdir)#g;s#@-PACKAGE_VERSION@#$(PACKAGE_VERSION)#g' htslib.pc.tmp > $(DESTDIR)$(pkgconfigdir)/htslib.pc
585	chmod 644 $(DESTDIR)$(pkgconfigdir)/htslib.pc
586
587# A pkg-config file (suitable for copying to $PKG_CONFIG_PATH) that provides
588# flags for building against the uninstalled library in this build directory.
589htslib-uninstalled.pc: htslib.pc.tmp
590	sed -e 's#@-includedir@#'`pwd`'#g;s#@-libdir@#'`pwd`'#g' htslib.pc.tmp > $@
591
592
593testclean:
594	-rm -f test/*.tmp test/*.tmp.* test/longrefs/*.tmp.* test/tabix/*.tmp.* test/tabix/FAIL* header-exports.txt shlib-exports-$(SHLIB_FLAVOUR).txt
595
596mostlyclean: testclean
597	-rm -f *.o *.pico cram/*.o cram/*.pico test/*.o test/*.dSYM version.h
598	-rm -f hts-object-files
599
600clean: mostlyclean clean-$(SHLIB_FLAVOUR)
601	-rm -f libhts.a $(BUILT_PROGRAMS) $(BUILT_PLUGINS) $(BUILT_TEST_PROGRAMS) $(BUILT_THRASH_PROGRAMS)
602
603distclean maintainer-clean: clean
604	-rm -f config.cache config.h config.log config.mk config.status
605	-rm -f TAGS *.pc.tmp *-uninstalled.pc htslib_static.mk
606	-rm -rf autom4te.cache
607
608clean-so:
609	-rm -f libhts.so libhts.so.*
610
611clean-cygdll:
612	-rm -f cyghts-*.dll libhts.dll.a
613
614clean-dll:
615	-rm -f hts-*.dll hts.dll.a
616
617clean-dylib:
618	-rm -f libhts.dylib libhts.*.dylib
619
620
621tags TAGS:
622	ctags -f TAGS *.[ch] cram/*.[ch] htslib/*.h
623
624# We recommend libhts-using programs be built against a separate htslib
625# installation.  However if you feel that you must bundle htslib source
626# code with your program, this hook enables Automake-style "make dist"
627# for this subdirectory.  If you do bundle an htslib snapshot, please
628# add identifying information to $(PACKAGE_VERSION) as appropriate.
629# (The wildcards attempt to omit non-exported files (.git*, README.md,
630# etc) and other detritus that might be in the top-level directory.)
631distdir:
632	@if [ -z "$(distdir)" ]; then echo "Please supply a distdir=DIR argument."; false; fi
633	tar -c *.[ch15] [ILMNRchtv]*[ELSbcekmnth] | (cd $(distdir) && tar -x)
634	+cd $(distdir) && $(MAKE) distclean
635
636force:
637
638
639.PHONY: all check clean distclean distdir force
640.PHONY: install install-pkgconfig installdirs lib-shared lib-static
641.PHONY: maintainer-check maintainer-clean mostlyclean plugins
642.PHONY: print-config print-version show-version tags
643.PHONY: test test-shlib-exports test_thrash testclean
644.PHONY: clean-so install-so
645.PHONY: clean-cygdll install-cygdll
646.PHONY: clean-dll install-dll
647.PHONY: clean-dylib install-dylib
648