Building C Header and Stub Files: the JavaH Builder

You can generate C header and source files for implementing native methods, by using the JavaH Builder. There are several ways of using the JavaH Builder. One typical invocation might look like:

      classes = Java(target = 'classes', source = 'src/pkg/sub')
      JavaH(target = 'native', source = classes)
    

The source is a list of class files generated by the call to the Java Builder, and the target is the output directory in which we want the C header files placed. The target gets converted into the -d when SCons runs javah:

      % scons -Q
      javac -d classes -sourcepath src/pkg/sub src/pkg/sub/Example1.java src/pkg/sub/Example2.java src/pkg/sub/Example3.java
      javah -d native -classpath classes pkg.sub.Example1 pkg.sub.Example2 pkg.sub.Example3
    

In this case, the call to javah will generate the header files native/pkg_sub_Example1.h, native/pkg_sub_Example2.h and native/pkg_sub_Example3.h. Notice that SCons remembered that the class files were generated with a target directory of classes, and that it then specified that target directory as the -classpath option to the call to javah.

Although it's more convenient to use the list of class files returned by the Java Builder as the source of a call to the JavaH Builder, you can specify the list of class files by hand, if you prefer. If you do, you need to set the JAVACLASSDIR construction variable when calling JavaH:

      Java(target = 'classes', source = 'src/pkg/sub')
      class_file_list = ['classes/pkg/sub/Example1.class',
                         'classes/pkg/sub/Example2.class',
                         'classes/pkg/sub/Example3.class']
      JavaH(target = 'native', source = class_file_list, JAVACLASSDIR = 'classes')
    

The JAVACLASSDIR value then gets converted into the -classpath when SCons runs javah:

      % scons -Q
      javac -d classes -sourcepath src/pkg/sub src/pkg/sub/Example1.java src/pkg/sub/Example2.java src/pkg/sub/Example3.java
      javah -d native -classpath classes pkg.sub.Example1 pkg.sub.Example2 pkg.sub.Example3
    

Lastly, if you don't want a separate header file generated for each source file, you can specify an explicit File Node as the target of the JavaH Builder:

      classes = Java(target = 'classes', source = 'src/pkg/sub')
      JavaH(target = File('native.h'), source = classes)
    

Because SCons assumes by default that the target of the JavaH builder is a directory, you need to use the File function to make sure that SCons doesn't create a directory named native.h. When a file is used, though, SCons correctly converts the file name into the javah -o option:

      % scons -Q
      javac -d classes -sourcepath src/pkg/sub src/pkg/sub/Example1.java src/pkg/sub/Example2.java src/pkg/sub/Example3.java
      javah -o native.h -classpath classes pkg.sub.Example1 pkg.sub.Example2 pkg.sub.Example3