rust-htslib 0.32.0

This library provides HTSlib bindings and a high level Rust API for reading and writing BAM files.
Documentation
FROM rustembedded/cross:x86_64-unknown-linux-musl

ENV MUSL_CROSS_MAKE_VERSION 0.9.9
ENV PKG_CONFIG_ALLOW_CROSS 1
ENV LZMA_VERSION 5.2.5
ENV ZLIB_VERSION 1.2.11
ENV OPENSSL_VERSION 1_1_1g
ENV CURL_VERSION 7.70.0

ENV LIBCLANG_PATH /usr/lib/llvm-10/lib
ENV LLVM_CONFIG_PATH /usr/bin


# The default includes and packages from the Ubuntu distro that cross uses will generate all sorts of linux-headers related include errors, see:
#   https://github.com/rust-bio/rust-htslib/pull/184#commitcomment-37496651
# Those are the packages installed, hopefully someone will find a good way to use the distro ones instead of compiling everything under /usr/local :/
#    apt-get install -y libssl-dev libcurl4-openssl-dev zlib1g-dev libbz2-dev liblzma-dev musl musl-dev musl-tools linux-libc-dev linux-headers-4.15.0-20-generic

# Install basics to locally compile htslib dependencies
RUN apt-get update && \
            apt-get install -y build-essential autoconf automake autotools-dev git wget

# Otherwise LLVM bump below fails
RUN apt-get install -y wget gnupg lsb-release software-properties-common apt-transport-https ca-certificates

# Autodetect and fetch latest LLVM repos for the current distro, avoids LLVM warnings and other issues, might generate slower builds for now though, see:
# https://www.phoronix.com/scan.php?page=news_item&px=Rust-Hurt-On-LLVM-10
RUN bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
#RUN apt-get install -y libssl-dev libcurl4-openssl-dev zlib1g-dev \
#			libbz2-dev liblzma-dev musl musl-dev musl-tools # htslib deps

# Remove pre-installed musl, to avoid cross-musl-make interference
RUN apt-get remove -y musl

# For now we'll have to go nuts and not only build musl-1.2.0 from scratch but all the other libs too...
# Updated musl-cross toolchain that does not fail on OpenSSL: https://github.com/openssl/openssl/issues/7207
WORKDIR /root
RUN wget https://github.com/richfelker/musl-cross-make/archive/v$MUSL_CROSS_MAKE_VERSION.tar.gz \
    && tar xvfz v$MUSL_CROSS_MAKE_VERSION.tar.gz
WORKDIR /root/musl-cross-make-$MUSL_CROSS_MAKE_VERSION
COPY config-musl-cross-make.mak config.mak
RUN make -j40 install && cd .. && rm v$MUSL_CROSS_MAKE_VERSION.tar.gz
			       #&& rm -rf musl-cross-make-*

# Now we assume we have a properly configured musl-cross...
ENV PATH "/usr/local/musl/bin:$PATH"
ENV CFLAGS "-fPIC"
ENV CROSS_COMPILE x86_64-linux-musl-
ENV CC ${CROSS_COMPILE}cc
ENV AR ${CROSS_COMPILE}ar
ENV RANLIB ${CROSS_COMPILE}ranlib
ENV CXX ${CROSS_COMPILE}g++
ENV CPPFLAGS "-I/usr/local/musl/include -I/usr/local/include"
ENV LDFLAGS "-L/usr/local/musl/lib -L/usr/local/lib"

# .. and carry on with the htslib deps
WORKDIR /root
RUN git clone --depth 1 https://github.com/ebiggers/libdeflate.git && \
    cd libdeflate && make -j40 CFLAGS="-fPIC -O3" PREFIX="/usr/local/musl" install && \
    cd .. && rm -rf libdeflate
RUN git clone https://github.com/cloudflare/zlib cloudflare-zlib && \
    cd cloudflare-zlib && ./configure --static --prefix=/usr/local/musl && \
    make install && cd .. && rm -rf cloudflare-zlib
