blob: 0094c5e0e79dab2947c0d527068adea47933d2b4 [file] [log] [blame] [edit]
#!/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