Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# version format.
# you can use {branch} name in version format too
# version: 1.0.{build}-{branch}
version: 'vers.{build}'

# branches to build
branches:
# Whitelist
only:
- develop

# Blacklist
except:
- gh-pages

# Do not build on tags (GitHub and BitBucket)
skip_tags: true

# Skipping commits affecting specific files (GitHub only). More details here: /docs/appveyor-yml
#skip_commits:
# files:
# - docs/*
# - '**/*.html'

# We use Mingw/Msys, so use pacman for installs
install:
- set HOME=.
- set MSYSTEM=MINGW64
- set PATH=C:/msys64/usr/bin;C:/msys64/mingw64/bin;%PATH%
- set MINGWPREFIX=x86_64-w64-mingw32
- "sh -lc \"pacman -S --noconfirm --needed base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-zlib mingw-w64-x86_64-bzip2 mingw-w64-x86_64-xz mingw-w64-x86_64-curl\""

build_script:
- set HOME=.
- set MSYSTEM=MINGW64
- set PATH=C:/msys64/usr/bin;C:/msys64/mingw64/bin;%PATH%
- "sh -lc \"aclocal && autoheader && autoconf && ./configure && make -j2\""

#build_script:
# - make

test_script:
- "sh -lc \"make test\""
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@
.git* export-ignore
/.travis.yml export-ignore
README.md export-ignore

# Remove the text attribute from reference files, so that git doesn't convert
# line separators on Windows machines. It causes the index files to become out
# of sync with the fasta files.
*.fa* -text
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
*.o
*.pico
*.obj
*.dSYM
*.exe
*.dll
*.pc.tmp
*-uninstalled.pc
/version.h
Expand Down
6 changes: 6 additions & 0 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ library is used. Systems that do not have CChmac will get this from
libcrypto. libcrypto is part of OpenSSL or one of its derivatives (LibreSSL
or BoringSSL).

On Microsoft Windows we recommend use of Mingw64/Msys2. Note that
currently for the test harness to work you will need to override the
test temporary directory with e.g.: make check TEST_OPTS="-t C:/msys64/tmp/_"
Whilst the code may work on Windows with other environments, these have
not be verified.

Building Configure
==================

Expand Down
24 changes: 23 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ LIBHTS_OBJS = \
hfile.o \
hfile_net.o \
hts.o \
hts_os.o\
md5.o \
multipart.o \
probaln.o \
Expand Down Expand Up @@ -208,6 +209,7 @@ config.h:
echo '/* Default config.h generated by Makefile */' > $@
echo '#define HAVE_LIBBZ2 1' >> $@
echo '#define HAVE_LIBLZMA 1' >> $@
echo '#define HAVE_DRAND48 1' >> $@

# And similarly for htslib.pc.tmp ("pkg-config template"). No dependency
# on htslib.pc.in listed, as if that file is newer the usual way to regenerate
Expand Down Expand Up @@ -235,6 +237,9 @@ lib-shared: libhts.dylib
else ifeq "$(findstring CYGWIN,$(PLATFORM))" "CYGWIN"
SHLIB_FLAVOUR = cygdll
lib-shared: cyghts-$(LIBHTS_SOVERSION).dll
else ifeq "$(findstring MSYS,$(PLATFORM))" "MSYS"
SHLIB_FLAVOUR = dll
lib-shared: hts-$(LIBHTS_SOVERSION).dll
else
SHLIB_FLAVOUR = so
lib-shared: libhts.so
Expand Down Expand Up @@ -276,6 +281,9 @@ libhts.dylib: $(LIBHTS_OBJS)
cyghts-$(LIBHTS_SOVERSION).dll: $(LIBHTS_OBJS)
$(CC) -shared -Wl,--out-implib=libhts.dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import $(LDFLAGS) -o $@ -Wl,--whole-archive $(LIBHTS_OBJS) -Wl,--no-whole-archive $(LIBS) -lpthread

hts-$(LIBHTS_SOVERSION).dll: $(LIBHTS_OBJS)
$(CC) -shared -Wl,--out-implib=hts.dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import $(LDFLAGS) -o $@ -Wl,--whole-archive $(LIBHTS_OBJS) -Wl,--no-whole-archive $(LIBS) -lpthread


.pico.so:
$(CC) -shared -Wl,-E $(LDFLAGS) -o $@ $< $(LIBS) -lpthread
Expand All @@ -286,6 +294,9 @@ cyghts-$(LIBHTS_SOVERSION).dll: $(LIBHTS_OBJS)
.o.cygdll:
$(CC) -shared $(LDFLAGS) -o $@ $< libhts.dll.a $(LIBS)

