Building Fuse
-------------

A compiler supporting the C11 language standard is required. Fuse targets
C11 and does not require features introduced in C17 or C23.

To compile Fuse (see below for instructions for other ports):

$ ./configure

There are now some options you can give to configure; `configure
--help' will list them all, but the most important are:

--with-fb		Use the framebuffer interface, rather than GTK.
--with-sdl		Use the SDL2 interface, rather than GTK.
--with-null-ui		Use the null user interface (headless builds and CI).
--without-gtk		Use the plain Xlib interface.

If glib is installed on your system, Fuse will use this for a couple
of things; however, it isn't necessary as libspectrum provides
replacements for all the routines used by Fuse.

The `--enable-automation` option enables the development automation
interface used by the CI unit-test runs; it requires zlib.

Another useful option is `--with-local-prefix=DIRECTORY' which allows
you to specify that you have some of the libraries needed by Fuse in
`<DIRECTORY>/lib' and the necessary header files in
`<DIRECTORY>/include'. If you specify the `--prefix' option to tell
Fuse to install itself somewhere other than in /usr/local, that
directory will automatically be searched as well.

Then just:

$ make

and then

$ make install

if you want to place Fuse into the main directories on your system
(under /usr/local by default, although you can change this with the
--prefix argument to 'configure'). You'll probably need to be root to
do this bit.

Once you've got Fuse configured and built, read the man page :-)

Note that if you're using version of Fuse from Git rather than
one of the released tarballs, you'll need to run `autogen.sh' before
running 'configure' for the first time.

Building the macOS version of Fuse
----------------------------------

The native Cocoa port by Fredrick Meunier <fredm@spamcop.net> comes as
a set of Xcode projects for libgcrypt, libspectrum and Fuse itself.

Building the Wii version of Fuse
--------------------------------

You'll need to have the standard Wii homebrew toolchain installed; see
eg <http://wiibrew.org/wiki/DevkitPro> for some information on setting
this up.

After that, make sure the dev tools are in your path (export
PATH=$PATH:$DEVKITPPC/bin) and that a Wii version of libspectrum has been
built and installed.

Then, use this configure line:

./configure --target=powerpc-gekko --host=powerpc-gekko \
	    --with-wii \
	    --without-libxml2 --without-libiconv --without-gpm --without-x \
	    CFLAGS="-g -I$DEVKITPPC/include -I$DEVKITPRO/libogc/include -DGEKKO" \
	    LDFLAGS="-g -mrvl -mcpu=750 -meabi -mhard-float \
                     -Wl,-Map,fuse.elf.map -L$DEVKITPPC/lib \
                     -L$DEVKITPRO/libogc/lib/wii" \
            LIBS="-lfat -lwiiuse -lbte -logc -lm"

Finally, to build, use this line:

EXEEXT=".elf" make -e

This should build fuse.elf, which you can run on your Wii via the usual
methods.

Building the Win32 version of Fuse
----------------------------------

You'll need to have the Mingw-w64 toolchain <http://mingw-w64.org/>, e.g., on
Debian: `apt-get install mingw-w64'

The Windows build environment is MSYS2 <https://www.msys2.org/>.
Use its MINGW32 shell for native 32-bit binaries, not the MSYS shell, and do not
mix Cygwin or other MinGW installations into PATH. A 64-bit Windows host runs
MSYS2, but the selected MINGW32 compiler produces 32-bit Fuse executables.

The Linux cross-compilation example below omits optional libraries for clarity.
The MSYS2 instructions include the libraries used by the Windows release builds.

1) On Linux, first build libspectrum:

./configure --host=i686-w64-mingw32 --without-zlib \
            --without-libgcrypt --without-bzip2 --with-fake-glib --prefix=`pwd`
make install

This should install libspectrum into the same source directory.

Then, compile Fuse:

PKG_CONFIG_LIBDIR=`pwd`/../libspectrum/lib/pkgconfig \
./configure --host=i686-w64-mingw32 --prefix=`pwd` --with-win32 \
            --without-libxml2 --without-zlib --without-png --without-pthread
make

You have to use the real path of libspectrum with `PKG_CONFIG_LIBDIR'.
This should build `fuse.exe' without any external lib, but you can run it on
Windows or Linux (with Wine).

You need libwinpthread-1.dll in the same directory as `fuse.exe', most
likely it is located in /usr/i686-w64-mingw32/lib/

