ioFTPD Development Environment Setup

This document describes how to reproduce the exact development environment used to build ioFTPD v7.10+, including all required tools, libraries, and build steps.


Table of Contents

  1. Directory Structure
  2. Prerequisites
  3. Build OpenSSL 3.6.1
  4. Build Tcl 9.0.2
  5. Build TclTLS (trunk)
  6. Build ioFTPD
  7. Post-Build Deployment
  8. Crash Analysis Tools (Optional)

Directory Structure

The build system expects the following layout. Create these directories before starting:

C:\Dev\
  Tools\
    nasm-2.15.05\      — NASM assembler (required for OpenSSL AES-NI)
    fossil\            — Fossil SCM binary (required for TclTLS checkout)
    Python314\         — Python 3.14 (optional; not required for ioFTPD build)
  Sources\
    openssl-3.6.1\     — OpenSSL source (extracted from tarball)
    tcl9.0.2\          — Tcl 9.0.2 source (extracted from tarball)
    tcltls-trunk\      — TclTLS (Fossil checkout; created during setup)
    ioFTPD\            — ioFTPD source (git clone)
  Libs\
    VS2022\
      x86\
        OpenSSL\Shared\Release\   — OpenSSL 32-bit headers + libs
        TCL\Shared\Release\       — Tcl 32-bit headers + libs
      x64\
        OpenSSL\Shared\Release\   — OpenSSL 64-bit headers + libs (x64 build only)
        TCL\Shared\Release\       — Tcl 64-bit headers + libs (x64 build only)

Prerequisites

Install all tools before proceeding to the library builds.

1. Visual Studio 2022 Community

Required for the MSVC compiler (v143 toolset) and Windows SDK.

Download: https://visualstudio.microsoft.com/vs/community/

During installation, select:

ioFTPD ships both Win32 (x86) and x64 (AMD64) binaries from v8.0. The x64 Native Tools are required if you intend to build the x64 configuration. For Win32-only builds the x64 toolset is not required but does not cause harm.

The project files pin <VCToolsVersion>14.44.35207</VCToolsVersion> (the toolset version that includes MFC) to prevent MSBuild from selecting an older installed toolset where MFC may be absent. If you install a newer VS 2022 update that ships a later compiler, update this version number in all six .vcxproj files or remove the pin to let MSBuild use the latest installed.

2. NASM 2.15.05

Required by OpenSSL’s Configure script for AES-NI assembly optimizations. Without NASM the build will fail during the asm generation step.

Download: https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/win32/nasm-2.15.05-installer-x86.exe

Install to: C:\Dev\Tools\nasm-2.15.05\

Do not add NASM to the system PATH — the build scripts add it temporarily.

3. Strawberry Perl

Required by OpenSSL’s Configure script and by the TclTLS header-generation step in Build TclTLS.bat.

Download: https://strawberryperl.com/

Install using the default installer. Strawberry Perl adds itself to the system PATH automatically. Verify after install:

perl --version

4. Fossil 2.27

Required to check out the TclTLS trunk repository.

Download: https://www.fossil-scm.org/home/uv/download.html (get the Win32 binary, fossil.exe)

Place fossil.exe at: C:\Dev\Tools\fossil\fossil.exe

5. Git

Required to clone the ioFTPD source repository.

Download: https://git-scm.com/download/win

Use the default installer options. Git adds itself to the system PATH.


Build OpenSSL 3.6.1

OpenSSL provides the TLS/SSL layer (libssl-3.dll, libcrypto-3.dll) and headers used by both ioFTPD and TclTLS.

3a. Download and extract source

Download the 3.6.1 tarball from: https://github.com/openssl/openssl/releases/tag/openssl-3.6.1

Extract to: C:\Dev\Sources\openssl-3.6.1\

3b. Run the build script

A ready-made build script is at C:\Dev\Sources\Build OpenSSL 3.6.1.bat. Double-click it from Explorer or run it from a plain cmd.exe prompt (not a VS Developer Command Prompt — the script loads vcvars32.bat itself):

cd C:\Dev\Sources
"Build OpenSSL 3.6.1.bat"

The script:

  1. Loads the VS 2022 x86 build environment (vcvars32.bat)
  2. Adds NASM to PATH
  3. Runs perl Configure VC-WIN32 shared --prefix=C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release
  4. Runs nmake (build)
  5. Runs nmake install (copies headers, libs, and DLLs to the prefix)

