Emacsbridge
Emacsbridge Documentation

Working with the core

requirements

The following table contains the Qt versions suitable for compiling emacsbridge:

OS Version State
Android 5.15.1 recommended
Android 5.15.0 minimum
PC 5.14.x minimum
PC 5.15.x recommended
PC 5.13.0 compiles, works mostly, but not recommended

For building on PC compiling Qt is straightforward, and your distribution might already have a correct version. The following packages should pull in all the other required dependencies for building:

  • Qt5Quick
  • Qt5QuickControls2
  • Qt5WebSockets
  • Qt5RemoteObjects
  • Qt5Network
  • Qt5Sensors
  • libQt5Core-private-headers-devel

The package names are for OpenSuSE, other distributions should have similar naming.

To build for Android an Android development environment needs to be set up. It should work with Android Studio or similar, below is a summary on how to setup a non-GUI build environment.

Preparing the sources

Emacsbridge requires qthttpserver, which is included as a submodule. qthttpserver also has submodules. The following snippet clones the repository and initializes all submodules:

$ git clone https://github.com/aardsoft/emacsbridge.git
$ cd emacsbridge
$ git submodule update --init --recursive qthttpserver

Now the code can be configured for qmake - for Android the qmake from inside the Android Qt tree needs to be called.

Build helper

The source repository contains a build helper (build.sh). Outside of simple Linux builds using that might be easiest.

Variables controlling the build include:

  • ANDROID_ABIS: ABIs to build, default arm64-v8a x86_64 armeabi-v7a
  • ANDROID_SDK_VERSION: Android SDK version to use, default android-29. When targetting Play store the version from the script generally is the one which has to be used.
  • QT_VERSION: The Qt version used for trying to find directories, default 5.15.1
  • QT_ANDROID_BIN: The bin directory inside of the Qt Android installation, defaulting to $HOME/qt/qt${QT_VERSION}-${ANDROID_SDK_VERSION}/bin
  • QT_WINDOWS_BIN: The bin directory inside of the Windows Qt installation, defaulting to $HOME/qt/qt${QT_VERSION}-mingw64/bin
  • WIN32_OBJDUMP: The name of the objdump binary for Windows, default x86_64-w64-mingw32-objdump
  • WIN32_SYSROOT: Path to the mingw32 sysroot, default /usr/x86_64-w64-mingw32/sys-root/mingw/bin
  • WIN32_PLUGINS: List of win32 plugins to use, default platforms
  • BUILD_DIR: Name of the build directory, default build
  • QMAKE_CXX: The C++ compiler to use for PC, default clang++
  • QMAKE_LINK: The linker to use for PC, default clang++

Debugging

To see what goes over the local socket, start socat and adjust socket address:

while true; do echo "Restart."; socat -v GOPEN:/tmp/Emacs1000/server UNIX-LISTEN:/tmp/es; done

Building for Android and Windows requires a proper cross-compiled toolchain,

Architecture

The application is separated into a client and a server part, communicating via Qt Remote Objects

Connection setup

Emacsbridge starts up with some open settings endpoints to make initial configuration easier. To set the connection up,

  • Emacs provides information about its server connection
  • Emacsbridge uses that to connect to Emacs. If that connection was successful it will disable the open endpoints, and make the RPC interface available.

URLs

/icons

Icons bundled with the application. Served without modification, directory index is enabled. No authentication required.

/lisp

Lisp files bundled with the application. Served without modification, directory index is enabled. No authentication required.

/local

Files served from a local directory, as set in the serversettings.ini in the http/localDir key. Per default this is not configured.

/rpc

Expects JSON data in a POST request, with a valid auth token. The method for which JSON data is sent must be specified in the method header. Only available after initial setup has been completed. The following methods are available:

addComponent

name required default
in-drawer no false
qmlData yes
qmlFile yes
title no qmlFile

setData

notification

name required default
title no "Missing notification title"
text no "Missing notification text"

