#!/bin/bash ############################################################################### # BRLTTY - A background process providing access to the console screen (when in # text mode) for a blind person using a refreshable braille display. # # Copyright (C) 1995-2021 by The BRLTTY Developers. # # BRLTTY comes with ABSOLUTELY NO WARRANTY. # # This is free software, placed under the terms of the # GNU Lesser General Public License, as published by the Free Software # Foundation; either version 2.1 of the License, or (at your option) any # later version. Please see the file LICENSE-LGPL for details. # # Web Page: http://brltty.app/ # # This software is maintained by Dave Mielke . ############################################################################### . "`dirname "${0}"`/../brltty-prologue.sh" . "${programDirectory}/mingw.sh" set -e umask 022 readonly defaultArchiveRoot="http://brltty.app/archive/Windows" readonly defaultTemporaryDirectory="${TMPDIR:-/tmp}/brltty-${programName}" havePath() { local path="${1}" [ -n "${path}" ] || return 1 [ -e "${path}" ] || return 2 return 0 } verifyDirectory() { local path="${1}" [ -e "${path}" ] || semanticError "directory not found: ${path}" [ -d "${path}" ] || semanticError "not a directory: ${path}" [ -w "${path}" ] || semanticError "directory not writable: ${path}" [ -r "${path}" ] || semanticError "directory not readable: ${path}" [ -x "${path}" ] || semanticError "directory not searchable: ${path}" } findCommand() { local variable="${1}" shift 1 for name do local path="$(command -v "${name}")" [ -n "${path}" ] && { setVariable "${variable}" "${path}" return 0 } done return 1 } executeCommand() { logMessage detail "executing command: ${*}" exitStatus=0 "${@}" || exitStatus="${?}" [ "${exitStatus}" -eq 0 ] || logMessage warning "command failed: ${1}: exit status ${exitStatus}" return "${exitStatus}" } downloadFile() { local source="${1}" local target="${2}" logMessage step "downloading file: ${source}" [ -z "${target}" ] && target="${source##*/}" executeCommand wget -nv -O "${target}" "${archiveRoot}/${source}" } unpackArchive() { local path="${1}" case "${path}" in *.zip) set -- unzip -q;; *.tar.gz) set -- tar xfz;; *) semanticError "unsupported archive: ${path}";; esac executeCommand "${@}" "${path}" } applyPatch() { local patch="${1}" local directory="${2}" local file="${3}" local pattern="${4}" local path="${directory}/${file}" if [ -f "${path}" ] then grep -q "${pattern}" "${path}" || { local name="${patch##*/}" logMessage task "applying patch: ${name}" "${dryRun}" || { downloadFile "${patch}" executeCommand patch -N -i "${temporaryDirectory}/${name}" -d "${directory}" "${file}" } } else logMessage warning "file not found: ${path}" fi } installFile() { local file="${1}" local directory="${2}" local source="${file##*/}" local target="${directory}/${source}" [ -e "${target}" ] || { logMessage task "installing file: ${target}" "${dryRun}" || { downloadFile "${file}" [ -d "${directory}" ] || executeCommand mkdir -p "${directory}" executeCommand cp "${source}" "${target}" } } } installLink() { local to="${1}" local directory="${2}" local name="${3}" [ -n "${name}" ] || name="${to##*/}" local from="${directory}/${name}" havePath "${from}" || { logMessage task "installing link: ${from} -> ${to}" [ -e "${to}" ] || semanticError "link target not found: ${to}" "${dryRun}" || executeCommand ln -s "${to}" "${from}" } } installWindowsArchive() { local archive="${1}" local path="${2}" havePath "${path}" || { logMessage task "installing Windows archive: ${archive}" "${dryRun}" || { downloadFile "${archive}" local directory="content-${archive}" executeCommand mkdir "${directory}" executeCommand cd "${directory}" unpackArchive "../${archive}" set -- * if [ "${#}" -eq 1 -a -d "${1}" ] then executeCommand mv "${1}" "${path}" executeCommand cd .. executeCommand rmdir "${directory}" else executeCommand cd .. executeCommand mv "${directory}" "${path}" fi } } } installMingwArchive() { local archive="${1}" local path="${2}" havePath "${mingwDirectory}/${path}" || { logMessage task "installing MinGW archive: ${archive}" "${dryRun}" || { downloadFile "MinGW/${archive}" executeCommand cd "${mingwDirectory}" unpackArchive "${temporaryDirectory}/${archive}" executeCommand cd "${temporaryDirectory}" } } } installMingwPackage() { local package="${1}" local path="${2}" havePath "${path}" || { logMessage task "installing MinGW package: ${package}" "${dryRun}" || executeCommand mingw-get --verbose=0 install "${package}" } } installMicrosoftVisualCTools() { local file for file in lib.exe link.exe mspdb100.dll msvcr100.dll do installFile "MSVC/${file}" "/usr/local/bin" done } installPackageConfigurationFiles() { local package for package in libusb libusb-1.0 do installFile "pkgconfig/${package}.pc" "${librariesDirectory}/pkgconfig" done } installBluetoothHeaders() { local name for name in ws2bth bthdef bthsdpdef do installFile "Bluetooth/${name}.h" "${headersDirectory}" done } installLibUSB0() { local directory="${windowsDirectory}/LibUSB-Win32" installWindowsArchive libusb-win32-bin-1.2.6.0.zip "${directory}" installLink "${directory}/include/lusb0_usb.h" "${headersDirectory}" usb.h installLink "${directory}/lib/gcc/libusb.a" "${librariesDirectory}" installLink "${directory}/bin/x86/libusb0_x86.dll" "${commandsDirectory}" libusb0.dll } installLibUSB1() { local directory="${windowsDirectory}/LibUSB-1.0" installWindowsArchive libusbx-1.0.18-win.tar.gz "${directory}" installLink "${directory}/include/libusbx-1.0" "${headersDirectory}" libusb-1.0 installLink "${directory}/MinGW32/dll/libusb-1.0.dll.a" "${librariesDirectory}" installLink "${directory}/MinGW32/dll/libusb-1.0.dll" "${commandsDirectory}" installWindowsArchive winusb.zip "${windowsDirectory}/WinUSB" } installCython() { local python if findCommand python python py then export PYTHONIOENCODING="utf-8" local directory="${python%/*}" findCommand cython cython || { logMessage task "installing Cython" "${dryRun}" || executeCommand pip -q install cython } installFile Cython/vcruntime140.dll "${directory}/libs" installFile Cython/distutils.cfg "${directory}/lib/distutils" applyPatch "Cython/PythonCygwinCCompiler.patch" "${directory}/lib/distutils" "cygwinccompiler.py" "vcruntime140" else logMessage warning "Python not found" fi } addProgramOption a string.URL archiveRoot "the URL for BRLTTY's Windows archive" "${defaultArchiveRoot}" addProgramOption d flag dryRun "dry run - don't actually install anything" addProgramOption k flag keepFiles "keep (do not remove) the temporary directory" addProgramOption p string.directory pythonDirectory "the directory where Python has been installed" addProgramOption t string.directory temporaryDirectory "the temporary directory to use" "${defaultTemporaryDirectory}" parseProgramArguments "${@}" [ -n "${archiveRoot}" ] || archiveRoot="${defaultArchiveRoot}" [ -n "${pythonDirectory}" ] && { [ -d "${pythonDirectory}" ] || semanticError "Python directory not found: ${pythonDirectory}" PATH="${pythonDirectory}:${pythonDirectory}/scripts:${PATH}" } readonly windowsDirectory="/c" verifyDirectory "${windowsDirectory}" readonly mingwDirectory="/mingw" verifyDirectory "${mingwDirectory}" readonly commandsDirectory="${mingwDirectory}/bin" verifyDirectory "${commandsDirectory}" readonly librariesDirectory="${mingwDirectory}/lib" verifyDirectory "${librariesDirectory}" readonly headersDirectory="${mingwDirectory}/include" verifyDirectory "${headersDirectory}" if [ -z "${temporaryDirectory}" ] then temporaryDirectory="${defaultTemporaryDirectory}" rm -f -r "${temporaryDirectory}" elif [ -e "${temporaryDirectory}" ] then semanticError "directory already exists: ${temporaryDirectory}" fi mkdir -p "${temporaryDirectory}" cd "${temporaryDirectory}" temporaryDirectory="$(pwd -W)" installMingwPackage msys-bison /bin/bison installMingwPackage msys-dos2unix /bin/dos2unix installMingwPackage msys-groff /bin/groff installMingwPackage msys-m4 /bin/m4 installMingwPackage msys-tar /bin/tar installMingwPackage msys-unzip /bin/unzip installMingwPackage msys-wget /bin/wget installMingwPackage msys-zip /bin/zip installMingwPackage mingw32-libpdcurses /mingw/include/curses.h installMingwPackage mingw32-pthreads-w32 /mingw/include/pthread.h installMingwPackage mingw32-tcl /mingw/bin/tclsh installMicrosoftVisualCTools installPackageConfigurationFiles installBluetoothHeaders installMingwArchive pkg-config_0.28-1_win32.zip "bin/pkg-config.exe" installMingwArchive glib_2.34.3-1_win32.zip "bin/libgobject-2.0-0.dll" installWindowsArchive AutoHotkey104805.tar.gz "${ahkLocation}" installWindowsArchive nsis-3.0b0.tar.gz "${nsisLocation}" installWindowsArchive icu4c-53_1-Win32-msvc10.zip "${icuLocation}" installLibUSB0 installLibUSB1 installCython "${keepFiles}" || { logMessage task "cleaning up" cd "${initialDirectory}" rm -f -r "${temporaryDirectory}" } logMessage task "done" exit 0