Hi I'm documenting my (unbelievably difficult but ultimately) successful experience of building OpenJDK on Windows with Visual Studio express edition.
I built the awt tree from about a week ago, with Windows Vista, Cygwin 1.5.25-15, Microsoft Visual Studio 2008 Express Edition SP1, Freetype 2.3.5-1, jdk-7-ea-plug-b77-windows-i586-03_dec_2009.jar, DirectX SDK as per README-builds.html, Ant copied from Netbeans 6.7, and make from the cmake.org website (as per README-builds.html). The import JDK was 1.6.0. Firstly the README-builds.html talks a lot about path problems, without offering any good solutions. After much effort, I discovered that you have to use /cygpath/c paths only in $PATH and use double quote quoted C:/ style paths everywhere else (eg. export WindowsSdkDir="C:/Program Files/Microsoft SDKs/Windows/v6.0A/"). Microsoft's quality C compilers apparently need environment variables set before they work properly, otherwise they crash (not complain, but actually crash). The vcvars32.bat doesn't work from inside cygwin, so I had to run "set > a.txt", then run "vcvars32.bat", then "set > b.txt", and finally diff a.txt with b.txt to find out what these mysterious variables were, then convert them into C:/ and /cygpath/c style paths that get set in cygwin. Running jdk/make/jdk_generic_profile.sh loses the variables again, so I avoided it. Compilation misdetects the Ant version and complains it is too old, but works fine. Even "make sanity" rapidly died as freetype_versioncheck didn't build. http://mail.openjdk.java.net/pipermail/jdk6-dev/2008-March/000023.html claims you need OPENJDK=true set, an undocumented fact that doesn't help. After much effort I discovered http://www.mail-archive.com/build-dev@openjdk.java.net/msg02319.html where someone got it to work with Freetype 2.3.5 by copying bin/freetype.dll into lib/freetype6.dll and applying a patch; I also had to copy zlib1.dll into the build/windows-i586/btbins. Please at least document the fact Freetype 2.3.4 is the last working version? It then compiled for a few minutes further and died in the corba/ subdirectory, with "COMPILER_PATH cannot be empty here". I found http://mail.openjdk.java.net/pipermail/build-dev/2009-March/001767.html and edited the file in question to fix RC (I had to use the full C:/ style path, the one from that email didn't work for me), unfortunately it still didn't help, so I just commented out lines 96-98 and it compiled much further. The problem repeated itself under the jdk/ directory, and I had to edit another file and fix the path to RC and RCS. Then, still in jdk/, came missing headers. The first was afxres.h which I got from mingw and copied into Visual Studio's include directory. This got it to compile further. Next missing header was atlbase.h which lead me to discover an email (http://mail.openjdk.java.net/pipermail/build-dev/2007-December/000654.html) stating that the Visual Studio express editions are not supposed to work (again, undocumented in README-builds.html). Indeed I found that atlbase.h is part of ATL, which isn't part of any Visual Studio express edition or the Platform SDK (6 or 7). Visual Studio is expensive to buy just to compile OpenJDK. But am I really going to let that stop me, after the previous 8 hour battle? $ grep atl * -iR | grep include Binary file hotspot/.hg/store/data/src/share/vm/include_d_b__core.i matches jdk/make/jdk_generic_profile.sh: include4sdk="${vc7_root}/atlmfc/include" jdk/make/jdk_generic_profile.sh: include4sdk="${include4sdk};${platform_sdk}/Include/atl" jdk/src/windows/native/sun/jkernel/kernel.cpp:#include <atlbase.h> jdk/src/windows/native/sun/jkernel/kernel.cpp:#include <atlwin.h> jdk/src/windows/native/sun/jkernel/stdafx.h:#include <atlbase.h> jdk/src/windows/native/sun/jkernel/stdafx.h:#include <atlcom.h> jdk/src/windows/native/sun/jkernel/stdafx.h:#include <atlwin.h> jdk/src/windows/native/sun/jkernel/DownloadDialog.cpp:#include <atlbase.h> jdk/src/windows/native/sun/jkernel/DownloadDialog.cpp:#include <atlcom.h> jdk/src/windows/native/sun/jkernel/DownloadDialog.cpp:#include <atlwin.h> jdk/src/windows/native/sun/jkernel/DownloadDialog.cpp:#include <atlhost.h> jdk/src/windows/native/sun/jkernel/DownloadHelper.cpp:#include <atlbase.h> jdk/src/windows/native/sun/jkernel/DownloadHelper.cpp:#include <atlcom.h> jdk/src/windows/native/sun/jkernel/DownloadHelper.cpp:#include <atlwin.h> jdk/src/windows/native/sun/jkernel/DownloadHelper.cpp:#include <atlhost.h> jdk/src/windows/native/sun/jkernel/stdafx.cpp:#include <atlimpl.cpp> So in other words only jkernel uses the ATL for anything. Pity that it uses it extensively, so there's no easy way to take ATL out as a dependency. Someone should rewrite it without ATL: 4000 lines of code shouldn't hold 7 million lines hostage. But if ATL can't come out of jkernel, maybe jkernel can come out of Java. I put in lots of #if 0 around the entire contents of all the jkernel .cpp files, and made preJVMStartup() into a no-op. It compiled further, complaining in at least one place about missing /usr/bin/diff which isn't documented as a dependency, but luckily that doesn't stop the build. When it got to compiling fonts, it broke again, this time looking for freetype.dll instead of freetype6.dll. I copied the one to the other and typed make with crossed fingers. After 20 minutes of compiling it got to the fonts again and they compiled. After a very long wait, it finally compiled successfully... ...and the hello world worked :-). Now I'm onto what I thought would be the hard part: the actual patch I want to write :-). Patches I used to build it are attached. Hope this helps someone. Regards Damjan
diff -r 086bf925ee95 make/common/shared/Compiler-msvc.gmk --- a/make/common/shared/Compiler-msvc.gmk Thu Nov 12 15:35:35 2009 -0800 +++ b/make/common/shared/Compiler-msvc.gmk Thu Dec 10 19:12:24 2009 +0200 @@ -34,7 +34,7 @@ CCC = $(COMPILER_PATH)cl LIBEXE = $(COMPILER_PATH)lib LINK = $(COMPILER_PATH)link - RC = $(MSDEVTOOLS_PATH)rc + RC = "C:/Program Files/Microsoft SDKs/Windows/v6.0A/Bin/rc" LINK32 = $(LINK) RSC = $(RC) @@ -93,9 +93,9 @@ #rebase and midl moved out of Visual Studio into the SDK: REBASE = $(MSDEVTOOLS_PATH)/rebase MTL = $(MSDEVTOOLS_PATH)/midl.exe - ifndef COMPILER_PATH - COMPILER_PATH := $(error COMPILER_PATH cannot be empty here) - endif + #ifndef COMPILER_PATH +# COMPILER_PATH := $(error COMPILER_PATH cannot be empty here) +# endif endif else # else ARCH_DATA_MODEL is 64
diff -r ca34cfff70a4 make/common/shared/Compiler-msvc.gmk --- a/make/common/shared/Compiler-msvc.gmk Fri Nov 27 16:07:32 2009 +0300 +++ b/make/common/shared/Compiler-msvc.gmk Thu Dec 10 19:13:15 2009 +0200 @@ -34,8 +34,8 @@ CCC = $(COMPILER_PATH)cl LIBEXE = $(COMPILER_PATH)lib LINK = $(COMPILER_PATH)link - RC = $(MSDEVTOOLS_PATH)rc - RSC = $(MSDEVTOOLS_PATH)rc + RC = "C:/Program Files/Microsoft SDKs/Windows/v6.0A/Bin/rc" + RSC = $(RC) LINK32 = $(LINK) # Fill in unknown values @@ -78,7 +78,7 @@ #rebase and midl moved out of Visual Studio into the SDK: REBASE = $(MSDEVTOOLS_PATH)/rebase MTL = $(MSDEVTOOLS_PATH)/midl.exe - MT = $(MSDEVTOOLS_PATH)mt + MT = "C:/Program Files/Microsoft SDKs/Windows/v6.0A/Bin/mt" ifndef COMPILER_PATH COMPILER_PATH := $(error COMPILER_PATH cannot be empty here) endif diff -r ca34cfff70a4 make/tools/freetypecheck/Makefile --- a/make/tools/freetypecheck/Makefile Fri Nov 27 16:07:32 2009 +0300 +++ b/make/tools/freetypecheck/Makefile Thu Dec 10 19:13:15 2009 +0200 @@ -38,7 +38,7 @@ # Start with CFLAGS (which gets us the required -xarch setting on solaris) ifeq ($(PLATFORM), windows) FT_OPTIONS = /nologo /c - FREETYPE_DLL = $(FREETYPE_LIB_PATH)/freetype.dll + FREETYPE_DLL = $(FREETYPE_LIB_PATH)/freetype6.dll FT_LD_OPTIONS = $(FREETYPE_LIB_PATH)/freetype.lib ifdef MT FT_LD_OPTIONS += /manifest diff -r ca34cfff70a4 src/windows/native/sun/jkernel/DownloadDialog.cpp --- a/src/windows/native/sun/jkernel/DownloadDialog.cpp Fri Nov 27 16:07:32 2009 +0300 +++ b/src/windows/native/sun/jkernel/DownloadDialog.cpp Thu Dec 10 19:13:15 2009 +0200 @@ -1,3 +1,4 @@ +#if 0 /* * Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -889,3 +890,4 @@ sprintf(msg, "Progress: %d / %d", m_ulProgress, m_ulProgressMax); log(msg); } +#endif diff -r ca34cfff70a4 src/windows/native/sun/jkernel/DownloadHelper.cpp --- a/src/windows/native/sun/jkernel/DownloadHelper.cpp Fri Nov 27 16:07:32 2009 +0300 +++ b/src/windows/native/sun/jkernel/DownloadHelper.cpp Thu Dec 10 19:13:15 2009 +0200 @@ -1,3 +1,4 @@ +#if 0 /* * Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -650,3 +651,4 @@ return E_FAIL; } } +#endif diff -r ca34cfff70a4 src/windows/native/sun/jkernel/kernel.cpp --- a/src/windows/native/sun/jkernel/kernel.cpp Fri Nov 27 16:07:32 2009 +0300 +++ b/src/windows/native/sun/jkernel/kernel.cpp Thu Dec 10 19:13:15 2009 +0200 @@ -1,3 +1,4 @@ +#if 0 /* * Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -1435,7 +1436,10 @@ // downloaded, this function performs various post-download cleanups such as // moving the merged rt.jar into place. At the end of cleanup, the JRE should // be indistinguishable from the non-kernel JRE. +#endif void preJVMStart() { +} +#if 0 char rawMsg[BUFFER_SIZE]; char msg[BUFFER_SIZE]; HMODULE kernel = GetModuleHandle("jkernel"); @@ -1619,3 +1623,4 @@ error(msg); } } +#endif diff -r ca34cfff70a4 src/windows/native/sun/jkernel/stdafx.cpp --- a/src/windows/native/sun/jkernel/stdafx.cpp Fri Nov 27 16:07:32 2009 +0300 +++ b/src/windows/native/sun/jkernel/stdafx.cpp Thu Dec 10 19:13:15 2009 +0200 @@ -1,3 +1,4 @@ +#if 0 /* * Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -35,3 +36,4 @@ #endif #include <atlimpl.cpp> +#endif