目录

  1. 不用 MinGW,改用 Mingw-w64
  2. 不用 MSYS,改用 MSYS2
  3. 終端可選用 futtyConEmu

使用

  1. 安裝 Cygwin
  2. 安裝 futty
  3. 升級安裝包
  4. 一般會保留安裝包,之後可以透過命令行直接安裝已下載的套件。
    $ .\setup-x86_64.exe -P make flex bison automake pkg-config gettext-devel gcc-core mingw64-x86_64-gcc-core vim
  5. 不建議使用 Mingw32,改採用 Mingw64。於 Cygwin 欲使用 MinGW 交叉編譯,使用底下命令行。1)
    # System types:
    #  --build=BUILD     configure for building on BUILD [guessed]
    #  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
    $ ./configure --host=x86_64-w64-mingw32
    $ ./configure --host=i686-w64-mingw32

注意事項

移除 Cygwin

製作安裝包

  1. 安裝 cygport 和 gettext-devel。
  2. 撰寫 cygport 設定檔 (參考 hidapi.cygportmingw64-x86_64-hidapi.cygport)。
  3. 製作安裝包。
    # 下載源代碼和補丁。
    $ cygport hidapi fetch
    # 打包。
    $ cygport hidapi all
  4. 檢查安裝包內容。
    $ tar tvf hidapi.x86_64/dist/hidapi/libhidapi/libhidapi-hidapi-hidapi.tar.xz
    $ tar tvf hidapi.x86_64/dist/hidapi/libhidapi-devel/libhidapi-devel-hidapi-hidapi.tar.xz
  5. 測試安裝包。
    $ cd /
    $ tar xvf hidapi.x86_64/dist/hidapi/libhidapi/libhidapi-hidapi-hidapi.tar.xz
    $ tar xvf hidapi.x86_64/dist/hidapi/libhidapi-devel/libhidapi-devel-hidapi-hidapi.tar.xz
  6. 送審。
  7. 上傳套件。
    • 啟動 ssh-agent
      $ eval "$(ssh-agent -s)"
      $ ssh-add ~/.ssh/id_rsa
    • 登入伺服器 (不需要密碼)。
      # 當前目錄已存在欲上傳套件之目錄。
      $ lftp sftp://cygwin@cygwin.com
      lftp cygwin@cygwin.com:~> ls
      -rw-rw-rw-   1 cygwin   cygwin         53 Feb 11 01:40 !packages
      drwxrwxr-x   4 cygwin   cygstage     4096 Feb 10 16:10 .
      drwxrwsr-x  62 cygwin   cygstage     4096 Feb 10 16:10 ..
      drwxrwxr-x   3 cygwin   cygwin       4096 Feb 10 16:10 x86
      drwxrwxr-x   3 cygwin   cygwin       4096 Feb 10 16:10 x86_64
    • 設定郵件通知。
      # email 為本機端檔案,內存預收信的電郵地址。
      $ put email -o !email
    • 上傳套件。
      $ cd x86_64/release
      # 把本機端的 hidapi 上傳至 sftp。
      $ mirror -eR hidapi
      $ ls
      drwxrwxr-x   3 cygwin   cygwin       4096 Feb 11 01:54 .
      drwxrwxr-x   3 cygwin   cygwin       4096 Feb 10 16:10 ..
      drwxr-xr-x   5 cygwin   cygwin       4096 Feb 11 01:54 hidapi
      # 通知 upset 更新套件列表。
      $ put /dev/null -o !ready

編程相關

MSYS2

# 更新套件庫
$ pacman -Sy
$ pacman -S mingw-w64-x86_64-gcc
# 以 usb 關鍵字搜尋套件庫
$ pacman -Ss usb
# 安裝 mingw-w64-x86_64 版本的 openocd
$ pacman -S mingw64/mingw-w64-x86_64-openocd-git

內部實現

$ wget http://mirrors.163.com/cygwin/release/cygwin/cygwin-1.7.16-1-src.tar.bz2
$ tar xvf cygwin-1.7.16-1-src.tar.bz2
$ tar xvf winsup-1.7.16.tar.bz2
# src/winsup/cygwin 實現 cygwin1.dll。
# src/winsup/w32api 實現 w32 API。
$ cd src/winsup/cygwin
# 或是透過 CVS。目錄底下不可以有 src 目錄,避免下載不了。
# 會有 how-to 文件。
$ export CVSROOT=:pserver:anoncvs@cygwin.com:/cvs/src
$ cvs login
(Logging in to anoncvs@cygwin.com)
CVS password: anoncvs
$ cvs checkout winsup
$ mkdir build install; cd build
$ ../src/configure --prefix=$INSTALL --enable-debugging
$ make -j

a DLL (cygwin1.dll) which acts as a Linux API layer providing substantial Linux API functionality.

cygwin1.dll 是 Linux 內核在 Windows 上的實現,它使用 Win32 API 實現 POSIX 系統呼叫。

Because we are trying to emulate a UNIX kernel which needs access to all processes running under it, the first Cygwin DLL to run creates shared memory areas that other processes using separate instances of the DLL can access. This is used to keep track of open file descriptors and assist fork and exec, among other purposes. In addition to the shared memory regions, every process also has a per_process structure that contains information such as process id, user id, signal masks, and other similar process-specific information.

編譯 Cygwin

參考 Installing and Updating Cygwinsetup.exe 用來初次安裝 cygwin 和其它套件。請安裝新版 GCC 以編譯 Cygwin。

內部結構

  1. mainCRTStartup (src/winsup/cygwin/crt0.c)
  2. cygwin_crt0 (src/winsup/cygwin/lib/cygwin_crt0.c)
  3. dll_crt0 (cygwin/dcrt0.cc)
  4. dll_crt0_1 (winsup/cygwin/dcrt0.cc)
(gdb) dll cygwin1
(gdb) b dll_crt0_1

實現 fork

  1. fork (winsup/cygwin/fork.cc)
    extern "C" int
    fork ()
    {
      frok grouped;
     
      debug_printf ("entering");
      grouped.load_dlls = 0;
     
      int res;
      bool ischild = false;
     
      myself->set_has_pgid_children ();
     
      // 創建子進程。
      if (grouped.ch.parent == NULL)
        return -1;
     
      ... 略 ...
     
    }
  2. frok::parent (winsup/cygwin/fork.cc)
    int __stdcall
    frok::parent (volatile char * volatile stack_here)
    {
     
      while (1)
        {
          hchild = NULL;
          rc = CreateProcessW (myself->progname,  /* image to run */
             myself->progname,  /* what we send in arg0 */
             &sec_none_nih,
             &sec_none_nih,
             TRUE,    /* inherit handles from parent */
             c_flags,
             NULL,    /* environment filled in later */
             0,       /* use current drive/directory */
             &si,
             &pi);
     
          if (rc)
      debug_printf ("forked pid %u", pi.dwProcessId);
          else
      {
        this_errno = geterrno_from_win_error ();
        error ("CreateProcessW failed for '%W'", myself->progname);
        memset (&pi, 0, sizeof (pi));
        goto cleanup;
      }

Heap

實現 open

外部連結