Tag Archives: cross compiling

Using crosstool-ng and Cygwin

My goal is to cross compile on Cygwin (on Winderz) for a Linux target – both 64 bit Ubuntu 13.10 or an ARM (such as a Beagle Bone). I sadistically thought that this could be done in MinGW.  Two words: Um, oops.

The real purpose is to take a Windows GUI that generates C code and compile it for a different platform (hence cross compiling).  These are my steps which are based on this guy’s post.

Note that as information on the web becomes quickly out of date, realize that this is the end of March in 2014.

  1. Before you begin, it is imperative to set your file system to be case sensitive in Windows.  Both the kernel headers and C library use file names with the same case insensitive name but different case sensitive name.  Open regedit.exe and set the following to 0.
    HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\kernel\obcaseinsensitive

    Then reboot.

  2. Download and Cygwin from here.  We will assume that you installed it on C:\cygwin.  I am using the Cygwin 2.844 32 bit version as the compiler being built because it will run on 32 bit or 64 bit Windows.
  3. When you run setup, you will get a nice GUI to choose your packages.  If you ever want to add or remove a package, you run setup again (seems counter-intuitive on Windows).  Take the defaults and add the following packages (not all may be required but it didn’t hurt).
      • Devel/gperf
      • Devel/bison
      • Devel/flex
      • Devel/patch
      • Devel/make: The GNU version…
      • Devel/automake
      • Devel/libtool
      • Devel/subversion
      • Devel/gcc-core
      • Devel/gcc-g++
      • Devel/catgets
      • Web/wget
      • Libs/libncursesw-devel
      • Libs/libncurses-devel
      • Libs/gettext
      • Libs/libexpat-devel
  4. Open up your cygwin terminal.  If you have a shortcut on your desktop or in your start menu, use that.  If not, the shortcut contains the following target:
    c:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -
  5. In the terminal, download and build crosstool-ng following the steps here.  Substitute your version.  There are listed below with my version and some other things I did.
    wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.19.0.tar.bz2
    tar xjf crosstool-ng-1.19.0.tar.bz2
    cd crosstool-ng-1.19.0
    ./bootstrap
    ./configure --prefix=/home/maks/crosstool
  6. There is one issue with curses.  In crosstool-ng-1.19.0/kconfig/nconf.c, there is the line “ESCDELAY = 1;”.  Swap this line with “set_escdelay(1);”  (A patch for this is listed here.  I did not apply the other two patches and had success building.)
  7. After making the previous correction,  we can make and install.
    make
    make install
  8. To make life easier, export your path to include /home/maks/crosstool/bin substituting your home directory.  I added this to my .bashrc so I wouldn’t have to think about it again.
    export PATH="${PATH}:/home/maks/crosstool/bin"
  9. This is where the patching begins.  Do the following.
    mkdir /usr/include/linux
    cp /usr/include/asm/types.h /usr/include/linux

    Then edit /usr/include/linux/types.h and include the following:

    typedef __signed__ long long __s64;
    typedef unsigned long long __u64;
  10. Make a new directory.  Since I wanted a 64 bit compiler for Linux, I did the following.  Adding the src directory seemingly allows the tarballs to be saved.  (This is not used and seems like a bug in the scripts.)  
  11. mkdir ~/src
    mkdir ~/linux64
    cd ~/linux64
    ct-ng i686-nptl-linux-gnu
    ct-ng menuconfig
  12. In menuconfig, I updated everything to the latest compiler, libraries, 64 bit, eglibc (which Ubuntu uses), etc.  If you want to cheat with menuconfig, use my config.  Simply copy the text into a .config file in the linux64 directory.
  13. You can start building with the following.  I recommend that you read the remainder of the post first.  These are tips that may help out.
    ct-ng build
  14. While building the kernel headers, I came to realize that Cygwin doesn’t have enough elf headers to be successful.  I applied the patch found here.  Make sure the patch applies correctly.  I had some issues.  Also, I had to edit /usr/include/sys/elf_common.h so that R_X86_64_JMP_SLOT was spelled R_X86_64_JUMP_SLOT (only that define).
  15. It turns out that for the latest kernel, a new version of make is needed than what comes with Cygwin.  In menuconfig, add make to the list of companion tools.
  16. Make sure you are not trying to build anything statically.  The final build of the compiler will not succeed.
  17. When you get passed installation of first pass of gcc, you are probably well on your way.  It will take around 2 to 3 hours to fully compile.  You may want to turn off anti-virus protection during this time.
  18. If you come across errors, you can restart ct-ng building where it left off by selecting “Paths and misc options / Debug crosstool-NG / Save intermediate steps.  Then to restart, run
    ct-ng list-steps
    ct-ng <last successful step name>+
  19. I never got D.U.M.A to actually build.  I lost patience trying to figure it out.  However, I never really needed a memory overrun checker in my case.

So that is that.  I compiled a C and C++ program on Windows and ran the binaries on Linux 64 bit Ubuntu 13.10.