Re: Regarding the JAVA primary

2010-04-25 Thread Ralf Wildenhues
* NightStrike wrote on Sat, Apr 24, 2010 at 02:08:43AM CEST:
 On Mon, Apr 19, 2010 at 2:25 PM, John Calcote john.calc...@gmail.com wrote:
  A problem I foresee is providing the globbing functionality to makefile
  commands. We'd almost need a new auxiliary script (like install-sh) to
  generate lists of files from such glob specs. Not sure yet from where the
  primary functionality would come -- perhaps a java utility, so that the same
  level of portability would be available to java builds as the source that's
  being built. That is, if someone uses the JAVA primary, he/she can expect to
  be required to have additional build functionality available, in the form of
  a JVM and javac compiler. Just a thought.
 
 You can resolve the globbing spec at automake time instead of make
 time.  That way, Makefile.in still contains a static list.

Would you consider the following semantics intuitive?

  edit Makefile.am ...
  run automake
  add another java file
  build fails due to new java file not being considered

Remember that it would not be a good idea to rerun automake at each
instance of 'make'.

Here's another reason against wildcards in prerequisites: they are not
portable to non-GNU make.  Period.  GNU make has $(wildcard ...) which
is well-defined, and GNU make also most of the time does the right thing
when you place a shell-style wildcard in a target or prerequisite list
(but see
http://www.gnu.org/software/make/manual/html_node/Wildcard-Pitfall.html
for pitfalls!), but non-GNU make will normally not do what you expect.

More precisely, while some non-GNU makes seem to expand wildcards in
prerequisite lists, they don't actually match the expanded words against
other targets listed in the makefile (tested with some versions of IRIX,
AIX, and Solaris make).  I found only FreeBSD make to do the matching
besides GNU make.  Tested with this script in a fresh directory:

cat Makefile \EOF
all: all1 all2 all3
echo updating $@
all1: newer*
echo updating $@
all2: older*
echo updating $@
all3: outdated*
echo updating $@
new* old* outd*:
echo updating $@
outd*: FORCE
FORCE:
EOF
touch older1 older2 outdated1 outdated2
sleep 1
touch all1 all2 all3
sleep 1
touch newer1 newer2
make

Only GNU and FreeBSD make will remake all1, outdated1, outdated2, and all2
before remaking all.  The rest will only remake all1 before all.

So, in case you have generated files, that'll just silently break your
dependencies.

I still need to rewrite this for an addition to the FAQ.

Cheers,
Ralf




Re: Regarding the JAVA primary

2010-04-23 Thread NightStrike
On Mon, Apr 19, 2010 at 2:25 PM, John Calcote john.calc...@gmail.com wrote:
 A problem I foresee is providing the globbing functionality to makefile
 commands. We'd almost need a new auxiliary script (like install-sh) to
 generate lists of files from such glob specs. Not sure yet from where the
 primary functionality would come -- perhaps a java utility, so that the same
 level of portability would be available to java builds as the source that's
 being built. That is, if someone uses the JAVA primary, he/she can expect to
 be required to have additional build functionality available, in the form of
 a JVM and javac compiler. Just a thought.

You can resolve the globbing spec at automake time instead of make
time.  That way, Makefile.in still contains a static list.

If you went this route, I'd be curious how quickly someone ports it to
other primaries :)




Regarding the JAVA primary

2010-04-19 Thread John Calcote

Hi Ralf,

I've been thinking a lot about the JAVA primary lately. It turns out 
that Automake's handling of Java sources is pretty efficient. 
Experiments indicate that building ~500 Java source files in a single 
command takes about 15 seconds on a 1.8 GHz CPU with 512 MB RAM. That 
same set of 500 sources, built individually can take upwards of 500 
seconds - a 40 times increase in compile time. (GNU Make, O'Reilly)


In other words, it's simply better to not manage individual 
source/object dependencies in Java. You win the battle, so to speak -- 
but you lose the war.


Since the current implementation of the JAVA primary is not managing 
individual source/object dependencies (something that's difficult to do 
anyway because of inner and anonymous class definitions), would it not 
be prudent to remove the restriction regarding needing to specify all 
source files individually in Makefile.am -- at least for the JAVA primary?


Builds in the Java world generally specify source files found within a 
subtree using a globbing mechanism, with optionally specified inclusions 
and exclusions. And the layout of that subtree defines the packages to 
which classes belong. Would it not be fair to say that all files found 
matching the source specification within a specified subtree are 
distributed within the directory layout to which they belong? In other 
words, distribution (for Java sources only) would include the same set 
of files specified in the Java source globbing pattern. Here's an example:


sources = src/**/*.java
exclude = src/examples/*.java

Distributed Java sources would include everything defined by /sources/. 
Excluded files would be excluded from the build, but not from distribution.


I'm not stealing this concept entirely from ant. Most of the Java IDE's 
(NetBeans, IntelliJ, Eclipse, etc) also use almost the same mechanism 
for specifying sources belonging to a particular build.


I recognize that this is a significant deviation from existing Autotools 
methodology, but I'm not sure we can make any real forward progress in 
Autotools Java builds without making a few such concessions.


A problem I foresee is providing the globbing functionality to makefile 
commands. We'd almost need a new auxiliary script (like install-sh) to 
generate lists of files from such glob specs. Not sure yet from where 
the primary functionality would come -- perhaps a java utility, so that 
the same level of portability would be available to java builds as the 
source that's being built. That is, if someone uses the JAVA primary, 
he/she can expect to be required to have additional build functionality 
available, in the form of a JVM and javac compiler. Just a thought.


One thing we can do at this point is to define JAR and WAR primaries 
that build and install (in appropriate locations), .jar and .war files. 
I've got a few ideas I'll try to codify and send out shortly.


John




Re: Regarding the JAVA primary

2010-04-19 Thread Ralf Wildenhues
Hi John,

* John Calcote wrote on Mon, Apr 19, 2010 at 08:25:22PM CEST:
 Since the current implementation of the JAVA primary is not managing
 individual source/object dependencies (something that's difficult to
 do anyway because of inner and anonymous class definitions), would
 it not be prudent to remove the restriction regarding needing to
 specify all source files individually in Makefile.am -- at least for
 the JAVA primary?

I guess that would be possible, at least technically.

 Builds in the Java world generally specify source files found within
 a subtree using a globbing mechanism, with optionally specified
 inclusions and exclusions. And the layout of that subtree defines
 the packages to which classes belong. Would it not be fair to say
 that all files found matching the source specification within a
 specified subtree are distributed within the directory layout to
 which they belong? In other words, distribution (for Java sources
 only) would include the same set of files specified in the Java
 source globbing pattern.

The issue is that it goes against one principle otherwise followed
throughout Automake: the user cannot have junk files in her source nor
her build tree that match the patterns.  At least for some users, this
is a feature; I for one have unfinished files in my source trees, or
even in a version control branch.  I do admit though that distributed
version control makes this less relevant.

 I recognize that this is a significant deviation from existing
 Autotools methodology, but I'm not sure we can make any real forward
 progress in Autotools Java builds without making a few such
 concessions.

We can have new semantics; in case of doubt we can enable them under a
new Automake option only.

 A problem I foresee is providing the globbing functionality to
 makefile commands. We'd almost need a new auxiliary script (like
 install-sh) to generate lists of files from such glob specs.

If it's not very complex it can be done in a makefile variable
scriptlet.

I haven't understood the JAR and WAR notes you wrote about.

Cheers,
Ralf




Re: Regarding the JAVA primary

2010-04-19 Thread Steffen Dettmer
On Mon, Apr 19, 2010 at 8:25 PM, John Calcote john.calc...@gmail.com wrote:
 [...]
 Builds in the Java world generally specify source files found
 within a subtree using a globbing mechanism, with optionally
 specified inclusions and exclusions.

Yes, they do. BTW, does anyone know why?

With some sarcasm someone could tell that it is done in this way
because with Java you need to make heaps of files (e.g. one for
every public exception), but maybe it has a good reason?

We use some very old and surely bad custom automake rules to
compile java sources. Ages ago we also had some wildcard (`find')
rules (inspired by ant assuming `this would be the good way to
go'). Those rules collected the files, but we changed them to use
a list of file names, which seemed much cleaner and solved some
issues (which of course could had been solved in other ways,
too).

One motivation for this change was that our make rules that
generated the exception source code files (many differing more or
less just in the name and some `String name ...') and people
forgot to add the files, so if existing for them they had been
built but not for others where the files were not updated (and
the new gensrc files were missing). This resulted in an
incomplete jar file and unfortunately when using this jar a
compilation error was flagged out in the wrong package... unit
tests did not helped because of course also missing in the
incomplete jars (and the make check scheme we used also used a
wildcard approach to collect the unit tests to be executed).
Strange things happend when switching between branches (where
typically the number and kind of exceptions changed etc).

I disliked that when by some problem almost all sources would get
lost in a sandbox (e.g. if switching to a bad / incomplete tag),
make (and even make check!) succeeded.

On `tree conflicts' (one changed a file, another moved it) it
could even happen to have two times the same functionality in a
jar...

To build a list of files why not open Makefile.am in $EDITOR,
like vim or emacs, and insert the file list here (in vim, you may
start a line `java_source = \' and on the next blank line use
`!!find . -name *.java -exec echo {} \\ ;'
which works except for the last file, which ends with a `\'.). No
need to make this at make run time, or is there any?

By this, cvs diff (or whichever SCM tool is used) easily shows
the included files which is easier to review I think.

Using wildcards IMHO means to logically `include' the directory
contents to the Makefile. I think you cannot even use it as
dependency (and thus I'd guess the jars would be resigned on each
make run, even if no file changed?).

What is the advantage of using find magic and make time?

How do you handle your java.in files?
How are you safe to get old generated files out the jar (if
removed from gensrc, they still are in builddir and the make
clean rule may not even take it any longer - how to notice?).

I'm afraid the find/wildcard approach only works for simple
builds - but those could also be done by ant I think...

 I'm not stealing this concept entirely from ant.

(yeah strange tool that, but different topic :-))

oki,

Steffen




Re: Regarding the JAVA primary

2010-04-19 Thread John Calcote

Hi Steffen,

On 4/19/2010 1:22 PM, Steffen Dettmer wrote:

On Mon, Apr 19, 2010 at 8:25 PM, John Calcotejohn.calc...@gmail.com  wrote:
  [...]
   

Builds in the Java world generally specify source files found
within a subtree using a globbing mechanism, with optionally
specified inclusions and exclusions.
 

Yes, they do. BTW, does anyone know why?

With some sarcasm someone could tell that it is done in this way
because with Java you need to make heaps of files (e.g. one for
every public exception), but maybe it has a good reason?

We use some very old and surely bad custom automake rules to
compile java sources. Ages ago we also had some wildcard (`find')
rules (inspired by ant assuming `this would be the good way to
go'). Those rules collected the files, but we changed them to use
a list of file names, which seemed much cleaner and solved some
issues (which of course could had been solved in other ways,
too).
   


Actually, the only thing bad about the current JAVA primary make rules 
is that the command line length may easily be exceeded with very large 
file sets (in fact, with hundreds of files, it surely will be exceeded 
on some platforms). But this problem can easily be fixed by dumping all 
of the source files into a temporary text file (filename), and then by 
using @filename on the javac command line.



One motivation for this change was that our make rules that
generated the exception source code files (many differing more or
less just in the name and some `String name ...') and people
forgot to add the files, so if existing for them they had been
built but not for others where the files were not updated (and
the new gensrc files were missing). This resulted in an
incomplete jar file and unfortunately when using this jar a
compilation error was flagged out in the wrong package... unit
tests did not helped because of course also missing in the
incomplete jars (and the make check scheme we used also used a
wildcard approach to collect the unit tests to be executed).
Strange things happend when switching between branches (where
typically the number and kind of exceptions changed etc).
   


Yes, Java does promote the use of many source files - not necessarily a 
bad thing, as this could be seen to promote modular design, if used 
correctly and wisely. I tend to use static inner classes to keep 
relevant things together and to reduce the number of source files. The 
nice thing about this approach is that it's generally fairly easy to see 
where a class should be defined at the outer scope (and thus in its own 
source file), or within another class.



I disliked that when by some problem almost all sources would get
lost in a sandbox (e.g. if switching to a bad / incomplete tag),
make (and even make check!) succeeded.

On `tree conflicts' (one changed a file, another moved it) it
could even happen to have two times the same functionality in a
jar...

To build a list of files why not open Makefile.am in $EDITOR,
like vim or emacs, and insert the file list here (in vim, you may
start a line `java_source = \' and on the next blank line use
`!!find . -name *.java -exec echo {} \\ ;'
which works except for the last file, which ends with a `\'.). No
need to make this at make run time, or is there any?

By this, cvs diff (or whichever SCM tool is used) easily shows
the included files which is easier to review I think.

Using wildcards IMHO means to logically `include' the directory
contents to the Makefile. I think you cannot even use it as
dependency (and thus I'd guess the jars would be resigned on each
make run, even if no file changed?).

What is the advantage of using find magic and make time?

How do you handle your java.in files?
How are you safe to get old generated files out the jar (if
removed from gensrc, they still are in builddir and the make
clean rule may not even take it any longer - how to notice?).

I'm afraid the find/wildcard approach only works for simple
builds - but those could also be done by ant I think...
   


All very good points - and all issues that Automake has been designed to 
overcome. Many folks don't like the requirement that all source files 
must be specified statically in Makefile.am. I'm not one of these 
people. I tend to agree with you. For Java, I think it's a matter of 
developer convenience that sources in a tree are specified with a 
globbing pattern. It's not just that there are a lot of files, but also 
that they tend to be spread around the source tree because they belong 
to various packages that are defined by their location within the source 
tree.


I can certainly see how we may want to stick with the Automake static 
source file specification rules for the reasons you point out. In this 
case, it becomes more of an evangelistic documentation issue. :) That 
is, we might be wise to add a chapter to the Automake manual describing 
the value that comes from Automake's position in this matter. Heaven 
knows, we've answered the question on the 

Re: Regarding the JAVA primary

2010-04-19 Thread Ralf Wildenhues
* John Calcote wrote on Mon, Apr 19, 2010 at 09:52:51PM CEST:
 I can certainly see how we may want to stick with the Automake
 static source file specification rules for the reasons you point
 out. In this case, it becomes more of an evangelistic documentation
 issue. :) That is, we might be wise to add a chapter to the Automake
 manual describing the value that comes from Automake's position in
 this matter. Heaven knows, we've answered the question on the
 mailing list more than enough times!

There already exists a FAQ entry on this.  If it's not complete, patches
are welcome to fix that.

Thanks,
Ralf