[CMake] Swig dependencies not being tested?

Tristan Carel tristan.carel at gmail.com
Wed Dec 12 11:17:00 EST 2007


On Dec 12, 2007 12:33 AM, Alan W. Irwin <irwin at beluga.phys.uvic.ca> wrote:
> Tristan, I have been slow to respond to your e-mail because it took a long
> time to investigate the java problems created by your patch.  Details,
> below.
>
> On 2007-12-11 10:59+0100 Tristan Carel wrote:
>
> > On Dec 10, 2007 8:58 PM, Alan W. Irwin <irwin at beluga.phys.uvic.ca> wrote:
> >> Tristan, since you do not encounter this problem, are you doing something
> >> qualitatively different than above in your CMakeLists.txt file?
> >
> [...]
>
>
> N.B. that patch did not work at all unless I changed
>
> @@ -48,9 +49,15 @@
>
> to
>
> @@ -48,9 +49,14 @@
>

Ooops!

>
> [...]
>
> Although it appears to be redundant since "%module plplotc" is specified in
> plplotcmodules.i, I added the following line to the CMake code
>
> set_source_files_properties(plplotcmodule.i
> PROPERTIES SWIG_MODULE_NAME plplotc
> )
>
> > I would be glad to know if it resolves your dependencies problem.
>
> Yes, it does for the python case, but can you explain why this patched
> version work (no gratuitous rebuilds) when "%module plplotc" alone does not
> work with the unpatched version?
>

In Python specific case, with "%module plplotc" alone, UseSwig.cmake
creates the following make rule:

plplotcmodulePYTHON_wrap.c plplotcapi.py: plplotcapi.i
    /usr/bin/swig ...

To get module's name, UseSwig.cmake does not look in swig files'
content: plplotcapi.py is deduced from the swig filename. So when
module's name specified with "%module <mymodule>" directive differs
from the swig filename, you can tell `UseSwig.cmake' the real module's
name with the `SWIG_MODULE_NAME' property.

So that if plplotcapi.py is (accidently) removed, `make' runs `swig'
to re-create it.

> The remainder of this e-mail concerns the java compilation problems that
> showed up with your patched version of UseSwig.cmake.
>
> Your current approach for compiling java files does not work since there is
> a whole boatload of *.java files generated by swig as well as some special
> files which we need to compile as well.  For the PLplot case the complete
> list of java files (all but those marked as hand-crafted or configured are
> generated by swig) is the following:
>
> bindings/java/PLStream.java (hand-crafted)
>
> in the source tree and
>
> bindings/java/PLGraphicsIn.java
> bindings/java/plplotjavac.java
> bindings/java/plplotjavacConstants.java
> bindings/java/plplotjavacJNI.java
> bindings/java/config.java  (configured)
>
> in the build tree.
>
> The plplotjavacConstants.java file can be taken care of by making the
> following change to your patched UseSWIG.cmake:
>
> -SET(SWIG_JAVA_EXTRA_FILE_EXTENSION "JNI.java" ".java")
> +# Order is important
> +SET(SWIG_JAVA_EXTRA_FILE_EXTENSION "JNI.java" "Constants.java" ".java")
>
> Also, when compiling plplotjavacConstants.java, the results of
> the plplotjavacJNI.java compilation cannot be found unless you
> add
>
> ${CMAKE_BINARY_DIR}/CMakeFiles/plplotjavac_wrap.dir
>
> to the list of directories referenced by INCLUDE_DIRECTORIES.  There is no
> guarantee in the future that this directory prefix will continue to be used
> to store the class files so this change must be classified as a temporary
> workaround. See below for a better approach which controls the location
> where the class files are located.

building wrappers generated by swig is not UseSwig.cmake's duty. But
to know which files are created by swig, I guess this is mandatory.
`UseSwig.cmake' should prevent user to painfully manage list of
generated wrappers, like you do to compile java bindings.
For example if you delete one of the generated java file, `make'
should re-run swig, which is not currently the case.

About the weird error you have with java:
Relative to the way I have used swig + java, I guessed the line:
SET(SWIG_JAVA_EXTRA_FILE_EXTENSION "JNI.java" ".java")
Unfortunately with plplot, some others are created.

For the moment, swig does not provide list of created files. With
option -MM, swig writes to standard output:

/tmp/plplot/bindings/java/plplotjavac_wrap.c: \
 /tmp/plplot/bindings/java/plplotjavac.i \
 /tmp/plplot/bindings/swig-support/plplotcapi.i

