| #!/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 |