3c. Copy the legacy provider

After the build completes, copy the legacy provider module to the ioFTPD system\ directory (needed for DHE-RSA / AES-CBC FXP compatibility):

C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release\lib\ossl-modules\legacy.dll
  → C:\ioFTPD\system\lib\ossl-modules\legacy.dll

Resulting layout

C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release\
  bin\
    libssl-3.dll
    libcrypto-3.dll
    openssl.exe
  include\openssl\   (headers)
  lib\
    libssl.lib
    libcrypto.lib
    ossl-modules\
      legacy.dll
      legacy.pdb

Build Tcl 9.0.2

Tcl provides the scripting engine (tcl90.dll) that ioFTPD embeds for server-side event hooks.

No source patches are required for Tcl 9.0.2. The official unmodified tarball builds cleanly with ioFTPD.

4a. Download and extract source

Download from: https://www.tcl.tk/software/tcltk/download.html (choose tcl9.0.2-src.tar.gz or the equivalent .zip)

Extract to: C:\Dev\Sources\tcl9.0.2\

4b. Build (Release)

Open a VS 2022 x86 Native Tools Command Prompt (found in the Start menu under Visual Studio 2022), then:

cd C:\Dev\Sources\tcl9.0.2\win

nmake -f makefile.vc OPTS=threads INSTALLDIR=C:\Dev\Libs\VS2022\x86\TCL\Shared\Release release
nmake -f makefile.vc OPTS=threads INSTALLDIR=C:\Dev\Libs\VS2022\x86\TCL\Shared\Release install

4c. Build (Debug — optional)

nmake -f makefile.vc OPTS=threads,symbols INSTALLDIR=C:\Dev\Libs\VS2022\x86\TCL\Shared\Debug release
nmake -f makefile.vc OPTS=threads,symbols INSTALLDIR=C:\Dev\Libs\VS2022\x86\TCL\Shared\Debug install

Resulting layout

C:\Dev\Libs\VS2022\x86\TCL\Shared\Release\
  bin\
    tcl90.dll
    tclsh90.exe
  include\   (headers: tcl.h, tclDecls.h, etc.)
  lib\
    tcl90.lib
    tcl9.0\  (standard library scripts)

Build TclTLS (trunk)

TclTLS is the OpenSSL TLS extension for Tcl. ioFTPD loads it as a Tcl package to support STARTTLS and other TLS operations from Tcl scripts.

5a. Check out the repository

From a plain cmd.exe prompt:

cd C:\Dev\Sources
fossil clone https://core.tcl-lang.org/tcltls tcltls.fossil
mkdir tcltls-trunk
cd tcltls-trunk
fossil open ..\tcltls.fossil

This checks out the latest trunk into C:\Dev\Sources\tcltls-trunk\.

5b. Fix the makefile (required)

Open C:\Dev\Sources\tcltls-trunk\win\makefile.vc in any text editor.

Find this line:

TCLSH = "$(_INSTALLDIR)\..\bin\tclsh.exe"

Replace it with the explicit path to the installed Tcl 9.0 shell:

TCLSH = "C:\Dev\Libs\VS2022\x86\TCL\Shared\Release\bin\tclsh90.exe"

Without this fix the makefile attempts to call a non-existent tclsh.exe and the header-generation step will fail.

5c. Run the build script

A ready-made build script is at C:\Dev\Sources\Build TclTLS.bat. Run it from a plain cmd.exe prompt (the script loads vcvars32.bat itself):

cd C:\Dev\Sources
"Build TclTLS.bat"

The script:

  1. Loads VS 2022 x86 build environment
  2. Generates generic\dh_params.h using openssl dhparam 2048
  3. Generates generic\tls.tcl.h from library\tls.tcl using Perl
  4. Runs nmake -f makefile.vc TCLDIR=... SSL_INSTALL_FOLDER=...
  5. Runs nmake install into C:\Dev\Libs\VS2022\x86\TCL\Shared\Release\lib\

5d. Manual build (alternative)

If you prefer to run the steps manually from a VS 2022 x86 Native Tools Command Prompt:

