Table of Contents

1 Building from source

    1.1 Build system introduction

        1.1.1 Makefile variables to override

        1.1.2 Make targets

        1.1.3 Build a module

        1.1.4 Parallel build

        1.1.5 Generate DSP/DSW files to use with MSVC6.0

    1.2 Build use cases

        1.2.1 Build use cases under MS Windows

    1.3 Build system dependencies

    1.4 Build under MS Windows

        1.4.1 Cygwin

   Cygwin installation

   Cygwin usage

        1.4.2 UnxUtils

   UnxUtils installation

   UnxUtils usage

        1.4.3 MinGW and MSYS

   MinGW and MSYS installation

   MinGW and MSYS usage

1 Building from source

1.1 Build system introduction

Ferry's build system is based on GNU Make. The build system uses a limited number of standard Unix utilities like 'grep', 'sed', 'cp' etc. that are likely to present on any modern Linux desktop and also ported to Windows platform (see 1.4 Build under MS Windows). Build system uses shell scripts with syntax compatible across Bash and Zsh shells. See 1.3 Build system dependencies for more information on tools needed to build Ferry.

Every module of the system has its own makefile. Module is either static or shared library, or an executable. The top level makefile is $FERRY/fe/build/ It is a placeholder for rules to build a set of modules in proper order considering dependencies by running submake for every module.

Dependencies between modules are declared in special text files (e.g.: $FERRY/fe/build/deps). The following command will output the complete list of these files:

find $FERRY -name deps -type f

The build system provides a notion of 'flag'. Flag is just a makefile variable whose value is persistent across sequential Make invocations. If value of some flag changes all modules depending on that flag are rebuilt. E.g.: DEBUG and MODULES makefile variables are flags.

There is a shell script wrapping Make invocation - $FERRY/fe/build/ It sets some mandatory makefile variables and runs Make with the top level makefile. It is not mandatory to use this wrapper for building, though it is convenient.

The command line syntax for $FERRY/fe/build/ is:

$FERRY/fe/build/ <options> <make_args>

The table below lists supported options:

Option name Option description


Prints help message and exits without calling Make.


Specifies that it is a debug build. See DEBUG makefile variable.

-p <platform>

Specifies name of underlying s/w platform. See PLATFORM makefile variable.

-m <make_option>

Escapes a single Make option. The <make_option> should be one of options supported by GNU Make, e.g.:

$FERRY/fe/build/ -m -d -m -j -m -p

The above example is equivalent to the following command line:

$FERRY/fe/build/ -m -d -j -m -p

because you don't need to escape GNU Make options that don't conflict with $FERRY/fe/build/ options ('-j' in the above example).

After parsing of any two above command line arguments $FERRY/fe/build/ will invoke Make as follows:

make -f -d -j -p

$FERRY/fe/build/ passes unrecognized command line arguments to Make command line unchanged.

$FERRY/fe/build/ sets default values for OS, PLATFORM makefile variables depending on the build environment. It also sets DEVTOOL makefile variable if it is not explicitly set on the command line.

The table below shows how the

$FERRY/fe/build/ -d -m -d AT= BLDROOT=/out fe/fe/fe

command line is transferred into Make command line, depending on the build environment:

Build environment Make command line arguments

Windows & Cygwin

make -r -f -d DEBUG=true AT= BLDROOT=/out fe/fe/fe OS=win32 PLATFORM=win32 DEVTOOL=msvc60

Windows & MinGW

make -r -f -d DEBUG=true AT= BLDROOT=/out fe/fe/fe OS=win32 PLATFORM=win32 DEVTOOL=gcc-mingw

Windows & UnxUtils

make -r -f -d DEBUG=true AT= BLDROOT=/out fe/fe/fe OS=win32 PLATFORM=win32 DEVTOOL=msvc60

1.1.1 Makefile variables to override

The table below lists a set of makefile variables that are commonly overridden at command line.

Variable name Default value Variable description



Absolute path to the top level directory where all generated sources, object files, binaries, etc. are placed. It is highly recommended to make this variable point to a directory outside of Ferry's source tree to have clean separation of sources and transient (i.e. object, binary, etc.) files.

The value shouldn't have trailing slash ('/').


Set by $FERRY/fe/build/ depending on the build environment. See How the command line is transferred into Make command line depending on the build environment.