.o.dll:
$(CC) -shared $(LDFLAGS) -o $@ $< hts.dll.a $(LIBS)


bgzf.o bgzf.pico: bgzf.c config.h $(htslib_hts_h) $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_thread_pool_h) cram/pooled_alloc.h $(htslib_khash_h)
errmod.o errmod.pico: errmod.c config.h $(htslib_hts_h) $(htslib_ksort_h)
Expand Down Expand Up @@ -348,6 +359,9 @@ tabix.o: tabix.c config.h $(htslib_tbx_h) $(htslib_sam_h) $(htslib_vcf_h) $(htsl

# For tests that might use it, set $REF_PATH explicitly to use only reference
# areas within the test suite (or set it to ':' to use no reference areas).
#
# If using MSYS, avoid poor shell expansion via:
# MSYS2_ARG_CONV_EXCL="*" make check
check test: $(BUILT_PROGRAMS) $(BUILT_TEST_PROGRAMS)
test/hts_endian
test/fieldarith test/fieldarith.sam
Expand All @@ -356,7 +370,7 @@ check test: $(BUILT_PROGRAMS) $(BUILT_TEST_PROGRAMS)
cd test/tabix && ./test-tabix.sh tabix.tst
REF_PATH=: test/sam test/ce.fa test/faidx.fa
test/test-regidx
cd test && REF_PATH=: ./test.pl
cd test && REF_PATH=: ./test.pl $${TEST_OPTS:-}

test/hts_endian: test/hts_endian.o
$(CC) $(LDFLAGS) -o $@ test/hts_endian.o $(LIBS)
Expand Down Expand Up @@ -446,6 +460,10 @@ install-cygdll: cyghts-$(LIBHTS_SOVERSION).dll installdirs
$(INSTALL_PROGRAM) cyghts-$(LIBHTS_SOVERSION).dll $(DESTDIR)$(bindir)/cyghts-$(LIBHTS_SOVERSION).dll
$(INSTALL_PROGRAM) libhts.dll.a $(DESTDIR)$(libdir)/libhts.dll.a

install-dll: hts-$(LIBHTS_SOVERSION).dll installdirs
$(INSTALL_PROGRAM) hts-$(LIBHTS_SOVERSION).dll $(DESTDIR)$(bindir)/hts-$(LIBHTS_SOVERSION).dll
$(INSTALL_PROGRAM) hts.dll.a $(DESTDIR)$(libdir)/hts.dll.a

install-dylib: libhts.dylib installdirs
$(INSTALL_PROGRAM) libhts.dylib $(DESTDIR)$(libdir)/libhts.$(PACKAGE_VERSION).dylib
ln -sf libhts.$(PACKAGE_VERSION).dylib $(DESTDIR)$(libdir)/libhts.dylib
Expand Down Expand Up @@ -483,6 +501,9 @@ clean-so:
clean-cygdll:
-rm -f cyghts-*.dll libhts.dll.a

clean-dll:
-rm -f hts-*.dll hts.dll.a

clean-dylib:
-rm -f libhts.dylib libhts.*.dylib

Expand Down Expand Up @@ -510,4 +531,5 @@ force:
.PHONY: tags test testclean
.PHONY: clean-so install-so
.PHONY: clean-cygdll install-cygdll
.PHONY: clean-dll install-dll
.PHONY: clean-dylib install-dylib
4 changes: 4 additions & 0 deletions bgzf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,9 @@ static int bgzf_check_EOF_common(BGZF *fp)
off_t offset = htell(fp->fp);
if (hseek(fp->fp, -28, SEEK_END) < 0) {
if (errno == ESPIPE) { hclearerr(fp->fp); return 2; }
#ifdef _WIN32
if (errno == EINVAL) { hclearerr(fp->fp); return 2; }
#endif
else return -1;
}
if ( hread(fp->fp, buf, 28) != 28 ) return -1;
Expand Down Expand Up @@ -1179,6 +1182,7 @@ static void *bgzf_mt_reader(void *vp) {
pthread_exit(NULL);
}
}
return NULL;
}

