Ilija Matoski

    ← Articles

    Building lftp on Windows

    One of the best FTP clients I have ever seen is lftp, and what is even best it's open source on Linux, if you want to use it on Windows you will have to compile it with Cygwin.

    One of the best FTP clients I have ever seen is lftp, and what is even best it’s open source on Linux, if you want to use it on Windows you will have to compile it with Cygwin.

    Why would someone use lftp, when there are alternatives like FileZilla, and a lot of other ones. Yes FileZilla is good and it’s free, but some of the options that are available with lftp are really good and helpful. And I know of a lot of people that use lftp for server backups on Windows Server and Linux machines to do recursive backups and mirroring.

    For a complete feature list you can see this page.

    Some interesting information about this application can be found on this page, there are various examples of how to use it on their page.

    If you want to learn how to compile it on Windows, read bellow, or if you are just interested in the compiled version you can download it bellow, the following builds are built on Cygwin x86x64, also bundled in the package is SSH and BASH. If you have Cygwin installation you can just unpack this file in the root, and you are set.

    At the bottom of the post you will find a script that was used to build these packages for anyone who want

    So first things first, download the latest version of lftp, and unpack it somewhere where you can access it, in my case I uncompressed it in my home directory, so at the time of writing the latest version is 4.4.9.

    Here are some of the perquisites for compiling the application successfully on Cygwin.

    In short you need the following packages for you to be able to compile lftp, for a more complete list of packages that I use to compile you can find them at the end of the post.

    bison, autoconf, gcc, gcc-c++, make, pkg-config, gnutls, gnutls-devel

    In the main directory we run:

    ./configure
    make

    So after compilation let’s check what support do we have in lftp:

    lftp.exe --version

    It shows us that we are using: Readline 6.2, Expat 2.1.0, GnuTLS 3.2.0, libiconv 1.14, zlib 1.2.8

    ldd.exe lftp.exe | grep --invert-match Windows

    This shows you all the dependencies for the particular executable, in our case it shows the following.

    ldd.exe lftp.exe | grep --invert-match Windows
    cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000)
    cygexpat-1.dll => /usr/bin/cygexpat-1.dll (0x3ff980000)
    cyggnutls-28.dll => /usr/bin/cyggnutls-28.dll (0x3ff590000)
    cyggmp-10.dll => /usr/bin/cyggmp-10.dll (0x3ff690000)
    cyghogweed-2.dll => /usr/bin/cyghogweed-2.dll (0x3ff4d0000)
    cygnettle-4.dll => /usr/bin/cygnettle-4.dll (0x3ff0e0000)
    cygiconv-2.dll => /usr/bin/cygiconv-2.dll (0x3ff3c0000)
    cygintl-8.dll => /usr/bin/cygintl-8.dll (0x3ff360000)
    cygp11-kit-0.dll => /usr/bin/cygp11-kit-0.dll (0x3ff0a0000)
    cygffi-6.dll => /usr/bin/cygffi-6.dll (0x3ff970000)
    cygtasn1-6.dll => /usr/bin/cygtasn1-6.dll (0x3feba0000)
    cygz.dll => /usr/bin/cygz.dll (0x3feb40000)
    cygreadline7.dll => /usr/bin/cygreadline7.dll (0x3fede0000)
    cygncursesw-10.dll => /usr/bin/cygncursesw-10.dll (0x3ff120000)
    cyggcc_s-seh-1.dll => /usr/bin/cyggcc_s-seh-1.dll (0x3ff850000)

    If you want to compile with OpenSSL support do the following, because by default it doesn’t compile with OpenSSL support, instead it uses GnuTLS.

    ./configure --without-gnutls --with-openssl
    make

    So after compilation let’s check what support do we have in lftp:

    lftp.exe --version

    It shows us that we are using: Readline 6.2, Expat 2.1.0, OpenSSL 1.0.1e 11 Feb 2013, libiconv 1.14, zlib 1.2.8

    ldd.exe lftp.exe | grep --invert-match Windows

    This shows you all the dependencies for the particular executable, in our case it shows the following.

    ldd.exe lftp.exe | grep --invert-match Windows
    cygcrypto-1.0.0.dll => /usr/bin/cygcrypto-1.0.0.dll (0x3ffbf0000)
    cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000)
    cygz.dll => /usr/bin/cygz.dll (0x3feb40000)
    cygexpat-1.dll => /usr/bin/cygexpat-1.dll (0x3ff980000)
    cygiconv-2.dll => /usr/bin/cygiconv-2.dll (0x3ff3c0000)
    cygintl-8.dll => /usr/bin/cygintl-8.dll (0x3ff360000)
    cygreadline7.dll => /usr/bin/cygreadline7.dll (0x3fede0000)
    cygncursesw-10.dll => /usr/bin/cygncursesw-10.dll (0x3ff120000)
    cygssl-1.0.0.dll => /usr/bin/cygssl-1.0.0.dll (0x3fecc0000)
    cyggcc_s-seh-1.dll => /usr/bin/cyggcc_s-seh-1.dll (0x3ff850000)

    Long package list

    autoconf, automake, bison, bzip2, cygwin-debuginfo, cygwin32, cygwin32-expat, cygwin32-libiconv, expat, expat-debuginfo, gcc-core, gcc-fortran, gcc-g++, gnutls, gnutls-devel, libexpat-devel, libexpat1, libiconv, libiconv-debuginfo, libiconv-devel, libiconv2, libmhash-devel, libmhash2, libreadline-devel, libreadline7, make, mhash-debuginfo, mingw-binutils, mingw-gcc-core, mingw-pthreads, mingw-runtime, mingw-w32api, mingw-zlib, mingw-zlib-devel, mingw-zlib1, mingw64-x86_64-binutils, mingw64-x86_64-gcc-core, mingw64-x86_64-gcc-fortran, mingw64-x86_64-gcc-g++, mingw64-x86_64-headers, mingw64-x86_64-runtime, mingw64-x86_64-winpthreads, mingw64-x86_64-zlib, openssl, openssl-devel, perl, perl-ExtUtils-PkgConfig, pkg-config, pkg-config-debuginfo, python, python-crypto, python-crypto-debuginfo, python-openssl, python-openssl-debuginfo, python-tkinter, zlib-devel, zlib0

    Build and packaging script

    #!/bin/bash
    if [ $# -eq 0 ]
    then
    echo "<script> name"
    exit
    fi
    if [ ! -f lftp.exe ];
    then
    echo "lftp.exe doesn't exist run this file from where it exists"
    exit
    fi
    cwd=`pwd`
    items=`ldd.exe lftp.exe | grep --invert-match Windows | cut -d " " -f3`
    tmpdir=`mktemp.exe --directory`
    echo "Creating temporary directory $tmpdir"
    mkdir $tmpdir/bin
    mkdir $tmpdir/etc
    for item in $items
    do
    echo "Copying LFTP dependency file: $item to $tmpdir/bin"
    cp $item $tmpdir/bin
    done
    items=`ldd.exe /bin/ssh.exe | grep --invert-match Windows | cut -d " " -f3`
    for item in $items
    do
    echo "Copying SSH dependency file: $item"
    cp $item $tmpdir/bin
    done
    items=`ldd.exe /bin/bash.exe | grep --invert-match Windows | cut -d " " -f3`
    for item in $items
    do
    echo "Copying BASH dependency file: $item"
    cp $item $tmpdir/bin
    done
    echo "Copying required files"
    cp lftp.exe $tmpdir/bin
    cp ../lftp.conf $tmpdir/etc
    cp /bin/ssh.exe $tmpdir/bin
    cp /bin/bash.exe $tmpdir/bin
    cd $tmpdir
    tar -cvzf ../$1.tar.gz .
    mv ../$1.tar.gz $cwd
    cd $cwd
    echo "File generated in $cwd/$1.tar.gz"