Windows下使用Cygwin交叉编译libftdi 1.3

因为linux虚拟机挂了,编译软件不方便,另外编译openocd前也需要先编译libftdi,否则编译后的openocd不支持ftdi设备。所以尝试在Windows使用Cygwin来编译libftdi 1.3.

网上也找到一些关于Windows下编译libftdi的文章,不过好像都是编译libftdi的早期版本。采用./configure方式进行配置的,现在的1.3版,已经不存在./configure文件,需要使用cmake进行编译配置。

准备工作:

  • 一个正常运行的Windows 系统 (至少Vista,Cygwin已经停止对XP的支持了)
  • 可以启动起来的Cygwin或者Cygwin64 (本人用的Cygwin64)
  • Cygwin中安装基础工具(make,cmake,autoconf,automake,gcc,mingw,pkg-config,libusb,基于mingw的boost,etc. )
  • libftdi 源码包 https://www.intra2net.com/en/developer/libftdi/index.php
  • libusb 源码包 https://github.com/libusb/libusb/releases
  • 阅读 libftdi 源码包中的 README.mingw,查看额外的依赖项以及构建步骤

libftdi 1.3中的README.mingw文件内容:

* How to cross compile libftdi-1.x for Windows? *
   1 - Prepare a pkg-config wrapper according to
       https://www.flameeyes.eu/autotools-mythbuster/pkgconfig/cross-compiling.html ,
       additionally export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS and
       PKG_CONFIG_ALLOW_SYSTEM_LIBS.
   2 - Write a CMake toolchain file according to
       http://www.vtk.org/Wiki/CmakeMingw . Change the path to your future sysroot.
   3 - Get libusb sources (either by cloning the git repo or by downloading a
       tarball). Unpack, autogen.sh (when building from git), and configure like this:
       ./configure --build=`./config.guess` --host=i686-w64-mingw32 \
               --prefix=/usr --with-sysroot=$HOME/i686-w64-mingw32-root/
   4 - run
       make install DESTDIR=$HOME/i686-w64-mingw32-root/
   5 - go to libftdi-1.x source directory and run
       cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-mingw.cmake \
             -DCMAKE_INSTALL_PREFIX="/usr" \
             -DPKG_CONFIG_EXECUTABLE=`which i686-w64-mingw32-pkg-config`
   6 - run
       make install DESTDIR=$HOME/i686-w64-mingw32-root/

* How to run libftdi 1.x under Windows *

On 26-Jan-2014, libusbx and libusb project were merged with the release
of libusb-1.0.18 and now the project is called libusb.

libusb Windows backend will need to rely on a proper driver to run.
Please refer to the following wiki page for proper driver installation.
https://github.com/libusb/libusb/wiki/Windows#wiki-How_to_use_libusb_on_Windows

As of 26-Jan-2014, libusb Windows backend supports WinUSB,
libusb0.sys and libusbk.sys driver. However, libusb's support of
libusb0.sys and libusbk.sys is considered to be less mature than
WinUSB. Therefore, WinUSB driver installation using Zadig
is recommended.

Take note once you replace the original FTDI driver with WinUSB driver,
you can no longer use the functionality the original FTDI driver provides
(eg. Virtual Serial Port or D2XX).

 

  • 根据实际需要,选择合适的mingw交叉编译工具链(在Cygwin中安装),并且安装基于mingw的boost(同样也是在Cygwin中安装)。我选择的是x86_64-w64-mingw32(简单讲就是64位cygwin下的编译Windows x64二进制的工具链)。
  • 确认下mingw的目录下是否存在sysroot目录 (默认cygwin所在的目录为根目录,检查/usr/x86_64-w64-mingw32/sys-root是否存在并且不为空),并且基于mingw的boost已正确安装(sysroot目录下是否存在mingw/include/boost目录)。

编译步骤:

  • 根据README.mingw中第1步中的链接,建立一个pkg-config的封装器。文件名需要改成工具链名-pkg-config。例如: x86_64-w64-mingw32-pkg-config。并把该文件放到libftdi源目录下。需要对示例脚本做些许修改。比如增加PKG_CONFIG_ALLOW_SYSTEM_CFLAGSPKG_CONFIG_ALLOW_SYSTEM_LIBS,以及设置正确的sysroot目录。我的x86_64-w64-mingw32-pkg-config文件内容如下:
    #!/bin/sh
    
    SYSROOT=/usr/x86_64-w64-mingw32/sys-root
    
    export PKG_CONFIG_DIR=
    export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig
    export PKG_CONFIG_SYSROOT_DIR=${SYSROOT}
    
    export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1
    export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
    
    exec pkg-config "$@"
    
    
    
  • 根据README.mingw中第2步的链接写一个cmake工具链文件,文件名可以自定义,这里为Toolchain-x86_64-w64-mingw32.cmake。该文件也放到libftdi源目录下。需要修改示例中的工具链前缀以及sysroot目录。我的cmake文件内容如下:
    # the name of the target operating system
    SET(CMAKE_SYSTEM_NAME Windows)
    
    # which compilers to use for C and C++
    SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
    SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
    set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
    
    # here is the target environment located
    SET(CMAKE_FIND_ROOT_PATH  /usr/x86_64-w64-mingw32/sys-root )
    
    # adjust the default behaviour of the FIND_XXX() commands:
    # search headers and libraries in the target environment, search 
    # programs in the host environment
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    
  • 根据README.mingw中第3步,解包libusb源码,进入源目录。如果是git版(存在autogen.sh文件)则先执行autogen.sh。然后执行命令:
    ./configure --build=`./config.guess` --host=x86_64-w64-mingw32 --prefix=/usr --with-sysroot=/usr/x86_64-w64-mingw32/sys-root

    其中–host改成当前使用的工具链,–with-sysroot改成上面的sysroot目录。

  • 根据README.mingw中第4步,在libusb源目录执行命令:
    make install DESTDIR=/usr/x86_64-w64-mingw32/sys-root

    其中DESTDIR改成上面的sysroot目录。

  • 根据README.mingw中第5步,切换到libftdi源目录,执行命令:
    cmake -DCMAKE_TOOLCHAIN_FILE=Toolchain-x86_64-w64-mingw32.cmake -DCMAKE_INSTALL_PREFIX="/usr" -DPKG_CONFIG_EXECUTABLE=`which x86_64-w64-mingw32-pkg-config`

    其中DCMAKE_TOOLCHAIN_FILE是第1步建立的工具链cmake文件名;DPKG_CONFIG_EXECUTABLE参数里which后面的内容是第1步建立的pkg-config封装器文件名。

  • 根据README.mingw中第6步,在libftdi源目录执行命令:
    make install DESTDIR=/usr/x86_64-w64-mingw32/sys-root

    同第4步,DESTDIR改成上面的sysroot目录。如果构建成功的话,终端中应该可以看到如下信息:

    Install the project...
    -- Install configuration: "RelWithDebInfo"
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/lib/pkgconfig/libftdi1.pc
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/lib/pkgconfig/libftdipp1.pc
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/bin/libftdi1-config
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/lib/cmake/libftdi1/LibFTDI1Config.cmake
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/lib/cmake/libftdi1/LibFTDI1ConfigVersion.cmake
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/lib/cmake/libftdi1/UseLibFTDI1.cmake
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/lib/libftdi1.dll.a
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/bin/libftdi1.dll
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/lib/libftdi1.a
    -- Installing: /usr/x86_64-w64-mingw32/sys-root/usr/include/libftdi1/ftdi.h