REM Generate headers
cd C:\Dev\Sources\tcltls-trunk\generic
openssl dhparam 2048 | findstr /V /C:"--" > dh_params.h
perl -ne "chomp; @c=unpack('C*', $_); print join(', ', map { sprintf('0x%02x', $_) } @c), qq{, 0x0a, \n};" ^
    < ..\library\tls.tcl > tls.tcl.h

REM Build
cd ..\win
nmake -f makefile.vc ^
    TCLDIR=C:\Dev\Libs\VS2022\x86\TCL\Shared\Release ^
    SSL_INSTALL_FOLDER=C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release ^
    TCLSH_PROG=C:\Dev\Libs\VS2022\x86\TCL\Shared\Release\bin\tclsh90.exe ^
    MACHINE=IX86

REM Install
nmake -f makefile.vc install ^
    TCLDIR=C:\Dev\Libs\VS2022\x86\TCL\Shared\Release ^
    INSTALLDIR=C:\Dev\Libs\VS2022\x86\TCL\Shared\Release\lib ^
    SSL_INSTALL_FOLDER=C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release

Build OpenSSL 3.6.1 (x64) — required for x64 ioFTPD

This step is only required if you intend to build the x64 configuration. The x64 OpenSSL libraries are installed to a separate prefix so they coexist with the x86 libraries built above.

x64-a. Open x64 Native Tools Command Prompt

From the Start menu, open VS 2022 x64 Native Tools Command Prompt (not the x86 prompt — using the wrong prompt will silently produce a 32-bit build).

x64-b. Configure and build

cd C:\Dev\Sources\openssl-3.6.1

REM Clean any x86 artifacts first
nmake clean

perl Configure VC-WIN64A shared ^
    --prefix=C:\Dev\Libs\VS2022\x64\OpenSSL\Shared\Release
nmake
nmake install

x64-c. Resulting layout

C:\Dev\Libs\VS2022\x64\OpenSSL\Shared\Release\
  bin\
    libssl-3.dll       (AMD64)
    libcrypto-3.dll    (AMD64)
  include\openssl\     (same headers as x86 — no separate copy needed)
  lib\
    libssl.lib
    libcrypto.lib
    ossl-modules\
      legacy.dll       (AMD64)

Build Tcl 9.0.2 (x64) — required for x64 ioFTPD

This step is only required for the x64 configuration.

x64-d. Build in x64 Native Tools Command Prompt

cd C:\Dev\Sources\tcl9.0.2\win

nmake -f makefile.vc MACHINE=AMD64 OPTS=threads ^
    INSTALLDIR=C:\Dev\Libs\VS2022\x64\TCL\Shared\Release release

nmake -f makefile.vc MACHINE=AMD64 OPTS=threads ^
    INSTALLDIR=C:\Dev\Libs\VS2022\x64\TCL\Shared\Release install

x64-e. Resulting layout

C:\Dev\Libs\VS2022\x64\TCL\Shared\Release\
  bin\
    tcl90.dll          (AMD64)
    tclsh90.exe        (AMD64)
  include\             (headers — same as x86, already installed)
  lib\
    tcl90.lib
    tcl9.0\

TclTLS x64: follow the same steps as the x86 TclTLS build but use the x64 Native Tools prompt and point TCLDIR / SSL_INSTALL_FOLDER at the x64 library directories above.


Build ioFTPD

6a. Clone the repository

cd C:\Dev\Sources
git clone <repository-url> ioFTPD

6b. Open the solution

Open C:\Dev\Sources\ioFTPD\ioFTPD-v7.sln in Visual Studio 2022.

The project already has the correct include and library paths configured:

If your paths differ, update AdditionalIncludeDirectories and AdditionalLibraryDirectories in the project properties.

6c. Build configurations

Configuration Output binary Notes
Release\|Win32 system\ioFTPD.exe Optimised 32-bit production build
Release\|x64 system\x64\ioFTPD.exe Optimised 64-bit production build
Debug\|Win32 system\ioFTPD-debug.exe No optimisation, debug CRT (32-bit)
Purify\|Win32 system\ioFTPD.exe Debug + /RTC1 runtime checks (32-bit)

From the command line (recommended for CI):

REM Win32 build
"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" ^
    "C:\Dev\Sources\ioFTPD\ioFTPD-v7.sln" ^
    /p:Configuration=Release /p:Platform=Win32 ^
    /t:Build /m /nologo

