| #!/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-2023 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 <dave@mielke.cc>. | |
| ############################################################################### | |
| set -e | |
| umask 022 | |
| export MAKEFLAGS= | |
| copyProperties() { | |
| local from="${1}" | |
| local to="${2}" | |
| shift 2 | |
| for suffix in ${*} | |
| do | |
| setVariable "${to}${suffix}" "$(getVariable "${from}${suffix}")" | |
| done | |
| } | |
| installFile() { | |
| local source="${1}" | |
| local target="${2}" | |
| [ "${target%/}" = "${target}" ] || target="${target}${source##*/}" | |
| if [ -e "${source}" ] | |
| then | |
| local path="${installRoot}/${target}" | |
| mkdir -p "${path%/*}" | |
| cp "${source}" "${path}" | |
| else | |
| logWarning "file not installed: ${target}" | |
| fi | |
| } | |
| installFiles() { | |
| local target="${1}" | |
| shift 1 | |
| local source | |
| for source | |
| do | |
| installFile "${source}" "${target}" | |
| done | |
| } | |
| installPackages() { | |
| while [ "${#}" -gt 0 ] | |
| do | |
| local package="${1}" | |
| shift 1 | |
| local name="$(getVariable "${package}Name")" | |
| logMessage task "installing package files: ${name}" | |
| "installPackage_${package}" | |
| done | |
| } | |
| installPackage_libusb0() { | |
| if [ -n "${libusb0Root}" ] | |
| then | |
| cd "${libusb0Root}/bin" | |
| installFile "x86/libusb0.sys" "bin/libusb0.sys" | |
| installFile "x86/libusb0_x86.dll" "bin/libusb0.dll" | |
| installFile "amd64/libusb0.sys" "bin/libusb0_x64.sys" | |
| installFile "amd64/libusb0.dll" "bin/libusb0_x64.dll" | |
| else | |
| logWarning "${libusb0Name} not installable" | |
| fi | |
| } | |
| installPackage_libusb1() { | |
| if [ -n "${libusb1Root}" ] | |
| then | |
| cd "${libusb1Root}" | |
| installFile "MinGW32/dll/libusb-1.0.dll" "bin/" | |
| else | |
| logWarning "${libusb1Name} not installable" | |
| fi | |
| } | |
| installPackage_winusb() { | |
| if [ -n "${winusbRoot}" ] | |
| then | |
| cd "${winusbRoot}" | |
| installFile "x86/winusbcoinstaller2.dll" "bin/x86/" | |
| installFile "amd64/winusbcoinstaller2.dll" "bin/amd64/" | |
| installFile "x86/WdfCoInstaller01009.dll" "bin/x86/" | |
| installFile "amd64/WdfCoInstaller01009.dll" "bin/amd64/" | |
| else | |
| logWarning "${winusbName} not installable" | |
| fi | |
| } | |
| . "`dirname "${0}"`/../brltty-prologue.sh" | |
| . "${programDirectory}/mingw.sh" | |
| defaultUsbPackage="libusb" | |
| defaultTemporaryDirectory="${TMPDIR:-/tmp}/brltty-${programName}" | |
| addProgramOption u string.package usbPackage "which USB package to use" "${defaultUsbPackage}" | |
| addProgramOption s flag invokeShell "invoke interactive shell to inspect/modify result" | |
| addProgramOption t string.directory temporaryDirectory "the temporary directory to use for the build" "${defaultTemporaryDirectory}" | |
| addProgramOption k flag keepBuild "keep (do not remove) the temporary directory" | |
| addWindowsPackageOption M msvc | |
| addWindowsPackageOption A ahk | |
| addWindowsPackageOption N nsis | |
| addWindowsPackageOption U libusb0 | |
| addWindowsPackageOption X libusb1 | |
| addWindowsPackageOption W winusb | |
| addWindowsPackageOption P python | |
| addWindowsPackageOption I icu | |
| addProgramOption C string.directory cygwinRoot "the root directory of a Cygwin installation" | |
| addProgramParameter source sourceRoot "the top-level directory of the source tree" | |
| optionalProgramParameters | |
| addProgramParameter revision buildRevision "the revision of the build" | |
| parseProgramArguments "${@}" | |
| sourceRoot="$(cd "${sourceRoot}" && pwd -W)" | |
| [ -f "${sourceRoot}/configure" ] || semanticError "not a source tree: ${sourceRoot}" | |
| revisionIdentifier="$("${sourceRoot}/getrevid" "${sourceRoot}")" | |
| logMessage task "revision identifier: ${revisionIdentifier}" | |
| [ -n "${buildRevision}" ] || { | |
| buildRevision="${revisionIdentifier%-g*}-" | |
| buildRevision="${buildRevision#*-}" | |
| buildRevision="${buildRevision#*-}" | |
| if [ -n "${buildRevision}" ] | |
| then | |
| buildRevision="${buildRevision%-}" | |
| else | |
| buildRevision="0" | |
| fi | |
| } | |
| [ -n "${cygwinRoot}" ] || { | |
| directory=/cygwin | |
| [ -e "${directory}" ] && cygwinRoot="${directory}" | |
| } | |
| [ -n "${cygwinRoot}" ] && { | |
| if [ -f "${cygwinRoot}/cygwin.ico" ] | |
| then | |
| export PATH="${PATH}:${cygwinRoot}/bin" | |
| export nodosfilewarning=1 | |
| else | |
| logWarning "not a Cygwin root directory: ${cygwinRoot}" | |
| fi | |
| } | |
| [ -n "${usbPackage}" ] || usbPackage="${defaultUsbPackage}" | |
| case "${usbPackage}" | |
| in | |
| winusb) usbWindowsPackages=();; | |
| libusb) usbWindowsPackages=("libusb0");; | |
| libusb-1.0) usbWindowsPackages=("libusb1" "winusb");; | |
| *) syntaxError "unrecognized USB package: ${usbPackage}" | |
| esac | |
| winusbFilter="" | |
| libusb0Filter="\ | |
| select "USB:", and install the ${libusb0Name} filter by doing one of the | |
| following: | |
| + run Install ${libusb0Name} Filter from the Start Menu | |
| + answer yes to the setup prompt for installing the ${libusb0Name} filter | |
| + install it by hand, from ${libusb0Download}" | |
| libusb1Filter="\ | |
| you will need to use ${libusb0Name} instead because | |
| ${libusb1Name} does not support this requirement." | |
| set -- "${usbWindowsPackages[@]}" | |
| copyProperties "${1}" usb Name Location Download Version Pattern Filter | |
| [ -z "${msvcRoot}" ] || { | |
| if verifyWindowsPackage msvc | |
| then | |
| export PATH="${msvcRoot}:${PATH}" | |
| fi | |
| } | |
| [ -n "${pythonRoot}" ] || { | |
| pythonLocationFile="${programDirectory}/python-location" | |
| if [ -f "${pythonLocationFile}" ] | |
| then | |
| read pythonRoot <"${pythonLocationFile}" | |
| fi | |
| } | |
| [ -z "${pythonRoot}" ] || { | |
| if verifyWindowsPackage python | |
| then | |
| export PATH="${pythonRoot}:${pythonRoot}/Scripts:${PATH}" | |
| export PYTHON="${pythonRoot}/python" | |
| fi | |
| } | |
| verifyWindowsPackages ahk nsis icu "${usbWindowsPackages[@]}" || : | |
| verifyWindowsCommands lib python cython || : | |
| verifyMingwPackages pthreads curses || : | |
| verifyMingwCommands zip unix2dos linuxdoc doxygen groff || : | |
| 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)" | |
| logMessage task "copying source tree" | |
| newSourceRoot="${temporaryDirectory}/source" | |
| cp -a "${sourceRoot}" "${newSourceRoot}" | |
| cd "${newSourceRoot}" | |
| sourceRoot="${newSourceRoot}" | |
| logMessage task "applying patches" | |
| for patch in affinity | |
| do | |
| patch -p0 <"Windows/${patch}.patch" | |
| done | |
| infFile="${usbPackage}.inf" | |
| infPath="Windows/${infFile}" | |
| Tools/updusbdevs -q "c:Programs/usb_devices.c" "inf:${infPath}" | |
| Tools/updcsvs -q | |
| buildRoot="${temporaryDirectory}/build" | |
| mkdir -p "${buildRoot}" | |
| cd "${buildRoot}" | |
| logMessage task "configuring build" | |
| "../source/cfg-windows" \ | |
| --prefix=/ \ | |
| --enable-relocatable-install \ | |
| --with-usb-package="${usbPackage}" \ | |
| --quiet | |
| . ./brltty-config.sh | |
| buildVersion="${BRLTTY_VERSION}-${buildRevision}" | |
| buildName="${BRLTTY_TARNAME}-win-${buildVersion}-${usbPackage}" | |
| logMessage task "building programs" | |
| make -s | |
| make -s -C Drivers/BrlAPI/WindowEyes we-dynamic-library-windows | |
| logMessage task "building documents" | |
| make -s -C Documents | |
| logMessage task "installing files" | |
| installRoot="${temporaryDirectory}/install/${buildName}" | |
| make -s install install-messages \ | |
| JAVA_JAR_DIR=/lib JAVA_JNI_DIR=/lib \ | |
| PYTHON_PREFIX="Python" \ | |
| INSTALL_ROOT="${installRoot}" | |
| logMessage task "updating files" | |
| documentDirectory="doc" | |
| readmeHeader="\ | |
| This build of ${BRLTTY_NAME} ${BRLTTY_VERSION} includes Windows-specific patches. | |
| You should probably read doc/BRLTTY.txt and doc/Windows.txt for information | |
| about BRLTTY. | |
| Here are some notes on how to get started: | |
| - BRLTTY only gives access to text consoles. For the rest of the Windows | |
| environment, you need to also install and run NVDA. | |
| - Either use the BRLTTY configurator (brlttycnf.exe) or manually uncomment the | |
| appropriate lines in etc/brltty.conf. | |
| - For Python support (e.g. for NVDA), run Brlapi-${BRLAPI_RELEASE}.win32.exe | |
| (which will install the .pyd and .egg-info files). | |
| - For sighted users, use the xw braille driver to get a virtual braille box. | |
| " | |
| readmeFooter="\ | |
| If you are having problems, please run debug-brltty.bat and send us the | |
| debug.log and brltty.conf files. | |
| Documentation can be found in the doc/ subdirectory. | |
| ============================== | |
| Technical notes on this build: | |
| - Source Revision: ${revisionIdentifier} | |
| - BRLTTY Version: ${BRLTTY_VERSION} | |
| - BrlAPI Version: ${BRLAPI_RELEASE} | |
| - Some MinGW-specific path and file name changes have been made. | |
| - To make life easier for Windows users, the BrlAPI server was modified to: | |
| * not use authentication by default (BRLAPI_DEFAUTH set to none) | |
| * only use local sockets (:0+127.0.0.1:0 changed to :0) | |
| - *${usbPattern}* files come from ${usbName} ${usbVersion}, which can be found at: | |
| ${usbDownload} | |
| - Python bindings are provided by: Brlapi-${BRLAPI_RELEASE}.win32.exe | |
| - C bindings are provided in: include/, and lib/ | |
| A .lib file is provided for linking in (for example) Visual C. Then you can | |
| just ship bin/brlapi${BRLAPI_RELEASE%.*}.dll alongside your .exe application. | |
| " | |
| cd "${buildRoot}" | |
| installFile "Documents/brltty.conf" "etc/" | |
| installFile "Drivers/BrlAPI/WindowEyes/webrloem109.dll" "WindowEyes/" | |
| installFiles "Debug/" config.h config.mk config.log | |
| installFiles "Debug/" Programs/*.exe Programs/*.dll | |
| set -- Bindings/Python/dist/Brlapi-${BRLAPI_RELEASE}.*.exe | |
| if [ "${#}" -gt 0 ] | |
| then | |
| for file | |
| do | |
| installFile "${file}" "Python/" | |
| done | |
| else | |
| logWarning "Python bindings installer not found" | |
| fi | |
| cd "${sourceRoot}" | |
| installFile "LICENSE-LGPL" "LICENSE-LGPL.txt" | |
| installFile "README" "${documentDirectory}/BRLTTY.txt" | |
| installFile "Drivers/Braille/XWindow/UBraille.ttf" "Fonts/" | |
| installFile "Drivers/BrlAPI/WindowEyes/README" "${documentDirectory}/WindowEyes.txt" | |
| installFile "${infPath}" "bin/brltty-${infFile}" | |
| installFiles "etc/" Documents/*.csv | |
| for document in ChangeLog HISTORY TODO | |
| do | |
| installFile "Documents/${document}" "${documentDirectory}/${document}.txt" | |
| done | |
| for document in Windows BrailleDots TextTables ContractionTables AttributesTables KeyTables | |
| do | |
| installFile "Documents/README.${document}" "${documentDirectory}/${document}.txt" | |
| done | |
| for root in "${sourceRoot}" "${buildRoot}" | |
| do | |
| cd "${root}/Documents" | |
| for manual in Manual-BRLTTY Manual-BrlAPI BrlAPIref | |
| do | |
| [ -d "${manual}" ] || continue | |
| for file in $(find "${manual}" -type f -print) | |
| do | |
| name="${file##*/}" | |
| extension="${name##*.}" | |
| case "${extension}" | |
| in | |
| txt | html | htm | doc | pdf) | |
| installFile "${file}" "${documentDirectory}/${file}" | |
| ;; | |
| *);; | |
| esac | |
| done | |
| done | |
| done | |
| cd "${sourceRoot}/Drivers" | |
| for document in $(find Braille Speech -type f -name "README*" -print) | |
| do | |
| installFile "${document}" "${documentDirectory}/Drivers/${document}.txt" | |
| done | |
| cd "${programDirectory}" | |
| installFiles "bin/" *.dll *.cat | |
| installFiles "/" *.bat | |
| logMessage task "USB package: ${usbPackage}" | |
| installPackages "${usbWindowsPackages[@]}" | |
| cd /mingw/bin | |
| for file in libgcc_s_dw2-1.dll libiconv-2.dll libpdcurses*.dll libintl-8.dll | |
| do | |
| installFile "${file}" "bin/" | |
| done | |
| cd "${installRoot}" | |
| rm -f "bin/brltty-config" | |
| rm -f "etc/brlapi.key" | |
| echo "${revisionIdentifier}" >"REVISION.txt" | |
| for source in $(find "share/man" -type f -name "*.[1-9]" -print) | |
| do | |
| [ -z "${groffPath}" ] || { | |
| target="${source%.*}.txt" | |
| "${groffPath}" -T ascii -mandoc 2>/dev/null <"${source}" | | |
| sed -e 's/'$'\033''\[[0-9]*m//g' >"${target}" | |
| [ -s "${target}" ] || rm -f "${target}" | |
| } | |
| rm -f "${source}" | |
| done | |
| cat >"README.txt" <<END-OF-README | |
| ${readmeHeader} | |
| - To register BRLTTY as a service so that it will get started automatically at | |
| boot, run enable-brlapi.bat. To unregister it, run disable-brlapi.bat. | |
| - If your braille device uses a USB connection: | |
| * If you either cannot, or would prefer not to, install its | |
| manufacturer's driver, then you can select "USB:", and install | |
| the ${usbName} driver by doing one of the following: | |
| + right-clicking on bin/brltty-${usbPackage}.inf and selecting install | |
| + answering yes to the setup prompt for installing the ${usbName} driver | |
| * If you have installed its manufacturer's driver, and if that driver defines | |
| a virtual COM port, then select that virtual COM port. | |
| * If you need to install its manufacturer's driver, but | |
| that driver does not define a virtual COM port, then | |
| ${usbFilter} | |
| - If your braille device uses a serial connection, or if it is connected via a | |
| serial to USB converter, then select the correct COM port. Make sure to | |
| select the correct braille driver as well, because serial autodetection may | |
| brick some devices. | |
| - If your braille device uses a Bluetooth connection, you can either use the | |
| Windows Bluetooth facilities to create a virtual COM port which you can then | |
| select, or manually configure the braille-device line in brltty.conf. | |
| ${readmeFooter} | |
| END-OF-README | |
| if [ -n "${libPath}" ] | |
| then | |
| cd "${installRoot}/lib" | |
| "${libPath}" //nologo /def:brlapi.def /name:brlapi-${BRLAPI_VERSION}.dll /out:brlapi.lib /machine:x86 | |
| else | |
| logWarning "import library not creatable" | |
| fi | |
| cd "${installRoot}/.." | |
| cat >"README.txt" <<END-OF-README | |
| ${readmeHeader} | |
| ${readmeFooter} | |
| END-OF-README | |
| # for the installer but before text file conversion | |
| nsisScript="${usbPackage}.nsi" | |
| nsisStrings="nsistrings.txt" | |
| for file in "${nsisScript}" "brltty.nsi" "${nsisStrings}" | |
| do | |
| path="${programDirectory}/${file}" | |
| if [ -f "${path}" ] | |
| then | |
| cp "${path}" . | |
| else | |
| logWarning "installer source file not found: ${file}" | |
| nsisRoot="" | |
| fi | |
| done | |
| if [ -n "${ahkRoot}" ] | |
| then | |
| logMessage task "creating configurator" | |
| cd "${installRoot}" | |
| cp "${programDirectory}/brlttycnf.ahk" . | |
| "${ahkRoot}/Compiler/Ahk2Exe.exe" //in brlttycnf.ahk //out brlttycnf.exe | |
| rm brlttycnf.ahk | |
| else | |
| logWarning "configurator not creatable" | |
| fi | |
| if [ -n "${unix2dosPath}" ] | |
| then | |
| logMessage task "converting text files" | |
| cd "${installRoot}/.." | |
| find . -print | | |
| while read path | |
| do | |
| handle="${path#.}" | |
| [ -n "${handle}" ] || continue | |
| handle="${handle#/}" | |
| name="${path##*/}" | |
| extension="${name##*.}" | |
| if [ -f "${path}" ] | |
| then | |
| if [ "${extension}" != "${name}" ] | |
| then | |
| case "${extension}" | |
| in | |
| bash | bat | cat | conf | csv | h | htm | html | inf | log | lua | mk | nsi | pc | policy | sh | tcl | txt | xml | [tcak]t[bi]) | |
| "${unix2dosPath}" -q -o "${path}" | |
| ;; | |
| a | def | dll | doc | egg-info | exe | exp | lib | mo | pdf | pyd | sys | ttf);; | |
| *) logWarning "unexpected file extension: ${handle}";; | |
| esac | |
| fi | |
| elif [ ! -d "${path}" ] | |
| then | |
| logWarning "unsupported special file: ${handle}" | |
| fi | |
| done | |
| else | |
| logWarning "text files not convertable" | |
| fi | |
| if "${invokeShell}" | |
| then | |
| logMessage task "invoking shell" | |
| cd "${installRoot}" | |
| "${SHELL:-/bin/sh}" || : | |
| fi | |
| if [ -n "${zipPath}" ] | |
| then | |
| logMessage task "creating archive" | |
| archiveFile="${initialDirectory}/${buildName}.zip" | |
| rm -f "${archiveFile}" | |
| cd "${installRoot}/.." | |
| "${zipPath}" -q -A -r "${archiveFile}" "${buildName}" | |
| else | |
| logWarning "archive not creatable" | |
| fi | |
| if [ -n "${nsisRoot}" ] | |
| then | |
| logMessage task "creating installer" | |
| cd "${installRoot}/.." | |
| mv "${nsisStrings}" "${buildName}" | |
| installerFile="${buildName}.exe" | |
| "${nsisRoot}/makensis" -V2 \ | |
| -DVERSION="${buildVersion}" \ | |
| -DDISTDIR="${buildName}" \ | |
| -DOUTFILE="${installerFile}" \ | |
| "${nsisScript}" | |
| rm -f "${initialDirectory}/${installerFile}" | |
| cp "${installerFile}" "${initialDirectory}/${installerFile}" | |
| else | |
| logWarning "installer not creatable" | |
| fi | |
| "${keepBuild}" || { | |
| logMessage task "cleaning up" | |
| cd "${initialDirectory}" | |
| rm -f -r "${temporaryDirectory}" | |
| } | |
| logMessage task "done" | |
| exit 0 |