I do most of my software development on Linux. Since my employer is a Windows shop, most of the software I write must run on Windows. Since I use cross-platform libraries (like Boost or Qt), I can still do most of my development work on Linux. Unfortunately, at some point, I need to move to Windows to compile and test the software.

On Linux, I mainly use Vim with tmux. I am very familiar with those tools. I have my tmux sessions, windows and panels set up just the way I like them. I also have fully configured my Vim plugins and key bindings. I really would like to keep using these tools and my workspace configuration when coding on Windows. And I can by using Cygwin.

According to Wikipedia:

Cygwin is a POSIX-compatible environment that runs natively on Microsoft Windows. Its goal is to allow programs of Unix-like systems to be recompiled and run natively on Windows with minimal source code modifications by providing them with the same underlying POSIX API they would expect in those systems. 1

Cygwin is a great tool. I can use Vim and tmux without any problem. All the plugins and configuration files I used on Linux work flawlessly on Cygwin.

In my work, I have access to multiple computers. I want to use Cygwin on all of them so I can have access to all my development tools. The problem is that Cygwin can be long and tedious to install and configure. I would like a version that can be run from a USB drive.

There are many projects on GitHub that hack on a local Cygwin installation to make it portable. Some of them are quite old and look abandoned. Some others I find too complex for my needs. So here is my own hack to make Cygwin portable.

Install Cygwin to your hard drive. It does not matter to which directory you install it. Here, I chose to install it to c:CygwinX86.

Cygwin Root Install Dir

Set the local package directory location to a subdirectory of the installation directory. Here, I use the packages subdirectory.

Cygwin Packages Install Dir

Follow the installation procedure to the end. There is no other special care to take during the installation process.

Once the installation procedure is complete, add a batch file named PortableCygwin.bat 2 to the Cygwin root directory.

Cygwin Portable Batch File

The file should contain the following lines:

@echo off
"%~dp0\bin\mintty.exe" -i /Cygwin-Terminal.ico -

This file will start the Cygwin terminal from whichever directory it is installed on.

Cygwin will create a home folder using the current Windows user name. My user name changes from computer to computer. This means that the name of my home folder will also change from computer to computer. We thus need to set a fix home folder to make our installation more portable. This can be easily accomplished by editing the /etc/nsswitch.conf file, uncommenting the db-home line and setting its value to a fixed path:

# /etc/nsswitch.conf
#
#    This file is read once by the first process in a Cygwin process tree.
#    To pick up changes, restart all Cygwin processes.  For a description
#    see https://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-mapping-nsswitch
#
# Defaults:
# passwd:   files db
# group:    files db
# db_enum:  cache builtin
db_home:  /home/foo
# db_shell: /bin/bash
# db_gecos: <empty>

In the above case, Cygwin will always set the home directory to /home/foo. Restart your terminal and check that your home directory has the expected path.

$ cygpath -w ~
c:\CygwinX86\home\foo

We need to register the proper path to the local package directory. This path is recorded in the /etc/setup/setup.rc file.

last-cache
        c:\CygwinX86\packages
mirrors-lst
        http://cygwin.mirror.constant.com/;cygwin.mirror.constant.com;United States;New Jersey
        http://cygwin.mirror.hoobly.com/;cygwin.mirror.hoobly.com;United States;Pennsylvania
        http://mirrors.koehn.com/cygwin/;mirrors.koehn.com;United States;Missouri
        http://mirrors.metapeer.com/cygwin/;mirrors.metapeer.com;United States;Washington
        ...

We need to replace the second line with the path to the local package directory on our USB key. Adding the following line to your .profile file will do the trick.

sed -i '2s|.*|\t'$(cygpath -m /)'/packages|' /etc/setup/setup.rc

It is important to specify the proper subdirectory in the command. Here we specified packages since this is the subdirectory we used during installation earlier. Now, every time we start Cygwin, the .profile file will be run and the setup.rc file will be updated with the actual path to the local package directory.

Finally, copy the whole installation directory anywhere on your USB drive. Use the PortableCygwin.bat file to start Cygwin and enjoy your portable POSIX experience.

  1. https://en.wikipedia.org/wiki/Cygwin
  2. You can of course name it any way you like.