Skip to content

Commit

Permalink
GUACAMOLE-1841: Replace outdated Cygwin build info.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmuehlner committed Jan 25, 2024
1 parent 48b6baf commit 45f12b3
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 147 deletions.
33 changes: 0 additions & 33 deletions Dockerfile.windows

This file was deleted.

170 changes: 81 additions & 89 deletions README-windows-build.md
Original file line number Diff line number Diff line change
@@ -1,127 +1,119 @@
# Building guacamole-server for Windows
The `guacamole-server` Windows build relies on compatibility features provided by Cygwin (most notably, a `fork()` implmentation), and therefore _must_ be built using Cygwin tools. Since no Cygwin cross-compilation environment exists, this means that `guacamole-server` can only be built for Windows using the Windows OS. This document describes a build that produces a working `guacd.exe`, as well as shared libraries for every supported protocol.
Certain portions of `guacamole-server` can be built using MinGW on Windows, specifically the libguac libraries. `guacd` itself relies on `fork()` and other functionality that has no equivalent in Windows. Theoretically, Cygwin could provide a compatibility layer for these missing functions, but so far attempts to implement such a build have not resulted in a functional `guacd`.

## Build Specifics
In this example, `guacamole-server` was built under Cygwin, on a Windows Server 2022 x86_64 build node. Dependencies were installed using packages from Cygwin and MSYS2 (and built from source where no suitable package is available, in the case of `libtelnet` and `libfreerdp2`).
This document will walk you through a known-working set of steps for building the libguac libraries for a Windows target. The following build steps were tested on a Windows Server 2022 x86_64 build node.

