Home > Software > Visual C in Ant

Visual C in Ant

Sounds a little bit crazy, but you would probably need this more often than you think. If you develop some JNI applications this probability increases quite a bit.

Nowadays there is a big hype with the Continuous Integration and behind that usually sits a pretty solid build system. So most likely you will have to find a way to create your native libraries automatically and not from the development environment. Not to mention that you would probably want to generate your binaries on multiple environments to ensure compatibility for your JNI application. After all, it is write once, run anywhere.
And isn’t just nice to do everything from one place? One IDE, one build system, etc.

OK, I convinced you. But how do you do it? Ant is simply great when it comes about building Java applications, but what about compiling C code into native libraries? Now is the part where cpptasks jumps to give you a hand. So let’s see how your ANT file will look like for compiling your native library:

<property environment="env"/>
<condition property="iswin">
    <os family="windows"/>
<taskdef resource="cpptasks.tasks"/>
<mkdir dir="${native.out}"/>
<cc outtype="shared" subsystem="console" outfile="${native.out}/${native.name}" objdir="${native.out}" name="msvc">
    <fileset dir="${native.src}" includes="*.c"/>
    <libset dir="${native.src}" libs="OtherLib"/>
    <sysincludepath location="${jdk.path}/include/"/>
    <sysincludepath location="${jdk.path}/include/win32" if="iswin"/>


  • iswin is an Ant property set only if we are running on windows
  • native.out is the directory where the libraries and object files are generated
  • native.src is the directory containing the C source files
  • native.name is the name of the generated library
  • jdk.path is the JDK installation directory


As you can see the C compiler used is Visual C (name attribute of the cc task). And most probably you will need the WinAPI include file, so add the below inside your cc task:

<compiler name="msvc">
    <sysincludepath location="${env.WindowsSdkDir}/include"/>

And now comes the messy part. The environment variable WindowsSdkDir must be defined. Without this the compiler won’t even start and you will get an error like this:

Could not launch cl: java.io.IOException: Cannot run program "cl" (in directory "native\out"): CreateProcess error=2, The system cannot find the file specified


But fortunately there is a workaround and it is pretty simple, even tough not beautiful. In the Windows SDK distribution there is a .bat file that defines all the necessary environment variables: vsvars32.bat. And its location is defined in an environment variable: VS90COMNTOOLS for Visual Studio 2008 and VS80COMNTOOLS for Visual Studio 8.

So all you have to do is run (in the same CMD session) “%VS90COMNTOOLS%\vsvars32.bat” before running your Ant build (or launching your IDE). And no, there is no (clean) way to set an environment variable from Ant or Java.

Categories: Software Tags: ,
  1. February 4, 2009 at 7:19 pm

    Ugh, I liked!

    Have a nice day

  2. Keyser Soze
    January 29, 2015 at 3:41 pm

    Thanks a lot for this hint!

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: