You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@buildr.apache.org by Oliver Frommel <of...@linuxnewmedia.de> on 2010/02/19 13:49:05 UTC
Always compiling
Hi there,
after some try and error I managed to create a buildfile for a small
Scala project that uses some artifacts from Maven repo and some local
libs. However every time I am running buildr it compiles the source code
files again, even if nothing has changed. Is this the default behaviour
or is there anything I can do to change it?
Please point me to anything else I can improve in my buildfile, too :)
This is my buildfile:
require 'buildr/scala'
repositories.remote << 'http://www.ibiblio.org/maven2'
SLF4JJDK = artifact('org.slf4j:slf4j-jdk14:jar:1.5.8')
SLF4JAPI = artifact('org.slf4j:slf4j-api:jar:1.5.8')
LOG4J = artifact('log4j:log4j:jar:1.2.15')
configgy_jar = file('libs/configgy-1.5.jar')
CONFIGGY = artifact('configgy:configgy:jar:1.5').from(configgy_jar)
mina_jar= file('libs/mina-core.jar')
MINA = artifact('mina:mina:jar:2.0-M6').from(mina_jar)
specs_jar= file('libs/specs-1.6.2.jar')
SPECS = artifact('specs:specs:jar:1.6.2').from(specs_jar)
naggati_jar= file('libs/naggati-0.7.2.jar')
NAGGATI = artifact('naggati:naggati:jar:0.7.2').from(naggati_jar)
define 'smtpd' do
project.version = '0.1.0'
compile.from('src').with SLF4JAPI, SLF4JJDK, MINA, CONFIGGY, NAGGATI,
SPECS, LOG4J
package(:jar).with :manifest=>_('MANIFEST.MF')
task :run => :compile do
command = "scala -cp
target/classes:#{CONFIGGY}:#{MINA}:#{SPECS}:#{NAGGATI}:#{SLF4JJDK}:#{SLF4JAPI}
com.programmingscala.smtpd.Main"
print "executing #{command}"
system command
end
end
Thanks for your help
Oliver
Re: Always compiling
Posted by Daniel Spiewak <dj...@gmail.com>.
The problem is that the Scala compiler is really bad at figuring out
what files need recompilation. So, rather than risking false
negatives, scalac recompiles everything every time. We do try to
mitigate this somewhat by looking at file modifications, but we can
only do it if all of the files contain one and only one class/trait of
the same name as the file (Java-style). Objects also break the trick,
so it's really not worth striving for.
I have looked at porting the incremental compilation detection from
SBT, but unfortunately it is a non-trivial task which I don't have
time for right now.
Daniel
On Feb 19, 2010, at 6:49 AM, "Oliver Frommel"
<of...@linuxnewmedia.de> wrote:
> Hi there,
>
> after some try and error I managed to create a buildfile for a small
> Scala project that uses some artifacts from Maven repo and some local
> libs. However every time I am running buildr it compiles the source
> code
> files again, even if nothing has changed. Is this the default
> behaviour
> or is there anything I can do to change it?
>
> Please point me to anything else I can improve in my buildfile, too :)
>
> This is my buildfile:
>
> require 'buildr/scala'
>
> repositories.remote << 'http://www.ibiblio.org/maven2'
>
> SLF4JJDK = artifact('org.slf4j:slf4j-jdk14:jar:1.5.8')
> SLF4JAPI = artifact('org.slf4j:slf4j-api:jar:1.5.8')
> LOG4J = artifact('log4j:log4j:jar:1.2.15')
>
> configgy_jar = file('libs/configgy-1.5.jar')
> CONFIGGY = artifact('configgy:configgy:jar:1.5').from(configgy_jar)
>
> mina_jar= file('libs/mina-core.jar')
> MINA = artifact('mina:mina:jar:2.0-M6').from(mina_jar)
>
> specs_jar= file('libs/specs-1.6.2.jar')
> SPECS = artifact('specs:specs:jar:1.6.2').from(specs_jar)
>
> naggati_jar= file('libs/naggati-0.7.2.jar')
> NAGGATI = artifact('naggati:naggati:jar:0.7.2').from(naggati_jar)
>
> define 'smtpd' do
> project.version = '0.1.0'
> compile.from('src').with SLF4JAPI, SLF4JJDK, MINA, CONFIGGY, NAGGATI,
> SPECS, LOG4J
> package(:jar).with :manifest=>_('MANIFEST.MF')
> task :run => :compile do
> command = "scala -cp
> target/classes:#{CONFIGGY}:#{MINA}:#{SPECS}:#{NAGGATI}:#{SLF4JJDK}:#
> {SLF4JAPI}
> com.programmingscala.smtpd.Main"
> print "executing #{command}"
> system command
> end
> end
>
> Thanks for your help
> Oliver
Re: Always compiling
Posted by Daniel Spiewak <dj...@gmail.com>.
> Most likely you have a source file (Foo.scala) that does not generate an
> equivalent class file (Foo.class).
>
> This pattern is currently required to only recompile sources that have
> changed. (Scala 2.8 offers a better way but this feature has not been
> integrated yet).
>
Done in r925720. Compiler-level change detection is now enabled by default
when using the 2.8 (or greater) compiler. The one caveat is that any use of
joint-compilation will cause Buildr to fall back on all-or-nothing
file-based change detection. This is only because I haven't had a chance to
test joint compilation in the presence of compiler-level change detection,
and I'm a little concerned about the compiler being overly-optimistic.
I did take the time to document the feature, as well as provide instructions
for using Buildr with Scala 2.8 (something we seemed to be lacking). Enjoy!
Daniel
Re: Always compiling
Posted by Alex Boisvert <al...@gmail.com>.
On Fri, Feb 19, 2010 at 7:59 AM, Oliver Frommel
<of...@linuxnewmedia.de>wrote:
> Alex Boisvert schrieb:
> > On Fri, Feb 19, 2010 at 4:49 AM, Oliver Frommel
> > <of...@linuxnewmedia.de>wrote:
> >
> >> after some try and error I managed to create a buildfile for a small
> >> Scala project that uses some artifacts from Maven repo and some local
> >> libs. However every time I am running buildr it compiles the source code
> >> files again, even if nothing has changed. Is this the default behaviour
> >> or is there anything I can do to change it?
> >>
> >
> > Most likely you have a source file (Foo.scala) that does not generate an
> > equivalent class file (Foo.class).
> >
>
> I see. How can I fix it? Is there no way to "hard code" dependencies
> like that, like in classic make, where I could write
>
> someCrazyClassname.class: src/main/scala/com/example/Foo.scala
>
That's not (easily) possible under the current scheme.
> What can you do anyway, when a Java/Scala source gets compiled to many
> class files?
>
Many .class files doesn't matter, as long as at least Foo.scala -> Foo.class
then you don't have to worry about it producing other ones. They will
always be recompiled correctly. The only waste here is that it may
recompile many classes in a single file whereas it could have recompile only
a single one. It's up to you to break it down into multiple file if that's
an issue.
alex
Re: Always compiling
Posted by Oliver Frommel <of...@linuxnewmedia.de>.
Alex Boisvert schrieb:
> On Fri, Feb 19, 2010 at 4:49 AM, Oliver Frommel
> <of...@linuxnewmedia.de>wrote:
>
>> after some try and error I managed to create a buildfile for a small
>> Scala project that uses some artifacts from Maven repo and some local
>> libs. However every time I am running buildr it compiles the source code
>> files again, even if nothing has changed. Is this the default behaviour
>> or is there anything I can do to change it?
>>
>
> Most likely you have a source file (Foo.scala) that does not generate an
> equivalent class file (Foo.class).
>
I see. How can I fix it? Is there no way to "hard code" dependencies
like that, like in classic make, where I could write
someCrazyClassname.class: src/main/scala/com/example/Foo.scala
What can you do anyway, when a Java/Scala source gets compiled to many
class files?
Best
Oliver
Re: Always compiling
Posted by Alex Boisvert <al...@gmail.com>.
On Fri, Feb 19, 2010 at 4:49 AM, Oliver Frommel
<of...@linuxnewmedia.de>wrote:
> after some try and error I managed to create a buildfile for a small
> Scala project that uses some artifacts from Maven repo and some local
> libs. However every time I am running buildr it compiles the source code
> files again, even if nothing has changed. Is this the default behaviour
> or is there anything I can do to change it?
>
Most likely you have a source file (Foo.scala) that does not generate an
equivalent class file (Foo.class).
This pattern is currently required to only recompile sources that have
changed. (Scala 2.8 offers a better way but this feature has not been
integrated yet).
You can run 'buildr --trace' and the logs should tell you which
recompilation is needed, e.g.,
** Invoke sugarcube:test:compile (first_time, not_needed)
Compile needed because source file
/home/boisvert/foo/src/main/scala/com/example/Foo.scala has no corresponding
/home/boisvert/foo/target/classes/com/example/Foo.class
alex