REM x64 build (requires x64 libraries to be built first — see above)
"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" ^
    "C:\Dev\Sources\ioFTPD\ioFTPD-v7.sln" ^
    /p:Configuration=Release /p:Platform=x64 ^
    /t:Build /m /nologo

Post-Build Deployment

After building, copy the required runtime files to the ioFTPD system\ directory.

DLLs

REM OpenSSL
copy C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release\bin\libssl-3.dll   C:\ioFTPD\system\
copy C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release\bin\libcrypto-3.dll C:\ioFTPD\system\

REM Tcl runtime
copy C:\Dev\Libs\VS2022\x86\TCL\Shared\Release\bin\tcl90.dll           C:\ioFTPD\system\

REM OpenSSL legacy provider (for DHE-RSA / AES-CBC FXP compatibility)
mkdir C:\ioFTPD\system\lib\ossl-modules
copy C:\Dev\Libs\VS2022\x86\OpenSSL\Shared\Release\lib\ossl-modules\legacy.dll ^
     C:\ioFTPD\system\lib\ossl-modules\

Tcl standard library

xcopy /s /i /y ^
    C:\Dev\Libs\VS2022\x86\TCL\Shared\Release\lib\tcl9.0 ^
    C:\ioFTPD\system\lib\tcl9.0

The encoding\ subdirectory is large. If startup time matters, only utf-8, iso8859-1, cp1252, and ascii encodings are required.

Runtime directory contents

At startup system\ must contain:

system\
  ioFTPD.exe
  libssl-3.dll
  libcrypto-3.dll
  tcl90.dll
  lib\
    ossl-modules\
      legacy.dll
    tcl9.0\         (Tcl standard library)
  ioFTPD.ini

Crash Analysis Tools (Optional)

WinDbg — Debugging Tools for Windows

Required to open .dmp minidump files generated by ioFTPD’s built-in crash handler (crash_YYYYMMDD_HHMMSS.dmp).

Download as part of the Windows SDK: https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/

Install path used in this environment: C:\Program Files\Debugging Tools for Windows\

Basic crash analysis workflow:

windbg -z crash_20260101_143022.dmp
.symfix
.reload
!analyze -v
!heap -p -a <faulting-address>

The WinDbg SDK include directory (sdk\inc) is referenced in the ioFTPD project for dbgeng.h / dbghelp.h. If WinDbg is not installed, remove that include path from the project properties and the build will still succeed (it is only used by IoDebug.c for symbol resolution).


Quick-Reference Build Order

Win32 build (same as before):
1.  Install VS 2022 Community (Desktop C++ workload, including x64 tools)
2.  Install Strawberry Perl          → verify: perl --version
3.  Install NASM 2.15.05 to C:\Dev\Tools\nasm-2.15.05\
4.  Install Fossil to C:\Dev\Tools\fossil\fossil.exe
5.  Install Git
6.  Download & extract OpenSSL 3.6.1 → C:\Dev\Sources\openssl-3.6.1\
7.  Download & extract Tcl 9.0.2     → C:\Dev\Sources\tcl9.0.2\
8.  Run (x86 prompt): "Build OpenSSL 3.6.1.bat"
9.  Run (VS x86 prompt): nmake for Tcl 9.0.2  (release + install)
10. Fossil clone TclTLS trunk        → C:\Dev\Sources\tcltls-trunk\
11. Edit tcltls-trunk\win\makefile.vc (fix TCLSH path)
12. Run: "Build TclTLS.bat"
13. git clone ioFTPD
14. MSBuild ioFTPD-v7.sln /p:Configuration=Release /p:Platform=Win32
15. Copy Win32 DLLs and Tcl lib tree to system\

Additional steps for x64 build:
16. Run (VS x64 prompt): perl Configure VC-WIN64A ... && nmake && nmake install
    (OpenSSL x64 → C:\Dev\Libs\VS2022\x64\OpenSSL\Shared\Release)
17. Run (VS x64 prompt): nmake MACHINE=AMD64 for Tcl 9.0.2 (release + install)
    (Tcl x64 → C:\Dev\Libs\VS2022\x64\TCL\Shared\Release)
18. MSBuild ioFTPD-v7.sln /p:Configuration=Release /p:Platform=x64
19. Copy x64 DLLs and Tcl lib tree to system\x64\