[Adding bug-automake in CC:, so that we won't forget about the issue] On Thursday 14 July 2011, tsuna wrote: > Hi all, > whether I like it or not, it so happens that I have a Java project I'm > trying to package properly, and I'm trying to use autoconf/automake > for maximum portability and ease of integration with various distros > (since most of them have tools to automagically build packages on > properly autotoolized projects), not to mention all the usual benefits > that the autotools provide out of the box. > > I'm aware of http://sources.redhat.com/automake/automake.html#Java-Support > (support via GCJ) but that's not what I want. Most of the Java people > don't use GCJ, they use Sun's JDK. Somewhat confusingly perhaps, that > section of the documentation doesn't refer to > http://sources.redhat.com/automake/automake.html#Java which seems to > be closer to what I want. > You're right; the documentation on Java support should be definitely be improved (especially making better distinction between usual bytecode compilation with javac and "native/binary compilation" with gcj).
> It's not clear from that part of the > documentation how to get a .jar and have it installed etc. I read the > code in lib/am/java.am and it seems all it does is to compile all the > .java files into .class files and install the .class files. > Sadly true. And IMHO adding support for generating and installing .jar files would be definitely worthwhile. BTW, I had already given some thoughts to this possibility, but I wasn't sure if there would be enough user interest to warrant a change in this direction; your mail seems to show that indeed there is some interest at least (thank you for that!). > The good > thing about this is that it's compiling all the .java files at once > (and not one-by-one like we do with C/C++ files), the bad thing is > that it has no facility to produce and install a .jar file that > contains all the .class files, > and it only supports one _JAVA target per Makefile.am. > Yes (but my proposal below about a new JARS primary should allow us to easily remove this limitation). > I noticed there's a branch called "java-work", however it's not clear > to me what improvements it has, and its lib/am/java.am seems pretty > much identical. > Yes, so far that branch has only dealt with small bug fixes and improved testsuite coverage. > One of the problems noted in the manual and in Automake's code is that > a single .java files doesn't predictably translate into a .class file. > And there's no equivalent to gcc -M in the Java world. "Foo.java" is > pretty much guaranteed to produce "Foo.class", but frequently there > will be other class files of the form "Foo$Something.class" produced > (this is because the nested class "Something" in the class "Foo" is > compiled into its own file). Right now in my project I build pretty > much everything with custom rules (even though I just switched from > plain Make to Automake) and the approach I've used to work around this > problem is to assume that "Foo.java" will produce "Foo*.class". I > don't know if Automake could use this approach too, since there are > cases where this will glob unrelated files, but it's working like a > charm in my project. Ideally we should look for "Foo.class" and, > maybe, "Foo$*.class", however the `maybe' part is annoying because if > the globbing pattern doesn't match anything, it'll stay as is or, > worse, produce an error with some shells (e.g. zsh with certain > options). > I'd rather deprecate the JAVA primary, and then introduce a new `JARS' primary, to be used e.g. as follows: jar_JARS = foo.jar zardoz_JARS = bar.jar foo_jar_SOURCES = all.java foo.java bar_jar_SOURCES = all.java bar.java bar_jar_JAVACFLAGS = -nowarn bar_jar_JARFLAGS = -J-Xmx48M This should cause the following behaviour: 1. javac will be called (with the `-d' option), to generate .class files from all.java and foo.java, and put them into a "private" directory `.classes/foo_jar/'; 2. similarly, javac will be called (this time also with the `-nowarn' option) to generate .class files from all.java and bar.java, placing them into the directory `.classes/bar_jar/'; 3. jar will be called to build `foo.jar' from all the .class files found in .classes/foo_jar/; 4. similarly, jar will be called (this time with the `-J-Xmx48M' option) to build `bar.jar' from all the .class files in .classes/foo_jar/; 5. "make mostlyclean" will remove the `.classes' directory; 6. "make clean" will also remove foo.jar and bar.jar; 7. "make install" will install foo.jar in $(jardir) (which we could make default to `$(datadir)/jar') and bar.jar in $(zardozdir) (which we expect to be user-defined). As my java foo is pretty weak, I'm not sure how to handle jar manifests, jar entry points, or other jar/javac subtleties and advanced features. Suggestions welcome. > My question now boils down to this: > Has anyone already got some thoughts on how to make Automake play well > with Java projects or what kind of workarounds can I use to leverage > as much of Automake as possible while still building my Java stuff the > way I want it? > > Alternate question: if Java was a brand new language Automake had > never heard of, how would I build my project with Automake without > doing what I'm doing now where I have custom rules for everything and > I need to hook myself into install- and dist-hooks to Do The Right > Thing? > Basically (and as far as my knowledge/understanding goes), you wouldn't; Automake is unfortunately quite unflexible in this regard. Providing your own "all-local", "install-hook" and "uninstall-local" rules is probably the best route to follow. > Like isn't it possible to have a bin_PROGRAMS = foo.jar and > foo_jar_SOURCES = main.java and then tell automake how to transform a > .java into a .class and then how to turn all the .class into a .jar? > It seems that when I try this, Automake dies with "Java source seen > but `GCJ' is undefined". > Yes, because Automake thinks you want to build foo.jar as a binary executable, and so it wants to use gcj to compile it. This happens because you've listed foo.jar in a PROGRAMS primary, which is only meant for binary executables, not scripts or bytecode files (ok, I'm simplifying things a bit here, but the main point stands). > Thanks and sorry for the longish email. > Well, thanks to you for rekindling interest in the Automake Java support :-) Regards, Stefano