Thursday May 07, 2009

Painful Ant Bite: A generous CLASSPATH and ant.bat out of hell

Painful ant bytes... ;\^) Starting to number them...

  1. When ant runs, it sometimes uses temporary files using the java property java.io.tmpdir as the root of the temporary file area for the system. Unfortunately, the temp file used by ant isn't unique enough to prevent two processes running ant from bumping into each other. We had problems using the same machine to build both Solaris 32bit and Solaris 64bit at the same time. OUCH!

    Jonathan came up with a good solution specific to the JDK in the langtools Makefile that runs ant. He defines the java.io.tmpdir property on the ant command line to be unique to this build area and platform:
    ant -Djava.io.tmpdir='$(ABS_OUTPUTDIR)/build/ant-tmp' ...

    The basic idea is to redefine the java.io.tmpdir (the root of the temporary file area) to something more unique to the circumstances, and ideally in a location that will get cleaned up at the right time.

  2. Had a lovely time (<- sarcasm) tracking down a problem on Windows with JDK ant builds. Apparently on Windows, if you manage to get the ant.bat startup instead of the shell script version of the startup, commas are not allowed on the command line. So you cannot do this:
    ant -Djavac.debuglevel=source,lines,vars OUCH!

    This problem was reported here but nothing was done. Seems like a simple note in the User Manual was a minimum here.

  3. So I downloaded the cpptasks for ant from the ant-contrib site. And it builds from the command line just fine with the latest ant, but it won't build using the ant that comes with NetBeans, and it won't build when loaded into NetBeans. So why is that? The build requires xercesImpl.jar, but the cpptasks build.xml file doesn't explicitly say that, so how did it find it in one case and not in another?

    Turns out that the default behavior for the ant <javac> task is to include all the ant runtime classpath in your java compilation. Yipes! That seems like a horrible default if you ask me, depending on what ant decides to use in its runtime classpath, you get it all? :\^( OUCH!

    Seems like every ant installation could potentially behave differently, depending on how ant is configured.

    So I'm thinking I want to change all <javac> uses to <javac includeAntRuntime="false">

    This was also talked about on a JavaLobby forum, with some helpful comments.

-kto

Monday Feb 16, 2009

The pain of vcvars32.bat, and an ant solution

On Windows, and using Ant to do native compilations with Visual Studio requires certain environment variables to be set. So to be able to say "just run ant", you need to require the user to have set these properties before they start ant. The standard way to set them is with the script vcvars32.bat or vsvars32.bat. So how do you just make this work inside ant? You can't just call vcvars32.bat from your ant script, or can you?

Turns out that you can dip into a cmd.exe environment just long enough to run vcvars32.bat, print out the settings as a properties file and pop back out. As an example,


REM Windows bat file that runs vcvars32.bat for Visual Studio 2003
REM   and echos out a property file with the values of the environment
REM   variables we want, e.g. PATH, INCLUDE, LIB, and LIBPATH.

REM Clean out the current settings
set INCLUDE=
set LIB=
set LIBPATH=

REM Run the vsvars32.bat file, sending it's output to neverland.
set VSVARS32=%VS71COMNTOOLS%\vsvars32.bat
if "%VS71COMNTOOLS%"=="" (
    set VSVARS32=%VS80COMNTOOLS%\vsvars32.bat
    if "%VS80COMNTOOLS%"=="" set VSVARS32=%VS90COMNTOOLS%\vsvars32.bat
)
call "%VSVARS32%" > NUL

REM Create some vars that are not set with VS Express 2008
if "%MSVCDIR%"=="" set MSVCDIR=%VCINSTALLDIR%
REM Try using exe, com might be hanging in ssh environment?
REM     set DEVENVCMD=%DEVENVDIR%\devenv.exe
set DEVENVCMD=%DEVENVDIR%\devenv.com

REM Adjust for lack of devenv in express editions.  This needs more work.
REM VCExpress is the correct executable, but cmd line is different...
if not exist "%DEVENVCMD%" set DEVENVCMD=%DEVENVDIR%\VCExpress.exe

REM Make sure Cygwin is on the path
set PATH="C:\cygwin\bin;C:\cygwin\;%PATH%"

REM Echo out a properties file
echo ############################################################
echo # DO NOT EDIT: This is a generated file.
echo windows.vs.vsvars32.bat=%VSVARS32%
echo windows.vs.DEVENVDIR=%DEVENVDIR%
echo windows.vs.DEVENVCMD=%DEVENVCMD%
echo windows.vs.VCINSTALLDIR=%VCINSTALLDIR%
echo windows.vs.VSINSTALLDIR=%VSINSTALLDIR%
echo windows.vs.MSVCDIR=%MSVCDIR%
echo windows.vs.INCLUDE=%INCLUDE%
echo windows.vs.LIB=%LIB%
echo windows.vs.LIBPATH=%LIBPATH%
echo windows.vs.PATH=%PATH%
echo ############################################################

Of course, the \\ characters need to be changed to /. This results in something like:

############################################################
# DO NOT EDIT: This is a generated file.
windows.vs.vsvars32.bat=C:/PROGRA~1/MICROS~2.NET//Common7/Tools/vsvars32.bat
windows.vs.VS71COMNTOOLS=C:/PROGRA~1/MICROS~2.NET//Common7/Tools/
windows.vs.DEVENVDIR=C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/IDE
windows.vs.VCINSTALLDIR=C:/Program Files/Microsoft Visual Studio .NET 2003
windows.vs.VSINSTALLDIR=C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/IDE
windows.vs.MSVCDIR=C:/Program Files/Microsoft Visual Studio .NET 2003/VC7
windows.vs.INCLUDE=C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/ATLMFC/INCLUDE;C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/INCLUDE;C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/PlatformSDK/include/prerelease;C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/PlatformSDK/include;C:/Program Files/Microsoft Visual Studio .NET 2003/SDK/v1.1/include;
windows.vs.LIB=C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/ATLMFC/LIB;C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/LIB;C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/PlatformSDK/lib/prerelease;C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/PlatformSDK/lib;C:/Program Files/Microsoft Visual Studio .NET 2003/SDK/v1.1/lib;
windows.vs.LIBPATH=
windows.vs.PATH=C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/IDE;C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN;C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/Tools;C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/Tools/bin/prerelease;C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/Tools/bin;C:/Program Files/Microsoft Visual Studio .NET 2003/SDK/v1.1/bin;C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322;"C:/cygwin/bin;C:/cygwin/;c:/PROGRA~1/MICROS~2.NET/Common7/IDE;c:/PROGRA~1/MICROS~2.NET/Vc7/bin;c:/PROGRA~1/MICROS~2.NET/Common7/Tools;c:/PROGRA~1/MICROS~2.NET/Common7/Tools/Bin/prerelease;c:/PROGRA~1/MICROS~2.NET/Common7/Tools/Bin;c:/PROGRA~1/MICROS~2.NET/SDK/v1.1/bin;c:/PROGRA~1/Java/JDK16~1.0_1/bin;C:/cygwin/home/ohair/import/APACHE~1.1/bin;C:/cygwin/usr/local/bin;C:/cygwin/bin;C:/cygwin/bin;C:/cygwin/usr/X11R6/bin;C:/cygwin/usr/sbin;C:/cygwin/sbin;C:/cygwin/home/ohair/hgws/home_bin/bin;C:/cygwin/home/ohair/hgws/home_bin/bin/win32;C:/cygwin/home/ohair/bin;c:/WINDOWS/System32;c:/WINDOWS;c:/WINDOWS/System32/Wbem;C:/cygwin/lib/lapack";
############################################################

So in your ant build script you can effectively do this (on Windows only of course :\^):


<target name="generate-vs-properties">
    <exec dir="." executable="cmd" output="vs.properties">
        <arg value="/q"/>
        <arg value="/c"/>
        <arg value="genVSproperties.bat"/>
    </exec>
    <replace file="vs.properties" token="\\" value="/"/>
    <property file="vs.properties"/>
</target>

So now what? The last piece of the puzzle is that to need to set the environment variables when you run Visual Studio, e.g.


<property file="vs.properties"/>
<exec dir="." executable="${windows.vs.VS71COMNTOOLS}/../../Vc7/bin/cl.exe" failonerror="true">
  <env key="VS71COMNTOOLS" value="${windows.vs.VS71COMNTOOLS}"/>
  <env key="INCLUDE" value="${windows.vs.INCLUDE}"/>
  <env key="LIB" value="${windows.vs.LIB}"/>
  <env key="LIBPATH" value="${windows.vs.LIBPATH}"/>
  <env key="PATH" value="${windows.vs.PATH}"/>
  <arg line="${compile_options}"/>
</exec>

Hope this is helpful to someone.

-kto

Wednesday Apr 30, 2008

OpenJDK7, Solaris, and Sun Studio 12 Compilers

Updated 4/30/2008: Added more configuration information

We are starting work to update the compilers and build OS releases used to build OpenJDK7 and JDK7. The implications of a build system OS change may mean that the JDK7 binary bundles may support fewer OS releases. So this is a bit of a status report, and a bit of a heads up. Hopefully most people will cheer over this news, but we'll see.

Solaris

On Solaris we have already moved to Solaris 10 as the base OS, which means that the build bundles will no longer run on Solaris 8 or Solaris 9 systems. We will also be moving from the Sun Studio 11 compilers to the Sun Studio 12 compilers. Sun Studio 12 is FREE for SDN members (registration is free too). Keep in mind that this doesn't mean that you can't build with Sun Studio 11, just that we will focus on using Sun Studio 12. At some point using older tools or OS releases to build the OpenJDK may become an issue, but it is not our intent to create these issues. There are some places in the JDK where we would like to depend on some newer features of the OS being available, so there are no promises that the OpenJDK7 sources will stay buildable on Solaris 8 or 9, but currently they are.

The Solaris Makefile changes for Sun Studio 12 (SS12) will include changing to new -xarch options as described in the "What's New In The Compilers" document. The old -xarch options will continue to work fine, but generate warning errors, and so the change to the new options is to avoid the warning errors.

Note that since we still use the assembler that comes with the Solaris system at /usr/ccs/bin/as, we still have to supply it with the old option spellings.

We did run into two build issues so far:

  • Using -xO4 built .o files with dtrace is giving us some problems. We suspect the optimizer may have tossed some C++ methods that exist only for dtrace probes. We had to change -xO4 to -xO3 -g on three files in hotspot.
  • We had to revert the C++ debug format from Dwarf2 to stabs with the option -xdebugformat=stabs. We were getting some ld errors on some Elf sections during link time. We suspect this is a known problem with Elf COMDAT sections and will be watching for a fix.

It may be a while before we push these Makefile changes to the OpenJDK repositories. Changing compilers with the JDK on any platform is not as trivial a task as people might think. With Solaris and the Sun Studio compilers, we have an advantage, knowing the team doing the compilers. But with any compiler change, our biggest issue becomes performance and correctness. Not so much the performance and correctness of the C/C++ generated code, but the combination of this C/C++ code with the Hotspot generated code. It's not unusual to have bad runtime interactions between the C/C++ generated code, and the Hotspot generated code, on any platform and with any compiler revision.

So the next steps will involve running formal benchmarks to verify that we haven't regressed in performance. A somewhat difficult task given the moving target that OpenJDK7 is right now.

Linux

We already know that building the OpenJDK with different Linux releases and gcc compiler versions is working, so with Linux we just need to advance to a slightly newer Linux release as the base OS, and one that gives us the largest set of deployed targets. We still run the risk of performance and correctness issues like with Solaris, so the same benchmark exercises will need to be done. This will mean that the JDK7 binary bundles will no longer run on some older Linux systems. That doesn't mean it can't be built for these versions, just that the binary bundles we supply may be limited in the Linux releases it supports.

Windows

There is some efforts going on to see about changing to the Visual Studio .NET 2008 compilers, and potentially Windows XP as the base OS for 32bit. Again, dito on the performance and correctness issues. This will mean that the JDK7 binary bundles will no longer work on Windows 2000.

Official Build Configurations

The current list of build machines for JDK7 is documented in the JDK7 Build README:

  • Solaris 10 SPARC
  • Solaris 10 SPARCV9
  • Solaris 10 X86
  • Solaris 10 X64
  • Linux X86 Redhat Enterprise Advanced Server 2.1 update 2
  • Linux X64 Suse 8 Enterprise Server - AMD64 Edition
  • Windows 2000 X86
  • Windows 2003 X64

Official Supported Configurations

The Official JDK6 supported configurations are those configurations that we have tested the JDK6 builds on. The official supported list for JDK7 will need to be adjusted of course, certainly Solaris 8 and Solaris 9 support for JDK7 will be removed.

Other Configurations

The OpenJDK sources can be built on many more systems as documented in the OpenJDK Build README. The intent with the OpenJDK is to allow for it to be built on as many configurations as possible, but that does not necessarily mean that a configuration will become any kind of officially supported JDK7 configuration. The OpenJDK project is an open-source project, and to date, binary builds have not been provided.

Other architectures like IA64 or PowerPC are or may be considered "ports", depending on the need for changing the Hotspot VM to generate code for a different architecture. There are several "ports" being talked about on the OpenJDK porters alias, see the OpenJDK Mailing Lists. Recently, changes to Hotspot were pushed into the OpenJDK source repositories that allowed for Linux SPARC builds of Hotspot, see the changeset Open-source hotspot linux-sparc support. Email exchanges on the distro-pkg alias indicate people are building on Linux IA64, not sure if they have been successful or not, I have no idea how IA64 this would be. Of course, successfully building is only step 1, the next step is to see if it works, and works reliably. The point being that many people are taking the OpenJDK sources or IcedTea and building on many configurations.

The funding needed to take on and support a new official configuration is considerable. We hope that the OpenJDK developers contribute back the changes made to port or build on any configuration. But adding a new configuration to the official JDK7 build configuration list is a high level decision.

-kto

About

Various blogs on JDK development procedures, including building, build infrastructure, testing, and source maintenance.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today