#RUN wget https://www.zlib.net/zlib-$ZLIB_VERSION.tar.gz \
#    && tar xvfz zlib-$ZLIB_VERSION.tar.gz \
#    && cd zlib-$ZLIB_VERSION \
#    && ./configure --static --prefix=/usr/local/musl \
#    && make -j40 install
RUN git clone git://sourceware.org/git/bzip2 \
    && cd bzip2 \
    && make -j40 CC=$CC AR=$AR RANLIB=$RANLIB CFLAGS=$CFLAGS bzip2 \
    && make PREFIX=/usr/local/musl -j40 bzip2 \
    && make -j40 install && cd .. && rm -rf bzip2
RUN wget https://tukaani.org/xz/xz-$LZMA_VERSION.tar.bz2 \
    && tar xvfj xz-$LZMA_VERSION.tar.bz2 \
    && cd xz-$LZMA_VERSION \
    && ./configure --prefix=/usr/local/musl \
	--enable-static --disable-shared \
	--host x86_64-unknown-linux-musl \
    && make -j40 install && cd .. && rm -rf xz-$LZMA_VERSION xz-$LZMA_VERSION.tar.bz2

# A few gems from: https://wiki.openssl.org/index.php/Compilation_and_Installation
# "OpenSSL has been around a long time, and it carries around a lot of cruft"
# "SSLv2 is completely broken, and you should disable it during configuration"
# "You should specify both --prefix and --openssldir to ensure make install works as expected."
#
# And also this:
# https://github.com/openssl/openssl/issues/11362
#
# And having to redefine AR,CC & RANLIB because otherwise, this:
#
# make[1]: x86_64-linux-musl-x86_64-linux-musl-ar: Command not found
RUN wget https://github.com/openssl/openssl/archive/OpenSSL_$OPENSSL_VERSION.tar.gz \
    && tar xvfz OpenSSL_$OPENSSL_VERSION.tar.gz && cd openssl-OpenSSL_$OPENSSL_VERSION \
    && ./Configure --prefix=/usr/local/musl --openssldir=/usr/local/musl \
                --with-zlib-lib=/usr/local/lib/zlib-$ZLIB_VERSION linux-x86_64 \
                no-shared no-dso no-gost no-engine no-ssl2 no-srp no-srtp no-tests zlib \
                no-weak-ssl-ciphers \
    && make AR=x86_64-linux-musl-ar \
            CC=x86_64-linux-musl-cc \
            -j40 \
    && make RANLIB=x86_64-linux-musl-ranlib -j40 install && cd .. \
    && rm -rf OpenSSL_$OPENSSL_VERSION.tar.gz openssl-OpenSSL_$OPENSSL_VERSION

RUN wget https://curl.haxx.se/download/curl-$CURL_VERSION.tar.gz \
    && tar xvfz curl-$CURL_VERSION.tar.gz && cd curl-$CURL_VERSION \
    && ./configure --prefix=/usr/local/musl --host x86_64-linux-musl \
        --with-ssl=/usr/local/musl --with-zlib=/usr/local/musl --enable-static \
        --disable-dict --disable-ftp --disable-gopher --disable-imap \
        --disable-pop3 --disable-rtsp --disable-smb --disable-smtp --disable-telnet \
        --disable-tftp --disable-ntlm --disable-ldap \
        && make -j40 install && cd .. \
	&& rm -rf curl-$CURL_VERSION.tar.gz curl-$CURL_VERSION

# To cater Rust's openssl-sys needs...
ENV OPENSSL_DIR /usr/local/musl

# Hack to force ld stick to musl on the hts-sys/build.rs side, otherwise:
#   = note: /usr/bin/ld: /target/debug/deps/liblibloading-689161fea10b6234.rlib(global_static.o): unable to initialize decompress status for section .debug_info
RUN rm /usr/bin/ld && ln -sf /usr/local/musl/bin/x86_64-linux-musl-ld /usr/bin/ld

# Prepare rustup and toolchain locally for easy manual intervention in this container
#RUN wget https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init \
#    && chmod +x rustup-init \
#    && ./rustup-init -y \
#    && . $HOME/.cargo/env \
#    && rustup target add x86_64-unknown-linux-musl

CMD ["bash"]