This is good actually, as we can determine list of dependencies. But
not good enough as we don't know the list of generated wrappers. This
feature of Swig is not currently used by `UseSwig.cmake', but we will
be soon to get exact dependencies.

> Additionally, there is the showstopper problem of the swig-generated file
> PLGraphicsIn.java.  I only have a superficial knowledge of swig and java,
> but I believe that file is generated because our API *.i file has a struct
> defined that is called PLGraphicsIn.  Anyhow, it appears in the Java case
> that swig-generated files will have a variety of names depending on the *.i
> internals of each separate project.
>
> Furthermore, there is the showstopper issue of the PLplot-specific java file
> called PLStream.java in the source tree, and our configured java file called
> config.java in the build tree which also must be compiled in the right
> order.

As written above, `UseSwig.cmake' is not (and might no be)  concerned
by the build of generated wrappers as, like you describe, this is very
dependant of user's project.

>
> Finally, the patched UseSWIG.cmake approach generates the following cmake.out
> error message.
>
> -- Configuring done
> CMake Error: Error required internal CMake variable not set, cmake may be
> not be built correctly.
> Missing variable is:
> CMAKE_Java_CREATE_SHARED_MODULE
> -- Generating done
> -- Build files have been written to: /home/software/plplot_cvs/HEAD/build_dir

I encountered the same trouble, but did not figure out what is going on...

> That error message makes no sense since java file compilation generates
> class files and not shared modules or libraries.  Anyhow, since the rest of
> the message looks like everything worked, I believe that error message is
> spurious.

Yes, indeed!
UseSwig.cmake's next patch won't try to guess generated java wrappers,
so the error disappears.

>  When I continued on with showstopper make after that the problems
> indicated above with the current patched approach showed up. (Note, I got
> the reported good result for python only by turning off our java interface.)
>
> Note, for our special case we make a complete list of the java files
> we want to compile, and then after
>
> swig_add_module(plplotjavac_wrap java plplotjavac.i)
> swig_link_libraries(plplotjavac_wrap plplot${LIB_TAG})
>
> we use (in the unpatched UseSwig.cmake case which only compiles the C file
> generated by swig, and not the java files) the following custom
> commands and overall custom target compile all our java files:
>
> foreach( srcfile ${JAVA_FILES_FULL} )
>    get_filename_component( fileroot ${srcfile} NAME_WE )
>    add_custom_command(
>    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/plplot/core/${fileroot}.class
>    COMMAND ${CMAKE_Java_COMPILER}
>    -classpath ${CMAKE_CURRENT_BINARY_DIR} ${srcfile}
>    -d ${CMAKE_CURRENT_BINARY_DIR}
>    DEPENDS ${srcfile}
>    )
> endforeach( srcfile ${JAVA_FILES_FULL} )
> add_custom_target(plplot_core ALL DEPENDS ${JAVA_CLASSES})
>
> JAVA_CLASSES is created (not shown) to make the appropriate file
> dependencies of the plplot_core target.
>
> The above command compiles the java files in the correct order while
> controlling the location of the generated class files in the build tree
> while pointing to that same location with classpath.  (It also generates no
> spurious cmake error messages involving CMAKE_Java_CREATE_SHARED_MODULE.)
>
> You may want to follow something similar to the above approach if
> you decide you do want to compile java files within your patched version of
> UseSWIG.cmake.  You would have to allow users to communicate a list of
> specially named java files to be compiled in the correct order with correct
> classpath as well as communicate the java package name (plplot.core in our
> case).
>
> Tristan, if you decide to create a patch for UseSwig.cmake that does all
> that for the java case, I would be happy to test it.  However, if it is
> possible to solve the original gratuitous C rebuild issue for the java
> interface case without compiling the java files, then that might greatly
> reduce the changes you have to do for UseSwig.cmake.

As we can't get the exact list of generated files by swig, we won't
try to guess it, so won't try to build them too :)

I have added an entry at CMake BT:
http://www.cmake.org/Bug/bug_view_page.php?bug_id=6151

The patch is sensibly different from the previous one: it mainly
remove the spurious entry
SET(SWIG_JAVA_EXTRA_FILE_EXTENSION "JNI.java" ".java")

It fixes unecessary rebuilds, whatever the language target.

I don't have CVS write access on the modules repository. I will ask Bill for it.

Bye
-- 
Tristan Carel
Music with dinner is an insult both to the cook and the violinist.
http://www.tristancarel.com


More information about the CMake mailing list