1#!/bin/zsh
2
3set -e
4# set -x
5
6setopt nullglob
7zmodload zsh/pcre
8
9script_dir=${${0:a}:h}
10src_dir=${script_dir}/../..
11src_dir=${src_dir:a}
12no_strip=${no_strip:-0}
13is_shared=${is_shared:-0}
14
15if [[ -f ${script_dir}/conf.sh ]] source ${script_dir}/conf.sh
16
17function fail {
18  print -- $@
19  exit 1
20}
21
22function setup_variables {
23  host=$(awk '/^host *=/ { print $3 }' ${src_dir}/build-config)
24  mxe_usr_dir=${mxe_dir}/usr/${host}
25  if [[ $host =~ shared ]] is_shared=1
26}
27
28function strip_files {
29  if [[ $no_strip == 1 ]] return
30
31  print -n -- "Stripping files…"
32
33  cd ${tgt_dir}
34  ${host}-strip **/*.exe **/*.dll
35
36  print -- " done"
37}
38
39function sign_exes {
40  if [[ -z $exe_signer ]] return
41
42  print -n -- "Signing executables…"
43
44  cd ${tgt_dir}
45  for exe (*.exe) {
46    ${exe_signer} ${exe} ${exe}.signed
47    mv ${exe}.signed ${exe}
48  }
49
50  print -- " done"
51}
52
53function create_directories {
54  print -n -- "Creating directories…"
55
56  cd ${tgt_dir}
57  rm -rf *
58  mkdir -p examples data/sounds doc/licenses locale/libqt
59
60  print -- " done"
61}
62
63function copy_dlls {
64  if [[ $is_shared == 0 ]]; then
65    return
66  fi
67
68  print -n -- "Copying DLLs…"
69
70  local dll_src_dir=$(which ${host}-g++)
71  dll_src_dir=${dll_src_dir:a:h}/../${host}/bin
72
73  cd ${tgt_dir}
74
75  # copy MKVToolNix' own DLLs
76  cp ${src_dir}/src/common/libmtxcommon.dll .
77
78  # copy Qt plugins
79  mkdir plugins
80  cp -R ${mxe_dir}/usr/${host}/qt5/plugins/{audio,iconengines,imageformats,mediaservice,platforms,styles} plugins/
81  rm -f plugins/platforms/{qminimal,qoffscreen}.dll
82
83  # copy basic DLLs
84  cp ${dll_src_dir}/lib{crypto-,gnurx-,harfbuzz-0,pcre-1,pcre2-16,png16-,ssl-}*.dll .
85
86  # copy dependencies
87  ${script_dir}/copy_dll_dependencies.rb *.exe **/*.dll
88
89  # fix permissions
90  chmod a+x **/*.dll
91
92  # create qt.conf
93  cat > qt.conf <<EOF
94[Paths]
95Plugins=./plugins
96EOF
97
98  print -- " done"
99}
100
101function copy_drmingw_dlls {
102  local drmingw_dir
103
104  cd ${src_dir}
105
106  if [[ -f build-config.local ]]; then
107    drmingw_dir="$(awk -F= '/^DRMINGW_PATH/ { gsub("^ +| +$", "", $2); print $2 }' < build-config.local)"
108  fi
109
110  if [[ -z ${drmingw_dir} ]]; then
111    drmingw_dir="$(awk -F= '/^DRMINGW_PATH/ { gsub("^ +| +$", "", $2); print $2 }' < build-config)"
112  fi
113
114  if [[ -z ${drmingw_dir} ]] return
115
116  print -n -- "Copying Dr. MinGW DLLs…"
117
118  cp ${drmingw_dir}/bin/*.dll ${tgt_dir}/
119
120  echo " done"
121}
122
123function copy_files {
124  local qt5trdir lang baseqm mo qm
125  print -n -- "Copying files…"
126
127  cd ${src_dir}
128
129  cp -R packaging/windows/installer examples ${tgt_dir}/
130  rm -rf ${tgt_dir}/examples/stylesheets
131  cp src/*.exe src/mkvtoolnix-gui/*.exe packaging/windows/installer/*.url ${tgt_dir}/
132  cp share/icons/windows/mkvtoolnix-gui.ico ${tgt_dir}/installer/
133
134  mkdir ${tgt_dir}/tools
135  cp src/tools/{bluray_dump,ebml_validator,hevcc_dump,xvc_dump}.exe ${tgt_dir}/tools/
136
137  cp share/sounds/* ${tgt_dir}/data/sounds/
138  touch ${tgt_dir}/data/portable-app
139
140  cp README.md ${tgt_dir}/doc/README.txt
141  cp COPYING ${tgt_dir}/doc/COPYING.txt
142  cp NEWS.md ${tgt_dir}/doc/NEWS.txt
143  cp doc/command_line_references.html ${tgt_dir}/doc/
144  cp doc/licenses/*.txt ${tgt_dir}/doc/licenses/
145
146  for mo in po/*.mo ; do
147    language=${${mo:t}:r}
148    mkdir -p ${tgt_dir}/locale/${language}/LC_MESSAGES
149    cp ${mo} ${tgt_dir}/locale/${language}/LC_MESSAGES/mkvtoolnix.mo
150  done
151
152  local qt5trdir=${mxe_usr_dir}/qt5/translations
153  local qm=''
154  for qm (${qt5trdir}/qt_*.qm) {
155    if [[ ${qm} == *qt_help* ]] continue
156
157    lang=${${${qm:t}:r}#qt_}
158
159    baseqm=${qt5trdir}/qtbase_${lang}.qm
160    if [[ -f $baseqm ]] qm=$baseqm
161    cp ${qm} ${tgt_dir}/locale/libqt/qt_${lang}.qm
162  }
163
164  local ts
165  for ts (po/qt/*.ts) {
166    lang=${${${ts:t}:r}#qt_}
167
168    lrelease -qm ${tgt_dir}/locale/libqt/qt_${lang}.qm ${ts} > /dev/null
169  }
170
171  typeset -a translations
172  translations=($(awk '/^MANPAGES_TRANSLATIONS/ { gsub(".*= *", "", $0); gsub(" *$", "", $0); print $0 }' build-config))
173
174  typeset -a xml_files expected_files
175  typeset src_file dst_file commands saxon_process
176
177  cd ${src_dir}/doc/man
178  xml_files=(*.xml)
179
180  commands=$(mktemp)
181
182  for lang (. $translations) {
183    typeset lang_dir=${src_dir}/doc/man/${lang}
184    cd ${lang_dir}
185
186    if [[ $lang == . ]] lang=en
187
188    man_dest=${tgt_dir}/doc/${lang}
189    mkdir -p ${man_dest}
190    cp ${src_dir}/doc/stylesheets/mkvtoolnix-doc.css ${man_dest}/
191
192    for src_file (${xml_files}) {
193      dst_file=${man_dest}/$(basename ${src_file} .xml).html
194      expected_files+=(${dst_file})
195
196      echo ${script_dir}/saxon_process.sh ${lang_dir}/${src_file} ${dst_file} ${src_dir}/doc/stylesheets/docbook-to-html.xsl >> ${commands}
197    }
198  }
199
200  xargs -P $(nproc) -d '\n' '-I{}' zsh -c '{}' < ${commands}
201
202  rm -f ${commands}
203
204  for dst_file (${expected_files}) {
205    if [[ ! -f ${dst_file} ]] exit 1
206  }
207
208  echo " done"
209}
210
211while [[ ! -z $1 ]]; do
212  case $1 in
213    -t|--target-dir) tgt_dir=$2;    shift; ;;
214    -m|--mxe-dir)    mxe_dir=$2;    shift; ;;
215    -s|--saxon-dir)  saxon_dir=$2;  shift; ;;
216    --exe-signer)    exe_signer=$2; shift; ;;
217    *)               fail "Unknown option $1" ;;
218  esac
219
220  shift
221done
222
223if [[   -z ${tgt_dir}   ]] fail "The target directory has not been set"
224if [[ ! -d ${tgt_dir}   ]] fail "The target directory does not exist"
225if [[   -z ${mxe_dir}   ]] fail "The MXE base directory has not been set"
226if [[ ! -d ${mxe_dir}   ]] fail "The MXE base directory does not exist"
227if [[   -z ${saxon_dir} ]] fail "The Saxon-HE base directory has not been set"
228if [[ ! -d ${saxon_dir} ]] fail "The Saxon-HE base directory does not exist"
229if [[ ( -n ${exe_signer} ) && ( ! -x ${exe_signer} ) ]] fail "The EXE signer cannot be run"
230
231setup_variables
232create_directories
233copy_files
234copy_dlls
235copy_drmingw_dlls
236strip_files
237sign_exes
238
239exit 0
240