2) On Windows, install MSYS2, update it with `pacman -Syu' (restart the shell
and repeat if requested), then open the MSYS2 MINGW32 shell. Install tools:

pacman -S --needed autoconf-wrapper automake-wrapper libtool make git bison flex dos2unix \
  man2html zip curl \
  mingw-w64-i686-gcc mingw-w64-i686-pkgconf \
  mingw-w64-i686-bzip2 mingw-w64-i686-zlib \
  mingw-w64-i686-libpng mingw-w64-i686-libxml2

For installers, separately install native NSIS <https://nsis.sourceforge.io/>
and put makensis.exe on PATH; this host tool does not need to be 32-bit.
CI installs it using Chocolatey.

Check that `echo $MSYSTEM' reports MINGW32 and `gcc -dumpmachine' reports
i686-w64-mingw32.

From the Fuse source directory, prepare the remaining dependencies:

export CPPFLAGS=-I/opt/fuse/include
export LDFLAGS=-L/opt/fuse/lib
export PKG_CONFIG_PATH=/opt/fuse/lib/pkgconfig
export PATH=/opt/fuse/bin:$PATH
bash .github/scripts/install_windows_crypto.sh

The crypto helper installs pinned official MSYS2 libgcrypt/libgpg-error packages.
It verifies their SHA-256 hashes and detached signatures against the MSYS2
pacman keyring. Transitive dependencies are installed by pacman.

libspectrum provides PCM WAV support without an external WAV library.

MSYS2 environment setup is also documented in:
https://sourceforge.net/p/fuse-emulator/wiki/Building%20Fuse%20on%20Windows%20with%20MinGW-w64%20and%20MSYS2/

Now change to the libspectrum source directory and build:

./autogen.sh
./configure --prefix=/opt/fuse --with-fake-glib \
            --with-wav-backend=pcm
make -j2
make check
make install-strip

Keep static libraries enabled for libspectrum's internal unit tests. Its shared
DLL is also built and is used by Fuse.

Then return to the Fuse source directory (keeping those exported variables):

./autogen.sh
./configure --prefix=/opt/fuse --disable-static --with-win32
make -j2
make check

For the SDL2 UI, install mingw-w64-i686-SDL2 and replace
--with-win32 with --without-win32 --with-sdl --with-audio-driver=sdl.

Note: you need the installed `libspectrum-*.dll' and the `roms' and `lib'
  directories alongside `fuse.exe'. You may copy this file and directories
  into that directory where `fuse.exe' exists. On Windows you may need to
  copy all files from `lib/uncompressed' into `lib'. Alternatively, you could
  run this rule:

  make install-win32 DESTDIR=/path/to/Fuse

  If you are planning to distribute Windows binaries with third parties on a
  regular basis, maybe you will find the next rules quite useful:

  make dist-win32-zip
  make dist-win32-7z
  make dist-win32-exe

  Additional tools are required for the former rules: Info-Zip, p7zip and NSIS,
  respectively. That will make a temporary subdirectory (fuse-VERSION-win32)
  in the build directory and then will create a package.

  Before packaging, stage the DLLs from this same MSYS2 environment:

  dest=fuse-VERSION-win32    # Substitute the configured Fuse version.
  make install-win32 DESTDIR="$dest"
  cp /opt/fuse/bin/*.dll "$dest/"
  bash data/win32/check_win32_dll_deps.sh "$dest"
  bash .github/scripts/collect_windows_notices.sh "$dest" "$dest/3rd-party"
  cp ../libspectrum/COPYING "$dest/3rd-party/libspectrum-COPYING.txt"
  make dist-win32-zip
  make dist-win32-exe

  Adjust the libspectrum source path in the COPYING command if necessary.
  DLL dependencies are collected recursively. Use libraries from the same
  MSYS2 environment throughout the build. The release workflow,
  .github/workflows/windows_release.yml, transfers libspectrum's DLLs between
  jobs and checks that dependency package versions match.

  Before distributing a build, run the tests and verify startup on a clean
  Windows system, installer/ZIP contents, audio and tape loading.