int bgzf_thread_pool(BGZF *fp, hts_tpool *pool, int qsize) {
Expand Down
18 changes: 17 additions & 1 deletion bgzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
#include "htslib/bgzf.h"
#include "htslib/hts.h"

#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif

static const int WINDOW_SIZE = 64 * 1024;

static void error(const char *format, ...)
Expand Down Expand Up @@ -198,6 +203,9 @@ int main(int argc, char **argv)

if ( index ) bgzf_index_build_init(fp);
buffer = malloc(WINDOW_SIZE);
#ifdef _WIN32
_setmode(f_src, O_BINARY);
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the decision here is to have bgzip open everything as binary (cf second paragraph of this comment), wouldn't it be better to just use hopen() rather than sprinkling _WIN32 platform crap all over the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we decided that hopen musn't do the O_BINARY setmode thing itself, indeed I recall you squashing a PR on that very reason. Plus again we'd be changing bgzip on Unix in order to make it run on Windows, which comes with potential bugs and risks. I'm happier with a windows-only change personally.

The change was made for a reason (it fixes bugs). If your view is that bgzip must NOT open everything as binary then we need to change the tool further still, adding a command line argument to tell it whether or not to treat stdin as text or binary. Yet more complications.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reread my comment. It's talking about changing bgzip.c to use hopen instead of open. It does not propose altering the implementation of hopen itself.

I changed bgzip's BGZF files from open to (effectively) hopen in b8204c1 during the PR you mention, which is linked in my previous comment. I would have rather liked to change its other files too as it simplifies and regularises the code, but I had not analysed the effects that would have on Windows, as I noted at the time.

The change was made for a reason (it fixes bugs).

Apparently you have now analysed the effects, though that wasn't apparent from the commit messages. Grand; and I guess it gives bgzip -i a chance to have the right offsets.

So the maintenance question is about the risks of a change that affects all platforms while regularising and simplifying the code, versus one that adds the maintenance burden of #ifdef spaghetti.

if (rebgzip){
if ( bgzf_index_load(fp, index_fname, NULL) < 0 ) error("Could not load index: %s.gzi\n", argv[optind]);

Expand Down Expand Up @@ -319,13 +327,21 @@ int main(int argc, char **argv)
if ( bgzf_index_load(fp, argv[optind], ".gzi") < 0 ) error("Could not load index: %s.gzi\n", argv[optind]);
if ( bgzf_useek(fp, start, SEEK_SET) < 0 ) error("Could not seek to %d-th (uncompressd) byte\n", start);
}
#ifdef _WIN32
_setmode(f_dst, O_BINARY);
#endif
while (1) {
if (end < 0) c = bgzf_read(fp, buffer, WINDOW_SIZE);
else c = bgzf_read(fp, buffer, (end - start > WINDOW_SIZE)? WINDOW_SIZE:(end - start));
if (c == 0) break;
if (c < 0) error("Could not read %d bytes: Error %d\n", (end - start > WINDOW_SIZE)? WINDOW_SIZE:(end - start), fp->errcode);
start += c;
if ( write(f_dst, buffer, c) != c ) error("Could not write %d bytes\n", c);
if ( write(f_dst, buffer, c) != c ) {
#ifdef _WIN32
if (GetLastError() != ERROR_NO_DATA)
#endif
error("Could not write %d bytes\n", c);
}
if (end >= 0 && start >= end) break;
}
free(buffer);
Expand Down
21 changes: 16 additions & 5 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ AC_ARG_ENABLE([s3],
[support Amazon AWS S3 URLs])],
[], [enable_s3=check])

AC_MSG_CHECKING([shared library type])
test -n "$host_alias" || host_alias=unknown-`uname -s`
AC_MSG_CHECKING([shared library type for $host_alias])
case $host_alias in
*-cygwin* | *-CYGWIN*)
host_result="Cygwin DLL"
Expand All @@ -125,6 +125,15 @@ case $host_alias in
PLATFORM=Darwin
PLUGIN_EXT=.bundle
;;
*-msys* | *-MSYS* | *-mingw* | *-MINGW*)
host_result="MSYS dll"
PLATFORM=MSYS
PLUGIN_EXT=.dll
# This also sets __USE_MINGW_ANSI_STDIO which in turn makes PRId64,
# %lld and %z printf formats work. It also enforces the snprintf to
# be C99 compliant so it returns the correct values (in kstring.c).
CPPFLAGS="$CPPCFLAGS -D_XOPEN_SOURCE=600"
;;
*)
host_result="plain .so"
PLATFORM=default
Expand All @@ -136,7 +145,7 @@ AC_SUBST([PLATFORM])

dnl FIXME This pulls in dozens of standard header checks
AC_FUNC_MMAP
AC_CHECK_FUNCS(gmtime_r)
AC_CHECK_FUNCS([gmtime_r fsync drand48])

