Contents
Introduction
Requirements
Important Notes
Building a Cross-Compiler
Building a Crossed-Native Compiler
Building a Native Compiler
Further Reading
Change History

Introduction

This document describes the process that I used to build the GNU Compiler for Java (GCJ) for Windows using the Minimalist GNU for Windows (MinGW) toolkit. I had written this document to avoid having to individually answer frequent queries on this process as well as to encourage people to experiment with creating GCJ for Windows customised to their liking.

DISCLAIMER: These instructions and scripts were valid for building GCJ 4.2 for Windows. I do not know if they continue to be valid for newer releases of GCJ since I have not built GCJ for Windows after GCJ 4.2.

The most obvious way to go about doing this would be to build GCJ on Windows using either MSYS or Cygwin. This is known as a “native” build. This is indeed how I first went about it. However, it was painfully slow. It was also rather unreliable due to various bugs in MSYS and due to the case-insensitivity of the Windows filesystems.

This is where the awesome design of the GNU Compiler Collection (GCC), of which GCJ is a part, came to my aid - I was actually able to use the following two-step process instead of the above:

  1. Build a GCJ on Linux that runs on Linux but creates executables for Windows (known as a “cross-compiler”).
  2. Using the GCJ created above, build a GCJ on Linux that runs on Windows and creates executables for Windows (known as a “crossed-native compiler”).

This two-step process is actually far faster than the single-step native build process and is also very reliable. I can also test the compiler created like this on Linux itself using either WINE or Windows itself running inside an emulator like QEMU, thus completely avoiding the need to reboot my PC.

It should come as no surprise then, that this is the process I used to build and test GCJ for Windows and this process is what is documented below.

If you have any comments on this document, or if you have any queries that are not answered by it, please feel free to contact me.

Requirements

The first thing you need is a decent PC running a modern Linux distribution. You would need around 500 MB of free hard disc space for the whole process. You should know how to work under Linux and you should have had some experience in building software from source. Your Linux installation should also have the “development” packages like GCC, binutils, make, bison, flex, etc.

You would need to download the source code for GCC and binutils. I recommend that you get the latest released version of these from a convenient mirror site. If bandwidth is a constraint for you, get only the “core”, “g++” and “java” bundles (compressed tarballs) of GCC.

I will use $TARGET to refer to the target of the code generated by GCC. This can be either “mingw32”, “i386-pc-mingw32” or “i686-pc-mingw32” (without the double quotes) depending on your needs. “mingw32” is the canonical MinGW target and is an alias for “i386-pc-mingw32” at the time of this writing. This represents 32-bit Windows executables that can run on any PC with an i386 or better. If you only want to target Pentium Pro or better (all modern PCs), use “i686-pc-mingw32” instead.

I will use $GCC_SRC_DIR and $BU_SRC_DIR to refer to the folders into which you have extracted the source code for GCC and binutils respectively.

Download the latest released versions of the “mingw-runtime” and “w32api” binary packages from the MinGW SourceForge repository.

We will use the following shell scripts to automate the build process:

  1. cfgxbu.sh - configure Linux to Windows cross-binutils.
  2. cfgxgcc.sh - configure Linux to Windows cross-GCC.
  3. cfgwbu.sh - configure Windows cross-native-binutils.
  4. cfgwgcc.sh - configure Windows crossed-native-GCC.
  5. buildit.sh - build configured software.

Download and save these scripts into a convenient folder and be sure to give “execute” permission on them.

IMPORTANT: At the top of each of these scripts are variables that you must set correctly to reflect your folder structure. These include the folders where you have extracted the binutils and GCC sources and the folders where the built software would be installed. If you do not do this, the process would most likely fail for you.

Finally, you must have some patience and perseverance as the entire process can take quite a while.

Important Notes

Here are some important notes for this process:

  1. You must get the binaries for “mingw-runtime” and “w32api”, not the source packages.
  2. The folders where you build GCC or binutils and the folder into which you finally install them must be totally separate from the folders that contain their respective sources. GCC does not yet properly support building it in the same folder as (or a sub-folder of) the folder that contains its sources. This holds for both the phases of this process.
  3. Before you start building GCC or binutils (in either phase), you should create a sub-folder named “sys-root” inside the folder into which you would install the GCC and binutils that you would be building. Create a sub-folder named “mingw” inside the “sys-root” folder and then extract the contents of the “mingw-runtime” and “w32api” binary packages as-is into this folder such that the “include” and “lib” sub-folders of this folder (i.e. “sys-root/mingw”) contain the MinGW headers and libraries respectively.
  4. After you build and install cross-binutils in the first phase, you must modify your PATH environment variable to contain before anything else the path to the “bin” sub-folder of the folder into which you have installed it. If you use the scripts I have provided here, you do not need to do this manually.
  5. I have used the target “i686-pc-mingw32” in the scripts. If you wish to use a different target (e.g. “i386-pc-mingw32”), you must change the value of the “TARGET” variable in each of the scripts before proceeding with this process.
  6. At least as of binutils-2.16.1, you must build cross and crossed-native binutils on a file-system that supports creating hard links. GCC does not have such a problem.
  7. You must have installed YACC and Lex (or equivalent programmes like GNU bison and flex) to build binutils.

Building a Cross-Compiler

We will first need to build a GCC that runs on Linux, but creates executables for Windows. This is sufficient in itself if you prefer Linux to Windows as a development environment.