### Build Steps
1. Install Cygwin (version 2.926 used here)
2. Install MSYS2 (version 20230718 used here)
3. Install Cygwin packages:
* autoconf
* automake
* cmake
* git
* gcc-core
* libtool
* libuuid-devel
* make
* pkg-config
4. Install MSYS2 packages:
1. Install MSYS2 (version 20230718 used here)
2. Install MSYS2 packages:
* autoconf-wrapper
* automake-wrapper
* diffutils
* git
* libtool
* libedit-devel
* make
* pkg-config
* wget
* msys2-runtime-devel
* mingw-w64-x86_64-gcc
* mingw-w64-x86_64-cairo
* mingw-w64-x86_64-pango
* mingw-w64-x86_64-libwebsockets
* mingw-w64-x86_64-libvncserver
* mingw-w64-x86_64-libssh2
* mingw-w64-x86_64-libtool
* mingw-w64-x86_64-libmariadbclient
* mingw-w64-x86_64-postgresql
* mingw-w64-x86_64-libpng
* mingw-w64-x86_64-libjpeg
* mingw-w64-x86_64-dlfcn
* mingw-w64-x86_64-pkg-config
* mingw-w64-x86_64-pulseaudio
* mingw-w64-x86_64-libvorbis
* mingw-w64-x86_64-cairo
* mingw-w64-x86_64-gcc
* mingw-w64-x86_64-gdb
* mingw-w64-x86_64-libpng
* mingw-w64-x86_64-libjpeg-turbo
* mingw-w64-x86_64-freerdp
* mingw-w64-x86_64-freetds
* mingw-w64-x86_64-postgresql
* mingw-w64-x86_64-libmariadbclient
* mingw-w64-x86_64-libvncserver
* mingw-w64-x86_64-dlfcn
* mingw-w64-x86_64-libgcrypt
* mingw-w64-x86_64-libgxps
* mingw-w64-x86_64-libwebsockets
* mingw-w64-x86_64-libwebp
* mingw-w64-x86_64-libssh2
* mingw-w64-x86_64-openssl
* mingw-w64-x86_64-libvorbis
* mingw-w64-x86_64-pulseaudio
* mingw-w64-x86_64-zlib
5. Build `libtelnet` from source using MSYS2 bash shell
*
3. Build `libtelnet` from source using MSYS2 bash shell
```
export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig"
export PATH="$PATH:/mingw64/bin:/usr/bin"
curl -s -L https://github.com/seanmiddleditch/libtelnet/releases/download/0.23/libtelnet-0.23.tar.gz | tar xz
cd libtelnet-0.23
autoreconf -fi
./configure --disable-static --disable-util LDFLAGS="-Wl,-no-undefined"
./configure --prefix=/mingw64 --disable-static --disable-util LDFLAGS="-Wl,-no-undefined -L/mingw64/bin/ -L/mingw64/lib" || cat config.log
cat config.log
make LDFLAGS="-no-undefined"
make install
# Required for the Windows Build to understand how to link against this DLL
ln -s /usr/bin/msys-telnet-2.dll /usr/bin/libtelnet.dll
ln -s /mingw64/bin/msys-telnet-2.dll /mingw64/bin/libtelnet.dll
```
5. Build `libfreerdp2` from source using Cygwin bash shell
4. Fix DLL prefixes so that the build can link against them, e.g. using this script
```
curl -s -L https://github.com/FreeRDP/FreeRDP/archive/2.10.0/FreeRDP-2.10.0.tar.gz | tar xz
cd FreeRDP-2.10.0
cmake \
-DWITH_ALSA=OFF \
-DWITH_CUPS=OFF \
-DWITH_CHANNELS=ON \
-DBUILTIN_CHANNELS=OFF \
-DCHANNEL_URBDRC=OFF \
-DWITH_CLIENT=ON \
-DWITH_DIRECTFB=OFF \
-DWITH_FFMPEG=OFF \
-DWITH_GSM=OFF \
-DWITH_GSSAPI=OFF \
-DWITH_GSTREAMER_1_0=OFF \
-DWITH_GSTREAMER_0_10=OFF \
-DWITH_IPP=OFF \
-DWITH_JPEG=ON \
-DWITH_MANPAGES=ON \
-DWITH_OPENH264=OFF \
-DWITH_OPENSSL=ON \
-DWITH_PCSC=OFF \
-DWITH_PULSE=OFF \
-DWITH_SERVER=OFF \
-DWITH_SERVER_INTERFACE=OFF \
-DWITH_SHADOW_X11=OFF \
-DWITH_SHADOW_MAC=OFF \
-DWITH_SSE2=$SSE2_SETTING \
-DWITH_WAYLAND=OFF \
-DWITH_X11=OFF \
-DWITH_X264=OFF \
-DWITH_XCURSOR=ON \
-DWITH_XEXT=ON \
-DWITH_XKBFILE=ON \
-DWITH_XI=OFF \
-DWITH_XINERAMA=OFF \
-DWITH_XRENDER=OFF \
-DWITH_XTEST=OFF \
-DWITH_XV=OFF \
-DWITH_ZLIB=ON \
.
cmake . -G"Unix Makefiles"
make
make install
#!/bin/bash
set -e
set -x
# Enable fancy pattern matching on filenames (provides wildcards that can match
# multiple contiguous digits, among others)
shopt -s extglob
# Strip architecture suffix
for LIB in /mingw64/bin/lib*-x64.dll; do
ln -sfv "$LIB" "$(echo "$LIB" | sed 's/-x64.dll$/.dll/')"
done
# Automatically add symlinks that strip the library version suffix
for LIB in /mingw64/bin/lib*-+([0-9]).dll; do
ln -sfv "$LIB" "$(echo "$LIB" | sed 's/-[0-9]*\.dll$/.dll/')"
done
# Automatically add symlinks that strip the library version suffix
for LIB in /mingw64/bin/lib*([^0-9.])@([^0-9.-])+([0-9]).dll; do
ln -sfv "$LIB" "$(echo "$LIB" | sed 's/[0-9]*\.dll$/.dll/')"
done
```
7. Build `guacamole-server` from source using Cygwin bash shell
5. Build `guacamole-server` from source using MSYS2 bash shell
```
export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:/usr/lib/pkgconfig"
export PATH="$PATH:/mingw64/bin:/usr/bin"
# FIXME: Update this to check out master once this PR is ready for merge
git clone https://github.com/jmuehlner/guacamole-server.git
cd guacamole-server
git checkout GUACAMOLE-1841-cygwin-build
git checkout GUACAMOLE-1841-cygwin-build-clean
autoreconf -fi
export LDFLAGS="-L/usr/bin/ -L/usr/lib/ -L/usr/local/lib -L/usr/local/bin -L/cygdrive/c/msys64/mingw64/bin -L/cygdrive/c/msys64/mingw64/lib -L/cygdrive/c/msys64/usr/bin"
export CFLAGS="-idirafter /cygdrive/c/msys64/mingw64/include/winpr2 -idirafter /usr/include/ -idirafter /cygdrive/c/msys64/mingw64/include -idirafter /cygdrive/c/msys64/mingw64/include/pango-1.0 -idirafter /cygdrive/c/msys64/mingw64/include/cairo -idirafter /usr/local/include/freerdp2 -idirafter /cygdrive/c/msys64/mingw64/include/glib-2.0 -idirafter /cygdrive/c/msys64/mingw64/include/harfbuzz -idirafter /cygdrive/c/msys64/mingw64/lib/glib-2.0/include -idirafter /cygdrive/c/msys64/usr/include"
export PKG_CONFIG_PATH="/cygdrive/c/msys64/mingw64/lib/pkgconfig/:/usr/local/lib/pkgconfig"
./configure --with-windows || cat config.log
export LDFLAGS="-L/mingw64/bin/ -L/usr/bin/ -L/mingw64/lib -lws2_32"
export CFLAGS="-isystem/mingw64/include/ \
-I/mingw64/include/pango-1.0 \
-I/mingw64/include/glib-2.0/ \
-I/mingw64/lib/glib-2.0/include/ \
-I/mingw64/include/harfbuzz/ \
-I/mingw64/include/cairo/ \
-I/mingw64/include/freerdp2 \
-I/mingw64/include/winpr2 \
-Wno-error=expansion-to-defined
-Wno-error=attributes"
./configure --prefix=/mingw64 --with-windows --disable-guacenc --disable-guacd --disable-guaclog || cat config.log
make
make install
```
## Closing Notes
The generated `guacd.exe` will run as expected when invoked from the Cygwin bash shell, but when run outside of a Cygwin environment (e.g. using powershell), connections using text-based protocols (ssh, telnet, kubernetes) will fail with `Fontconfig error: Cannot load default config file`.
FIXME: Update this document to explain how to configure fonts under Windows once I figure it out.
In addition, to enable running `guacd.exe` outside of a Cygwin environment, all (non-system) DLLs that it depends on should be copied into the same directory as the executable. These can be found by running `ldd` in the Cygwin bash shell - e.g.
```
ldd /usr/local/sbin/guacd.exe
find /usr -name '*guac*.dll' | xargs ldd
```
25 changes: 0 additions & 25 deletions scripts/fix-links.sh

This file was deleted.

0 comments on commit 45f12b3

Please sign in to comment.