# Darwin has a dubious fdatasync() symbol, but no declaration in <unistd.h>
AC_CHECK_DECL([fdatasync(int)], [AC_CHECK_FUNCS(fdatasync)])
Expand Down Expand Up @@ -183,9 +192,11 @@ FAILED. This error must be resolved in order to build HTSlib successfully.])
fi

dnl connect() etc. fns are in libc on linux, but libsocket on illumos/Solaris
libsocket=unneeded
AC_SEARCH_LIBS(connect, socket, [libsocket=needed], [])

AC_SEARCH_LIBS([recv], [socket ws2_32], [
if test "$ac_cv_search_recv" != "none required"
then
static_LIBS="$static_LIBS $ac_cv_search_recv"
fi], [AC_MSG_ERROR([unable to find the recv() function])])

if test "$enable_bz2" != no; then
bz2_devel=ok
Expand Down
2 changes: 1 addition & 1 deletion cram/cram_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,7 @@ static int cram_add_insertion(cram_container *c, cram_slice *s, cram_record *r,
}

/*
* Encodes auxiliary data.
* Encodes auxiliary data, CRAM 1.0 format.
* Returns the read-group parsed out of the BAM aux fields on success
* NULL on failure or no rg present (FIXME)
*/
Expand Down
8 changes: 6 additions & 2 deletions cram/cram_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,7 @@ char *cram_block_method2str(enum cram_block_method m) {
case RANS0: return "RANS0";
case RANS1: return "RANS1";
case GZIP_RLE: return "GZIP_RLE";
case ERROR: break;
case BM_ERROR: break;
}
return "?";
}
Expand Down Expand Up @@ -3663,7 +3663,11 @@ SAM_hdr *cram_read_SAM_hdr(cram_fd *fd) {
* Out must be at least PATH_MAX bytes long.
*/
static void full_path(char *out, char *in) {
if (*in == '/') {
size_t in_l = strlen(in);
if (*in == '/' ||
// Windows paths
(in_l > 3 && toupper(*in) >= 'A' && toupper(*in) <= 'Z' &&
in[1] == ':' && (in[2] == '/' || in[2] == '\\'))) {
strncpy(out, in, PATH_MAX);
out[PATH_MAX-1] = 0;
} else {
Expand Down
2 changes: 1 addition & 1 deletion cram/cram_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ typedef struct cram_file_def {
struct cram_slice;

enum cram_block_method {
ERROR = -1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change and its parallel MF_APPEND are caused by a clash with Windows.h. The workaround used here certainly works, but I'd recommend a less intrusive one instead: define NOUSER and NOGDI when compiling libhts. That shouldn't interfere with anything on any other platforms.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noted that the affected header files aren't part of the public API. So perhaps less of an issue than I originally thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. I figured it's probably a good move anyway to minimally name-space that ERROR enum as the potential for clashes on other systems will be reduced.

BM_ERROR = -1,
RAW = 0,
GZIP = 1,
BZIP2 = 2,
Expand Down
5 changes: 5 additions & 0 deletions cram/mFILE.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ typedef struct {
size_t flush_pos;
} mFILE;

// Work around a clash with winuser.h
#ifdef MF_APPEND
# undef MF_APPEND
#endif

#define MF_READ 1
#define MF_WRITE 2
#define MF_APPEND 4
Expand Down
24 changes: 5 additions & 19 deletions cram/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,27 +205,13 @@ static inline uint16_t le_int2(uint16_t x) {
* Microsoft Windows running MinGW
*/
#if defined(__MINGW32__)
/* #define mkdir(filename,mode) mkdir((filename)) */
#include <io.h>
#define mkdir(filename,mode) mkdir((filename))
#define sysconf(x) 512
#define ftruncate(fd,len) _chsize(fd,len)
#ifndef ftruncate
# define ftruncate(fd,len) _chsize(fd,len)
#endif
#endif

/* Generic WIN32 API issues */
#ifdef _WIN32
# ifndef HAVE_FSEEKO
# if __MSVCRT_VERSION__ >= 0x800
/* if you have MSVCR80 installed then you can use these definitions: */
# define off_t __int64
# define fseeko _fseeki64
# define ftello _ftelli64
# else
/* otherwise we're stuck with 32-bit file support */
# define off_t long
# define fseeko fseek
# define ftello ftell
# endif
# endif /* !HAVE_FSEEKO */
#endif /* _WIN32 */

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions errmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ DEALINGS IN THE SOFTWARE. */
#include <math.h>
#include "htslib/hts.h"
#include "htslib/ksort.h"
#include "htslib/hts_os.h" // for drand48

KSORT_INIT_GENERIC(uint16_t)

struct errmod_t {
Expand Down
Loading