Name of development tool to use. Should be one of listed below:

  • msvc60
  • gcc-mingw


List of all available modules

Double colon separated list of modules to build. See 'ls-modules' make target for the complete list of available modules.


Set by $FERRY/fe/build/ depending on the build environment. See How the command line is transferred into Make command line depending on the build environment.

Name of underlying s/w platform. So far the only supported platform is Windows API, 32bit. You normally should use '-p' option of $FERRY/fe/build/ script to specify platform.


Controls if the build is 'debug'. By default DEBUG variable is not set (DEBUG=), so the build is 'release'. You normally should use '-d' option of $FERRY/fe/build/ script to produce debug build instead of explicit DEBUG=true as '-d' controls some additional makefile variables.



Suppresses or enables print of commands in rules. Set to empty string (AT=) to enable printing. You shouldn't normally override value of this variable unless you need to debug makefiles.

1.1.2 Make targets

The table below lists public top level targets.

Target name Target description


Builds all modules. See 'ls-modules' make target for the complete list of available modules.

You shouldn't normally specify this target as many modules are just for testing and you may not want to build them. Instead specify module name(s) explicitly. See 1.1.3 Build a module.



Generates contents for site.


Generates Ferry documentation. This target is just a shortcut to build 'buildnotes' and 'doxydoc' targets.


Runs shell script to generate $BLDROOT/gen/doc/html/build_notes.html file. Script uses Saxon XSLT processor. Use SAXON_JAR makefile variable to set path to saxon.jar - archive with Saxon XSLT processor implementation, e.g:

$FERRY/fe/build/ buildnotes BLDROOT=`pwd`/ferry-out SAXON_JAR=/lib/saxon.jar


Runs Doxygen to generate Ferry API documentation. Output goes to the $BLDROOT/gen/doc/html directory. If Doxygen executable is not in the $PATH, or you want to explicitely specify Doxygen executable, use DOXYGEN makefile variable to specify path to it, e.g:

$FERRY/fe/build/ doc BLDROOT=`pwd`/ferry-out DOXYGEN=/bin/doxygen


Prints flags with the current values to the console.


Outputs target names for building all modules. So far the complete list of modules is following:

  • fe/fe/core
  • fe/fe/ui
  • fe/fe/fe
  • fe/fe/core_sanity_test
  • fe/fe/core_test
  • fe/fe/ui_sanity_test
  • fe/fe/fe_test
  • fe/ext/colorer
  • fe/ext/colorer_decorator
  • fe/ext/scintilla_lexers
  • fe/ext/scintilla_decorator
  • fe/ext/ext_cfg
  • fe/ext/bindings
  • fe/ext/ext
  • uc/cmn/cmn
  • uc/cmn/test
  • uc/hopper/hopper
  • uc/hopper/test_sanity
  • uc/hopper/test_gen
  • uc/mem/mem
  • uc/mem/test
  • uc/cmd/cmd
  • uc/mt/mt


Builds Ferry Core library.


Builds Ferry Extensions library. The target depends on fe/fe/fe target.


Builds interactive test application to exercise Ferry Core and Ferry Extensions libraries. The target depends on fe/ext/ext target.

This is the target you normally should specify to build Ferry Core and Ferry Extensions libraries and an application that demonstrates basic features these libraries provide.

1.1.3 Build a module

The following command will examine and rebuild if outdated all modules <module_name> module depends on and finally rebuild the module itself:

$FERRY/fe/build/ <module_name>

$FERRY/fe/build/ MODULES=<module_name>

where <module_name> is one of names 'ls-modules' make target outputs.

If you don't want the build system to spend time considering module dependencies use the following command:

$FERRY/fe/build/ <module_name>.self

$FERRY/fe/build/ MODULES=<module_name>.self

I.e. suffix '.self' appended to a module name instructs build system that it should not consider dependencies for the target. This saves time but obviously produces consistent result only if module dependencies are up to date.

You can specify multiple module names, e.g.:

$FERRY/fe/build/ fe/fe/fe fe/ext/ext.self

or using MODULES makefile variable:
$FERRY/fe/build/ MODULES=fe/fe/fe:fe/ext/ext.self

1.1.4 Parallel build

Ferry's makefiles are consistent enough to allow parallel builds. Just use standard Make '-j' option:

$FERRY/fe/build/ -j fe/fe/fe

Parallel build doesn't work if DEVTOOL=msvc60, GEN_IDE_PRJ=false and DEBUG=true, as compilers from MSVC family use a single file to store debugging information (MSVC6.0 uses 'vc.pdb') for all object files in a module. The problem is that object files don't depend on each other but depend on corresponding source files thus Make starts two or more compilation tasks simultaneously which results in failures to update module's 'vc.pdb' if it is already opened for update by another compilation task and not closed yet.

1.1.5 Generate DSP/DSW files to use with MSVC6.0

The build system can produce project/workspace files in MSVC6.0 format instead of compiling sources. These files can be later loaded in MSVC6.0 IDE or automatically imported by the newer MSVC IDEs.

To use this feature set DEVTOOL=msvc60 and GEN_IDE_PRJ=true, e.g.:

$FERRY/fe/build/ DEVTOOL=msvc60 GEN_IDE_PRJ=true MODULES=fe/fe/fe

The above command will produce DSP file for fe/fe/fe module ($BLDROOT/gen/msvc60/fe/fe.dsp) as well as a number of DSP files for all its dependencies. And the workspace file that properly inherits dependencies between modules would be $BLDROOT/gen/msvc60/fe.dsw.

Generated DSP/DSW files address source files as well as output directories with relative paths that makes these files usable outside of the build machine without additional manual changes. You can even generate DSP/DSW files on Linux build machine and later use on Windows box.

You should always use MODULES makefile variable to specify what DSP files to generate as in opposite case build system will not generate DSW file.

1.2 Build use cases

1.2.1 Build use cases under MS Windows

This section gives examples of the most common build configurations under MS Windows platform. It focuses on use of makefile variables that are not covered in 1.1.1 Makefile variables to override section.

Build Ferry Core and Ferry Extensions libraries as DLLs using MinGW. The result of the build is $BLDROOT/bin/fe.dll and $BLDROOT/bin/feext.dll files:

$FERRY/fe/build/ MODULES=fe/ext/ext DEVTOOL=gcc-mingw

The same result but using one of MSVC compilers:

$FERRY/fe/build/ MODULES=fe/ext/ext DEVTOOL=msvc60

When MSVC compiler is used from command line ensure that corresponding environment variables are set properly, do the following:

  1. Run cmd.exe;
  2. Execute corresponding vcvars32.bat batch file from the started cmd.exe (See for brief description of vcvars32.bat);
  3. Start Unix-like build environment of your preference (See 1.4 Build under MS Windows for information on suitable build environment under MS Windows) from the running cmd.exe;
  4. Run $FERRY/fe/build/ from the started shell.

Generate MSVC6.0 project files for debug build of Ferry Core and Ferry Extensions libraries. Generate project files asynchronously for speed:

$FERRY/fe/build/ -j -d MODULES=fe/fe/fe DEVTOOL=msvc60 GEN_IDE_PRJ=true

Build and pack Ferry Core and Ferry Extensions libraries in a single DLL - $BLDROOT/bin/feext.dll. DEVTOOL makefile variable is set implicitely depending on the build environment:

$FERRY/fe/build/ MODULES=fe/ext/ext FE_FE_SHARED_LIB=false

Like the example above but Ferry Core and Ferry Extensions libraries are packed in a single static library - $BLDROOT/lib/feext.lib rather then in a single DLL:

$FERRY/fe/build/ MODULES=fe/ext/ext FE_FE_SHARED_LIB=false FE_EXT_SHARED_LIB=false

1.3 Build system dependencies

1.4 Build under MS Windows

