[CMake] Re: Raven, Antwrap, Buildr
Gonzalo Garramuño
ggarra at advancedsl.com.ar
Mon Mar 3 09:13:01 EST 2008
Brandon Van Every wrote:
> On Sun, Mar 2, 2008 at 7:46 PM, Brandon Van Every <bvanevery at gmail.com> wrote:
>> On Sun, Mar 2, 2008 at 7:29 PM, Brandon Van Every <bvanevery at gmail.com> wrote:
>> >
>> > http://www.onjava.com/pub/a/onjava/2007/12/05/introducing-raven-an-elegant-build-for-java.html
>>
>> The comments following this article are interesting. For instance, on syntax:
>>
>> "This is just stupid. The Ruby syntax is horrendous. I'd rather use
>> Groovy than Ruby if I was ever going to use a scripting language. I've
>> never been stuck using Ant either, it does everything I need."
>
It is not the ruby syntax that is horrendous but the rake one. I'm a
true fan of ruby but not of rake. Raven is just a wrapper built on top
of rake to add java functionality.
> - is a :colon in front of something a great idea?
It is a pretty good one. It isn't of course as clean as just a simple
string with no quotes, but then again, you otherwise get quickly in
trouble with local vars. CMake basically does not have local vars (all
are globals) and those are always defined/dealt in SET() commands.
> - why do I have to type |bars| around something?
This is a ruby convention that is somewhat overused in rake. The do
|iter| ... end or { |iter| ... } defines a block with a local
variable to the block which is usually used for iteration or for
construction.
The local variable is usually filled by the caller (usually providing
you with access to *this or self of the object you built).
The advantage is for OO. Consider this:
task :myexe { |t|
t.link_libs = "asdasd"
t.so_version = 1.0
t.call_func
}
With that, you'd basically have an OO approach to setting cmake
properties (and not just properties, you can also run a function defined
in whatever class t is).
That code is somewhat sugar akin to:
t = Rake::Task.new( "myexe" )
t.link_libs = 'asdasd'
t.so_version = 1.0
t.call_func
The benefit of not using the constructor directly is that the api is
easier to change. Also, at the end of the block (end or end bracket), a
lot of other internal hidden code may run (for example, validating
dependencies or parameters right away)-
> From other context
> I read, it seems to be a decorator for a symbol. So I guess if you
> forgot the decorator, you'd be in trouble. I hope that always throws
> an intelligible error.
If your forget the decorator, it is interpreted as a local variable. As
no such variable would likely exist, you'd get an error.
Obviously this flexibility does allow you do, for example:
#
# 3 targets, each with same dependency.
#
targets = [ :target1, :target2, :target3 ]
targets.each { |name|
task name { |t|
t.dependencies = %w( dep1 dep2 dep3 )
}
}
Here the symbol is replaced with a local variable called 'name' which
changes on each iteration.
> - why put both [square brackets] and {curly braces} around something?
[square brackets] is an array, {} is a hash. In the example you
posted, you have an array of hashes, which is as ugly as it can get.
> Is that so we can be terse about minimum versions?
No. It is just that the api you posted seems to require an array of
hashes. Pretty ugly api, if you ask me. Having a hash that contains
arrays (or other hashes) is more common.
> - how, in any universe, could this possibly be preferable to
> add_dependencies(target dep1 dep2 dep3...) ?
>
An api (say swig wrapped) that would be identical to cmake would look like;
add_dependency :target, :dep1, :dep2, :dep3
Here I am using symbols, but you could also make the api use strings
(which forces to use quotes) or accept both (which is usually the case
with ruby).
add_dependency "target", "dep1", "dep2", "dep3"
or (if you want to make it more explicit as rake):
add_dependency :target => %w( dep1 dep2 dep3 )
In a more extensible api that would use hashes for values, it would look
like:
add_dependency :target, :dependencies => %w( dep1 dep2 dep3 )
or, like rake does, use an OO approach:
task :target { |t|
t.dependencies = %w( dep1 dep2 dep3 )
}
In ruby it is pretty trivial to provide both types of interfaces (even
with swig for C++ code). Rake only provides an OO api.
> Only Ruby people are going to see this syntax as an advantage. It's
> worth remembering that Ruby got popular not because of the language,
No, ruby got popular with the language and is highly respected for it.
Rails made it popular for the web.
Talking about rails, rails uses another form of DSL, which is class based.
Basically, a cmake api based like rails would look more like:
class MyExe < CMake::Executable
dependencies %w( dep1 dep2 dep3 )
def compile
# optionally override CMake::Executable compile routine
end
end
A class DSL really does not make that much sense for a build system, but
it is obviously great for actual coding the core of the system.
P.S. BTW, rake is something like a 200 line script only, so it is
extremely bare-bones.
--
Gonzalo Garramuño
ggarra at advancedsl.com.ar
AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy
More information about the CMake
mailing list