Survex Hacker's Guide

# Hacking Survex

(That's hacking in the "tinkering with code" sense, not in the "breaking into other people's computer systems" sense).

This is currently a random collection of notes that need to be written down while I remember. With time it should evolve into a more coherent document. If you have any questions which this should answer but doesn't then ask me and I'll add them.

## Network code debugging

You can pick which network simplifications are attempted using "-z" with an argument listing code letters. So:

- -z= no special simplifications (articulation still performed)
- -z=l remove "lollipops"
- -z=p remove parallel legs
- -z=d convert deltas to stars

And you can combine these in any combination:

- -z=lp remove "lollipops" and parallel legs
- -z=lpd remove "lollipops" and parallel legs; convert deltas to stars

"-z=lpd" is the default (in 0.99 at least - more transformations may conceivably be added in future, although the simple common cases are already covered).

## Developing on Unix Platforms

You'll need automake 1.5 or later (earlier versions don't support per-executable CFLAGS; 1.6 has been tested and works, but wasn't a very stable release - automake 1.6.1 is a better bet) and autoconf 2.50 or later (autoconf 2.52, 2.53, 2.64 and 2.71 have all been used successfully).

The wxWidgets library is used for aven's UI. Currently >= 3.2.0 is supported.

The PROJ library is used for coordinate conversions. Currently >= 7.2.0 is supported.

The Perl Locale::PO module is used for process message translation files.

For building the documentation you'll need sphinx-doc (Debian/Ubuntu package `python3-sphinx`) and w3m.

And for building unifont.pixelfont, you'll need unifont installed.

On Debian, you can install the required packages using:

    sudo apt-get install autoconf automake liblocale-po-perl libproj-dev libwxgtk3.2-dev inkscape netpbm python3-sphinx w3m unifont

## Building on Non-Unix Platforms

### Mingw (Microsoft Windows)

Survex can be built in an MSYS2+mingw64 environment - since 1.4.9 the pre-built installer for Microsoft Windows is built in such an environment by a CI job running on Github Actions.

It should also be possible to use a Linux-hosted cross-compiler, which is how we used to built releases, but this requires cross-building a lot of required libraries so we gave up on doing this. Some notes on this are left below in case anyone wants to try.

I use the packaged cross-compiler in the debian testing/unstable distribution:

    sudo apt-get install mingw-w64-i686-dev

Then install the various libraries by compiling from source. For wxWidgets I apply a patch to disable a pointless and annoying compiler ABI check (with this check aven stops working each time my cross compiler package is upgraded to a new GCC version; without it everything works fine).

Then I configure, build and install with:

    ./configure --prefix=/usr/i686-w64-mingw32 --host i686-w64-mingw32 --with-msw --with-opengl --enable-display --disable-shared host_alias=i686-w64-mingw32
    make
    sudo make install

For sqlite (needed by PROJ):

    wget https://www.sqlite.org/2021/sqlite-autoconf-3360000.tar.gz
    tar xvf sqlite-autoconf-3360000.tar.gz
    mkdir BUILD
    cd BUILD
    ../configure --prefix=/usr/i686-w64-mingw32 --host i686-w64-mingw32 --disable-shared --disable-fts4 --disable-fts5 --disable-json1 --disable-rtree host_alias=i686-w64-mingw32
    make
    sudo make install

Sadly newer versions of PROJ have to be built with cmake. For PROJ 9.3.0 I used the following (TIFF is apparently useful for some grids, but would also need libtiff):

    mkdir BUILD
    cd BUILD
    cmake .. -DCMAKE_TOOLCHAIN_FILE=~/git/survex/cross-mingw.cmake -DCMAKE_INSTALL_PREFIX=/usr/i686-w64-mingw32 -DENABLE_CURL=OFF -DENABLE_TIFF=OFF -DBUILD_PROJSYNC=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON -DFETCHCONTENT_FULLY_DISCONNECTED=ON -DBUILD_TESTING=OFF
    make
    sudo make install

where `cross-mingw.cmake` contains:

    # the name of the target operating system
    set(CMAKE_SYSTEM_NAME Windows)

    # which compilers to use for C and C++
    set(CMAKE_C_COMPILER   i686-w64-mingw32-gcc)
    set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)

    # where is the target environment located
    set(CMAKE_FIND_ROOT_PATH  /usr/i686-w64-mingw32)

    # adjust the default behaviour of the FIND_XXX() commands:
    # search programs in the host environment
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

    # search headers and libraries in the target environment
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

For ffmpeg 4.4.1:

    sudo apt-get install yasm
    mkdir BUILD
    cd BUILD
    ../configure --prefix=/usr/i686-w64-mingw32 --cross-prefix=i686-w64-mingw32- --enable-cross-compile --target-os=mingw32 --arch=i686 --disable-shared --disable-decoders --disable-demuxers --disable-programs --disable-network --disable-bsfs --disable-protocols --disable-devices
    make
    sudo make install

You'll also need to install GDAL, which requires a lot of other libraries installed to build. I gave up at this point.

## Microsoft Windows Installer Builder

We use InnoSetup to build the MS Windows Installer. Since 1.4.9 we use the InnoSetup version which is pre-installed in the Github CI images.

Survex 1.4.8 was built using InnoSetup 6.2.2.

Here are some random notes on the old cross-building approach:

### Packages Needed

On Debian unstable/testing:

    sudo apt-get install wine wx3.2-i18n

And then run:

    wine ~/Downloads/innosetup-6.2.2.exe

### Translations

In addition to the translations included with InnoSetup as standard, we also add these, which you can find in the `lib` subdirectory of Survex's source tree:

- ChineseSimplified.isl (6.1.0+)
- ChineseTraditional.isl (6.1.0+)
- EnglishBritish.isl (6.1.0+)
- Greek.isl (6.1.0+)
- Indonesian.isl (6.1.0+)
- Romanian.isl (6.1.0+)

These are taken from the Inno Setup Translations page.

### survex.iss

This file is generated by configure (from the template survex.iss.in). We could instead have a static survex.iss which uses #include to pull in a file with the Survex version info in, but the current method works well enough so we'll stick with it for now (I suspect #include was introduced since we started using InnoSetup).