To build Ferry under MS Windows platform you need to use one of these environments: UnxUtils (, Cygwin ( or MSYS ( Both Cygwin and MSYS are reliable though rather slow. UnxUtils is fast, but buggy: build occasionally fails due to internal errors and should be manually restarted many times to finally succeed. MinGW's interactive shell is not convenient enough (strongly IMHO), so the preferable choice is to use Cygwin.

1.4.1 Cygwin Cygwin installation

Download and run Select the following extra packages in addition to the default package set:

If you plan to build Ferry documentation in Cygwin, i.e. use Doxygen tool, make sure that build system hooks up non-cygwin doxygen.exe otherwise build will fail. See doxydoc target.

Cygwin imports MinGW headers/libs, so it has a bug in /usr/include/w32api/mlang.h file. See MinGW and MSYS installation for bug description and proposed workaround. Cygwin usage

Run cygwin.bat from your Cygwin install directory to start interactive shell.

At this point you can run $FERRY/fe/build/

1.4.2 UnxUtils UnxUtils installation

Assume the root directory for UnxUtils installation is referenced with UU_ROOT label.

Download and unzip to $UU_ROOT directory.

Download and unzip to $UU_ROOT/usr/local/wbin directory. UnxUtils usage

Run $UU_ROOT/bin/sh.exe to start interactive shell.

Update PATH environment variable:

export PATH=`pwd`';'`pwd`/../usr/local/wbin';'$PATH

At this point you can run $FERRY/fe/build/

1.4.3 MinGW and MSYS

This section covers installation and use of MinGW tools under MSYS environment.

Ferry is proved to build successfully with MinGW v5.1.4 and MSYS v1.0.10. MinGW and MSYS installation

Assume the root directory for MinGW installation is referenced with MGW_ROOT label.

Go to page and download appropriate MinGW and MSYS installers.

Run MinGW installer (MinGW-5.1.4.exe) first. Ensure you get $MGW_ROOT/MinGW directory created.

The default $MGW_ROOT/MinGW/include/mlang.h has wrong IMLangFontLink interface declaration causing the following compilation error:

/fe/src/win32/fe/ui/fonts.cxx: In member function `HFONT__* fe::Fonts::Iterator::FontBuilder<Type>::create(fe::Fonts::Iterator::LogFont) [with int Type = 4]':
/fe/src/win32/fe/ui/fonts.cxx:438: error: invalid conversion from `HFONT__*' to `WCHAR'
/fe/src/win32/fe/ui/fonts.cxx:438: error: initializing argument 3 of `virtual HRESULT IMLangFontLink::MapFont(HDC__*, DWORD, WCHAR, HFONT__**)'
make[1]: *** [/bldroot/mingw/obj/fe/ui/fonts.o] Error 1

The bugreport was submitted ( Until the bug is fixed the simple workaround is to apply the following patch:

--- mlang.h.orig    2007-12-27 17:12:47.001000000 +0300
+++ mlang.h 2008-07-21 19:18:37.203125000 +0400
@@ -239,9 +239,9 @@
         STDMETHOD(CodePageToCodePages)(THIS_ UINT,DWORD*) PURE;
         STDMETHOD(ReleaseFont)(THIS_ HFONT) PURE;
-        STDMETHOD(ResetFontMapping)(THIS) PURE;
+        STDMETHOD(ResetFontMapping)(THIS) PURE;

Run MSYS installer (MSYS-1.0.10.exe). When the console window with prompts appears, answer 'y' when appropriate and finally specify MinGW installation directory - $MGW_ROOT/MinGW. Ensure you get $MGW_ROOT/msys/1.0 directory created.

MSYS v1.0.10 includes obsolete version of GNU Make. Download recent version of this tool from the link. Just replace the default $MGW_ROOT/msys/1.0/bin/make.exe with the binary extracted from the downloaded archive.

MSYS v1.0.10 includes obsolete version of 'sed' utility. To build Ferry successfully you need sed v4.0.0 or higher. You can grab one from GnuWin32 ( project. Go to page, download and install appropriate binary.

Set PATH environment variable in $MGW_ROOT/msys/1.0/etc/profiles file so that MSYS hook up updated sed instead of the default one every time it is started. Say, sed is installed in c:/GnuWin32 directory, then append the following line to the $MGW_ROOT/msys/1.0/etc/profiles file:

export PATH="/c/GnuWin32/bin:$PATH"

Run $MGW_ROOT/msys/1.0/msys.bat to start interactive shell. Type

sed --version

to check if you updated $MGW_ROOT/msys/1.0/etc/profiles properly.

Disable $MGW_ROOT/msys/1.0/rxvt.exe as it causes problems when running console applications that do console I/O from multiple threads (binary built with fe/fe/fe_test make target is of that kind). You can rename it into $MGW_ROOT/msys/1.0/rxvt.exe.disabled or just delete the binary. MinGW and MSYS usage

Run $MGW_ROOT/msys/1.0/msys.bat to start interactive shell.

At this point you can run $FERRY/fe/build/