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

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