拷贝一下Docker中Kaldi for android编译步骤,手动编译也可以参照此步骤
来源于:https://github.com/jcsilva/docker-kaldi-androidDockerfile:FROM ubuntu:16.04RUN mkdir -p /opt/android-sdk-linux && mkdir -p ~/.android && touch ~/.android/repositories.cfgENV WORKING_DI
来源于:https://github.com/jcsilva/docker-kaldi-android
Dockerfile:
FROM ubuntu:16.04
RUN mkdir -p /opt/android-sdk-linux && mkdir -p ~/.android && touch ~/.android/repositories.cfg
ENV WORKING_DIR /opt
ENV ANDROID_NDK_HOME ${WORKING_DIR}/android-ndk-linux
ENV ANDROID_TOOLCHAIN_PATH /tmp/my-android-toolchain
ENV PATH ${ANDROID_TOOLCHAIN_PATH}/bin:${PATH}
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
clang \
file \
gfortran \
git \
python \
unzip \
wget && \
apt-get clean autoclean && \
apt-get autoremove -y
##### Install Android toolchain
RUN cd ${WORKING_DIR} && \
wget -q --output-document=android-ndk.zip https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip && \
unzip android-ndk.zip && \
rm -f android-ndk.zip && \
mv android-ndk-r14b ${ANDROID_NDK_HOME}
RUN ${ANDROID_NDK_HOME}/build/tools/make_standalone_toolchain.py --arch arm --api 21 --stl=libc++ --install-dir ${ANDROID_TOOLCHAIN_PATH}
##### Download, compile and install OpenBlas
RUN cd ${WORKING_DIR} && \
git clone https://github.com/xianyi/OpenBLAS && \
cd OpenBLAS && \
make TARGET=ARMV7 HOSTCC=gcc CC=arm-linux-androideabi-gcc NO_SHARED=1 NOFORTRAN=1 USE_THREAD=0 NUM_THREADS=32 libs && \
make install NO_SHARED=1 PREFIX=`pwd`/install
##### Download, compile and install CLAPACK
RUN cd ${WORKING_DIR} && \
git clone https://github.com/simonlynen/android_libs && \
cd android_libs/lapack && \
sed -i 's/-mfloat-abi=softfp/-mfloat-abi=hard/g' jni/Application.mk && \
sed -i 's/LOCAL_MODULE:= testlapack/#LOCAL_MODULE:= testlapack/g' jni/Android.mk && \
sed -i 's/LOCAL_SRC_FILES:= testclapack.cpp/#LOCAL_SRC_FILES:= testclapack.cpp/g' jni/Android.mk && \
sed -i 's/LOCAL_STATIC_LIBRARIES := lapack/#LOCAL_STATIC_LIBRARIES := lapack/g' jni/Android.mk && \
sed -i 's/include $(BUILD_SHARED_LIBRARY)/#include $(BUILD_SHARED_LIBRARY)/g' jni/Android.mk && \
${ANDROID_NDK_HOME}/ndk-build && \
cp obj/local/armeabi-v7a/*.a ${WORKING_DIR}/OpenBLAS/install/lib
##### Compile kaldi
# Using "/opt" because of a bug in Docker:
# https://github.com/docker/docker/issues/25925
COPY ./compile-kaldi.sh /opt
RUN chmod +x /opt/compile-kaldi.sh
ENTRYPOINT ["./opt/compile-kaldi.sh"]
compile-kaldi.sh:
#!/bin/bash
cd ${WORKING_DIR}/kaldi/tools
# tools directory --> we'll only compile OpenFST
OPENFST_VERSION=$(grep -oP "OPENFST_VERSION *= *\K(.*)$" ${WORKING_DIR}/kaldi/tools/Makefile)
wget -T 10 -t 1 http://openfst.cs.nyu.edu/twiki/pub/FST/FstDownload/openfst-${OPENFST_VERSION}.tar.gz
tar -zxvf openfst-${OPENFST_VERSION}.tar.gz
cd openfst-${OPENFST_VERSION}/
CXX=clang++ ./configure --prefix=`pwd` --enable-static --enable-shared --enable-far --enable-ngram-fsts --host=arm-linux-androideabi LIBS="-ldl"
make -j 4
make install
# source directory
cd ..
ln -s openfst-${OPENFST_VERSION} openfst
cd ../src
CXX=clang++ ./configure --static --android-incdir=${ANDROID_TOOLCHAIN_PATH}/sysroot/usr/include/ --host=arm-linux-androideabi --openblas-root=${WORKING_DIR}/OpenBLAS/install
make clean -j
make depend -j
make -j4
关于生成SO库的说明:
CXX=clang++ ./configure --shared --android-incdir=/home/houwenbin/android-ndk-r14b/sysroot/usr/include/ --host=arm-linux-androideabi --openblas-root=/home/houwenbin/OpenBLAS/install
以为这样就可以了?非也,还是生成了静态库?原因就在于--android-incdir设置项又把动态选项给摁回去了。。。。
--android-incdir=*)
android=true;
threaded_math=false;
static_math=true;
static_fst=true;
dynamic_kaldi=true;//这里需要手动修改为true
MATHLIB='OPENBLAS';
ANDROIDINC=`read_dirname $1`;
shift;;
这样才会生成动态库,创建lib文件夹,以及连接符号:
if $dynamic_kaldi ; then
KALDILIBDIR=`pwd`/lib
echo "KALDI_FLAVOR := dynamic" >> kaldi.mk
echo "KALDILIBDIR := $KALDILIBDIR" >> kaldi.mk
fi
生成的mk文件和Makefile文件:
# This file was generated using the following command:
# ./configure --shared --android-incdir=/home/houwenbin/android-ndk-r14b/sysroot/usr/include/ --host=arm-linux-androideabi --openblas-root=/home/houwenbin/OpenBLAS/install
CONFIGURE_VERSION := 6
# Toolchain configuration
CXX = arm-linux-androideabi-clang++
AR = arm-linux-androideabi-ar
AS = arm-linux-androideabi-as
RANLIB = arm-linux-androideabi-ranlib
# Base configuration
DOUBLE_PRECISION = 0
OPENFSTINC = /home/houwenbin/kaldi-master/tools/openfst/include
OPENFSTLIBS = /home/houwenbin/kaldi-master/tools/openfst/lib/libfst.a
OPENFSTLDFLAGS =
OPENBLASINC = /home/houwenbin/OpenBLAS/install/include
OPENBLASLIBS = /home/houwenbin/OpenBLAS/install/lib/libopenblas.a /home/houwenbin/OpenBLAS/install/lib/libclapack.a /home/houwenbin/OpenBLAS/install/lib/liblapack.a /home/houwenbin/OpenBLAS/install/lib/libblas.a /home/houwenbin/OpenBLAS/install/lib/libf2c.a
ANDROIDINC = /home/houwenbin/android-ndk-r14b/sysroot/usr/include
# OpenBLAS specific Android configuration
ifndef DOUBLE_PRECISION
$(error DOUBLE_PRECISION not defined.)
endif
ifndef OPENFSTINC
$(error OPENFSTINC not defined.)
endif
ifndef OPENFSTLIBS
$(error OPENFSTLIBS not defined.)
endif
ifndef OPENBLASINC
$(error OPENBLASINC not defined.)
endif
ifndef OPENBLASLIBS
$(error OPENBLASLIBS not defined.)
endif
ifndef ANDROIDINC
$(error ANDROIDINC not defined.)
endif
COMPILER = $(shell $(CXX) -v 2>&1)
ifneq ($(findstring clang,$(COMPILER)),clang)
$(error Android build does not support compiling with $(CXX).
Supported compilers: clang++)
endif
CXXFLAGS = -std=c++11 -I.. -I$(OPENFSTINC) $(EXTRA_CXXFLAGS) \
-Wall -Wno-sign-compare -Wno-unused-local-typedefs \
-Wno-deprecated-declarations -Winit-self -Wno-mismatched-tags \
-DKALDI_DOUBLEPRECISION=$(DOUBLE_PRECISION) \
-DHAVE_CXXABI_H -DHAVE_OPENBLAS -DANDROID_BUILD \
-I$(OPENBLASINC) -I$(ANDROIDINC) -ftree-vectorize -mfloat-abi=hard \
-mfpu=neon -mhard-float -D_NDK_MATH_NO_SOFTFP=1 -pthread \
-g # -O0 -DKALDI_PARANOID
ifeq ($(KALDI_FLAVOR), dynamic)
CXXFLAGS += -fPIC
endif
LDFLAGS = $(EXTRA_LDFLAGS) $(OPENFSTLDFLAGS) -Wl,--no-warn-mismatch -pie
LDLIBS = $(EXTRA_LDLIBS) $(OPENFSTLIBS) $(OPENBLASLIBS) -lm_hard -ldl
# Environment configuration
# This is the top-level Makefile for Kaldi.
# Also see kaldi.mk which supplies options and some rules
# used by the Makefiles in the subdirectories.
SHELL := /bin/bash
SUBDIRS = base matrix util feat tree gmm transform \
fstext hmm lm decoder lat kws cudamatrix nnet \
bin fstbin gmmbin fgmmbin featbin \
nnetbin latbin sgmm2 sgmm2bin nnet2 nnet3 chain nnet3bin nnet2bin kwsbin \
ivector ivectorbin online2 online2bin lmbin chainbin
MEMTESTDIRS = base matrix util feat tree gmm transform \
fstext hmm lm decoder lat nnet kws chain \
bin fstbin gmmbin fgmmbin featbin \
nnetbin latbin sgmm2 nnet2 nnet3 nnet2bin nnet3bin sgmm2bin kwsbin \
ivector ivectorbin online2 online2bin lmbin
CUDAMEMTESTDIR = cudamatrix
SUBDIRS_LIB = $(filter-out %bin, $(SUBDIRS))
KALDI_SONAME ?= libkaldi.so
# Optional subdirectories
EXT_SUBDIRS = online onlinebin # python-kaldi-decoding
EXT_SUBDIRS_LIB = $(filter-out %bin, $(EXT_SUBDIRS))
include kaldi.mk
# Reset the default goal, so that the all target will become default
.DEFAULT_GOAL :=
all:
$(MAKE) checkversion
$(MAKE) kaldi.mk
$(MAKE) mklibdir
$(MAKE) subdirs
-echo Done
subdirs: $(SUBDIRS)
mklibdir:
@echo $(KALDILIBDIR)
test -d $(KALDILIBDIR) || mkdir $(KALDILIBDIR)
#I don't want to call rm -rf
rmlibdir:
ifneq ($(KALDILIBDIR), )
-rm $(KALDILIBDIR)/*{.so,.a,.o}
-rmdir $(KALDILIBDIR)
else
@true
endif
.PHONY: checkversion
checkversion:
ifeq ($(shell ./configure --version),$(CONFIGURE_VERSION))
@echo "The version of configure script matches kaldi.mk version. Good."
else
@echo ""
@echo "The kaldi.mk file was generated using a different version of configure script. Please rerun the configure again"
@test -f ./kaldi.mk && echo "Hint: Previous configure command line: " && head -n 2 ./kaldi.mk | grep configure | sed 's/^# *//g'
@echo ""
@false
endif
biglib: $(SUBDIRS_LIB)
ifeq ($(KALDI_FLAVOR), dynamic)
ifeq ($(shell uname), Darwin)
$(CXX) -dynamiclib -o $(KALDILIBDIR)/libkaldi.dylib -install_name @rpath/libkaldi.dylib -framework Accelerate $(LDFLAGS) $(SUBDIRS_LIB:=/*.dylib)
else
ifeq ($(shell uname), Linux)
#$(warning the following command will probably fail, in that case add -fPIC to your CXXFLAGS and remake all)
$(CXX) -shared -o $(KALDILIBDIR)/$(KALDI_SONAME) -Wl,-soname=$(KALDI_SONAME),--whole-archive $(SUBDIRS_LIB:=/kaldi-*.a) $(LDLIBS) -Wl,--no-whole-archive
else
$(error Dynamic libraries not supported on this platform. Run configure with --static flag. )
endif
endif
endif
biglibext: $(EXT_SUBDIRS_LIB)
ifeq ($(KALDI_FLAVOR), dynamic)
ifeq ($(shell uname), Darwin)
$(CXX) -dynamiclib -o $(KALDILIBDIR)/libkaldi_ext.dylib -install_name @rpath/libkaldi_ext.dylib -framework Accelerate $(LDFLAGS) $(EXT_SUBDIRS_LIB:=/*.dylib)
else
ifeq ($(shell uname), Linux)
#$(warning The following command will probably fail, in that case add -fPIC to your CXXFLAGS and remake all.)
$(CXX) -shared -o $(KALDILIBDIR)/libkaldi_ext.so -Wl,-soname=libkaldi_ext.so,--whole-archive $(EXT_SUBDIRS_LIB:=/kaldi-*.a) -Wl,--no-whole-archive
else
$(error Dynamic libraries not supported on this platform. Run configure with --static flag. )
endif
endif
endif
kaldi.mk:
@[ -f kaldi.mk ] || { echo "kaldi.mk does not exist; you have to run ./configure"; exit 1; }
# Compile optional stuff
ext: ext_depend $(SUBDIRS) $(EXT_SUBDIRS)
-echo Done
check_portaudio:
@[ -d ../tools/portaudio ] || ( cd ../tools; ./install_portaudio.sh )
clean: rmlibdir
-for x in $(SUBDIRS) $(EXT_SUBDIRS); do $(MAKE) -C $$x clean; done
distclean: clean
-for x in $(SUBDIRS) $(EXT_SUBDIRS); do $(MAKE) -C $$x distclean; done
test: $(addsuffix /test, $(SUBDIRS_LIB))
ext_test: $(addsuffix /test, $(EXT_SUBDIRS_LIB))
# Define an implicit rule, expands to e.g.:
# base/test: base
# $(MAKE) -C base test
%/test: % mklibdir
$(MAKE) -C $< test
cudavalgrind:
-for x in $(CUDAMEMTESTDIR); do $(MAKE) -C $$x valgrind || { echo "valgrind on $$x failed"; exit 1; }; done
valgrind:
-for x in $(MEMTESTDIRS); do $(MAKE) -C $$x valgrind || { echo "valgrind on $$x failed"; exit 1; }; done
base/.depend.mk:
$(MAKE) depend
depend: $(addsuffix /depend, $(SUBDIRS))
%/depend:
$(MAKE) -C $(dir $@) depend
ext_depend: check_portaudio
-for x in $(EXT_SUBDIRS); do $(MAKE) -C $$x depend; done
.PHONY: $(SUBDIRS)
$(SUBDIRS) : mklibdir
$(MAKE) -C $@
.PHONY: $(EXT_SUBDIRS)
$(EXT_SUBDIRS) : mklibdir ext_depend
$(MAKE) -C $@
### Dependency list ###
# this is necessary for correct parallel compilation
#1)The tools depend on all the libraries
bin fstbin gmmbin fgmmbin sgmm2bin featbin nnetbin nnet2bin nnet3bin chainbin latbin ivectorbin lmbin kwsbin online2bin: \
base matrix util feat tree gmm transform sgmm2 fstext hmm \
lm decoder lat cudamatrix nnet nnet2 nnet3 ivector chain kws online2
#2)The libraries have inter-dependencies
base: base/.depend.mk
matrix: base
util: base matrix
feat: base matrix util gmm transform tree
tree: base util matrix
gmm: base util matrix tree
transform: base util matrix gmm tree
sgmm2: base util matrix gmm tree transform hmm
fstext: base util matrix tree
hmm: base tree matrix util
lm: base util matrix fstext
decoder: base util matrix gmm hmm tree transform lat
lat: base util hmm tree matrix
cudamatrix: base util matrix
nnet: base util hmm tree matrix cudamatrix
nnet2: base util matrix lat gmm hmm tree transform cudamatrix
nnet3: base util matrix lat gmm hmm tree transform cudamatrix chain fstext
chain: lat hmm tree fstext matrix cudamatrix util base
ivector: base util matrix transform tree gmm
#3)Dependencies for optional parts of Kaldi
onlinebin: base matrix util feat tree gmm transform sgmm2 fstext hmm lm decoder lat cudamatrix nnet nnet2 online
# python-kaldi-decoding: base matrix util feat tree gmm transform sgmm2 fstext hmm decoder lat online
online: decoder gmm transform feat matrix util base lat hmm tree
online2: decoder gmm transform feat matrix util base lat hmm tree ivector cudamatrix nnet2 nnet3 chain
kws: base util hmm tree matrix lat
更多推荐
所有评论(0)