intent

name required default
action no
data no
package no
class no
extra no
startType no "activity"
(emacsbridge-post-json "intent" (json-encode `((:package . "com.termux")
(:startType . "service")
(:class . "com.termux.app.RunCommandService")
(:extra . (((:type . "string")
(:key . "com.termux.RUN_COMMAND_PATH")
(:value . "/data/data/com.termux/files/usr/bin/ps"))
((:type . "stringarray")
(:key . "com.termux.RUN_COMMAND_ARGUMENTS")
(:value . (((:value . "a"))
((:value . "x")))))))
(:action . "com.termux.RUN_COMMAND"))))

sensor

removeComponent

Shell scripts bundled with the application. Served with simple template expansion, directory index is enabled.

/settings

/test_connection

Returns a page reporting the setup status of the connection to Emacs in human friendly text. No authentication required.

Preparing the build environment

Android builds

First the directory structure gets prepared, and some variables need to be set. The SDK directory used here is ~/.android/sdk:

export ANDROID_SDK_ROOT=$HOME/.android/sdk
export ANDROID_HOME=$HOME/.android/sdk
mkdir -p $ANDROID_HOME

Next the command line tools need to be downloaded from the Android SDK download page in the 'Command line tools only' section, and extracted:

unzip -d $ANDROID_HOME ~/Downloads/commandlinetools-linux-6858069_latest.zip
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/tools/bin

Now sdkmanager can be used to initialize the SDK and download required packages:

sdkmanager --verbose --licenses
sdkmanager --update
sdkmanager "platforms;android-29" "ndk-bundle" "build-tools;30.0.2" "platform-tools" "tools"

Next Qt needs to be Downloaded (5.15.1 mirror list), extracted and built:

tar xf qt-everywhere-src-5.15.1.tar.xz
cd qt-everywhere-src-5.15.1
./configure -opensource -confirm-license -android-abis armeabi-v7a,arm64-v8a,x86_64 -xplatform android-clang --disable-rpath -nomake tests -nomake examples -no-warnings-are-errors -android-ndk $HOME/.android/sdk/ndk-bundle -android-sdk $HOME/.android/sdk/platforms -android-ndk-platform android-29 -prefix $HOME/qt/qt5.15.1-android-29
make -j$(nproc)
make -j$(nproc) install

Windows builds

The Windows version is highly experimental, seems to segfault due to issues with Qt remote objects, and probably won't see any work unless I'm very bored or somebody is interested in actually using it on Windows. Therefore the following just contains a few pointers for a chance to have a build environment.

A Visual Studio build might have the best chances to actually work, but probably will require code changes. MinGW compiles without code changes. On OpenSuSE probably the following packages are required:

  • mingw64-cross-pkgconf
  • mingw64-libicu-devel
  • mingw64-angleproject-devel
  • mingw64-cross-binutils
  • mingw64-cross-gcc
  • mingw64-cross-gcc-c++
  • mingw64-cross-pkg-config
  • mingw64-dbus-1-devel
  • mingw64-filesystem
  • mingw64-libicu-devel
  • mingw64-libjpeg-devel
  • mingw64-libopenssl-devel
  • mingw64-libpng-devel
  • mingw64-libtiff-devel
  • mingw64-mysql-connector-c-devel
  • mingw64-pcre-devel
  • mingw64-sqlite-devel
  • mingw64-zlib-devel
  • mingw64-libharfbuzz-devel
  • mingw64-glib2-devel
  • mingw64-libintl-devel

With those installed this should provide a more or less working build of Qt for Windows:

rm -Rf qtactiveqt
./configure -opensource -confirm-license -xplatform win32-g++ -device-option CROSS_COMPILE=x86_64-w64-mingw32- -nomake examples -release -make tools -prefix $HOME/qt/qt5.15.0-mingw64 -opengl desktop -skip qtlocation -skip qtactiveqt

Resources

Android

Qt