Follow the following steps in the given order:

  1. Create a folder outside of either $BU_SRC_DIR or $GCC_SRC_DIR where we will install the cross-compiler. We will call this folder $XGCC_DIR.
  2. Create a folder named “sys-root” in $XGCC_DIR. Create a folder named “mingw” within the “sys-root” folder. Extract the “mingw-runtime” and “w32api” binary packages as-is into this sub-folder (i.e. “$XGCC_DIR/sys-root/mingw”).
  3. Create a folder outside of either $BU_SRC_DIR or $GCC_SRC_DIR where we will build cross-binutils. We will call this folder $XBU_BUILD_DIR.
  4. Update the “cfgxbu.sh” script with the correct value for BU_SRC_DIR and set PREFIX to the value of $XGCC_DIR.
  5. Run “cfgxbu.sh” with $XBU_BUILD_DIR as the working folder.
  6. Update the “buildit.sh” script with the correct value for XGCC_DIR.
  7. Run “buildit.sh” with $XBU_BUILD_DIR as the working folder. This will build and install cross-binutils into $XGCC_DIR.
  8. Create a folder outside of either $BU_SRC_DIR or $GCC_SRC_DIR where we will build cross-GCC. We will call this folder $XGCC_BUILD_DIR. If you want to save space, you can clean up $XBU_BUILD_DIR and use it here.
  9. Update the “cfgxgcc.sh” script with the correct value for GCC_SRC_DIR and set PREFIX to the value of $XGCC_DIR.
  10. Run “cfgxgcc.sh” with $XGCC_BUILD_DIR as the working folder.
  11. Run “buildit.sh” with $XGCC_BUILD_DIR as the working folder. This will build and install cross-GCC into $XGCC_DIR.

If everything went smoothly, you now have a complete cross-compiler running on Linux that can generate Windows executables from programmes written in C, C++ or Java. The compiler executables will be named $TARGET-gcc, $TARGET-g++, etc. and can be found in $XGCC_DIR/bin.

Building a Crossed-Native Compiler

We will now use the cross-GCC built above to create a native GCC for Windows. This is needed if you prefer to compile and test Windows programmes on Windows itself.

Follow the following steps in the given order:

  1. Create a folder outside of either $BU_SRC_DIR or $GCC_SRC_DIR where we will install the crossed-native GCC. We will call this folder $WGCC_DIR.
  2. Create a folder named “sys-root” in $WGCC_DIR. Create a folder named “mingw” within the “sys-root” folder. Extract the “mingw-runtime” and “w32api” binary packages as-is into this sub-folder (i.e. “$WGCC_DIR/sys-root/mingw”).
  3. Create a folder outside of either $BU_SRC_DIR or $GCC_SRC_DIR where we will build crossed-native-binutils. We will call this folder $WBU_BUILD_DIR. If you want to save space, you can clean up $XGCC_BUILD_DIR and use it here.
  4. Update the “cfgwbu.sh” script with the correct values for BU_SRC_DIR and XGCC_DIR. Set PREFIX to the value of $WGCC_DIR.
  5. Run “cfgwbu.sh” with $WBU_BUILD_DIR as the working folder.
  6. Update the “buildit.sh” script with the correct value for XGCC_DIR.
  7. Run “buildit.sh” with $WBU_BUILD_DIR as the working folder. This will build and install crossed-native-binutils into $WGCC_DIR.
  8. Create a folder outside of either $BU_SRC_DIR or $GCC_SRC_DIR where we will build GCC for Windows. We will call this folder $WGCC_BUILD_DIR. If you want to save space, you can clean up $WBU_BUILD_DIR and use it here.
  9. Update the “cfgwgcc.sh” script with the correct values for GCC_SRC_DIR and XGCC_DIR. Set PREFIX to the value of $WGCC_DIR.
  10. Run “cfgwgcc.sh” with $WGCC_BUILD_DIR as the working folder.
  11. Run “buildit.sh” with $WGCC_BUILD_DIR as the working folder. This will build and install GCC into $WGCC_DIR.

If everything went smoothly, you now have a crossed-native GCC for Windows that can compile C, C++ and Java programmes into executables for Windows. Transfer the contents of $WGCC_DIR to a Windows machine to use it.

WARNING: When you install binutils into $WGCC_DIR, the tools are installed into both $WGCC_DIR/bin as well as $WGCC_DIR/$TARGET/bin. To save space, these are created as hard links. When you transfer the contents of $WGCC_DIR to a Windows machine, make sure that the $WGCC_DIR/$TARGET/bin folder exists and has the necessary tools from binutils. If you do not do this, GCC will not be able to automatically locate these tools unless their location is specified in the PATH environment variable.

Building a Native Compiler

While I have built the C and C++ compilers in GCC natively for MinGW using MSYS, I have not tried building GCJ natively in this environment in a long time for the reasons mentioned elsewhere. However, there are some things you should definitely bear in mind while building GCC natively for MinGW using MSYS:

Further Reading

Now you can start using GCJ to build and run your applications. If you run into any problems, feel free to ask the GCJ mailing list for help by sending a message to java@gcc.gnu.org giving as many details as possible. However, you should first read the GCJ documentation and search the GCJ mailing list to find out if your issue has already been addressed.

Since GCC/GCJ is Free Software and you have the complete source code available for it, you might sometimes find that you can fix a problem yourself by patching it. In this case, do share your fix with other users by sending your patch to java-patches@gcc.gnu.org. If you are new to this, read “How to Create Patches” for information on how to create and submit a patch.

Change History

Here are the summaries of the major changes made to this document since it was first published: