Rake and Rant

I was wondering whether anybody has had any experience with both these Ruby
build tools. If so, which one would be more suitable for large projects
that contain both C++ and Java source code?

Rant is a superset of Rake in that it has everything Rake has and more, so
if you are looking for a build tool that uses Ruby as its underlying
language then you should go with Rant. You can use only a subset of it and
pretend it is Rake if you want.

···

On 8/11/07, barcaroller <barcaroller@music.net> wrote:

I was wondering whether anybody has had any experience with both these
Ruby
build tools. If so, which one would be more suitable for large projects
that contain both C++ and Java source code?

Yes, Rake is perfectly useful in large non-ruby projects as a build
tool. According to
(http://railsenvy.com/2007/6/11/ruby-on-rails-rake-tutorial\) Jim
actually created Rake to deal with a Java project. And that link is a
good tutorial too.

Jim has a few tutorials on using Rake with C :

  - http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialIntroduction.rdoc
  - http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialAnotherCExample.red

enjoy,

-jeremy

···

On Sun, Aug 12, 2007 at 03:35:05AM +0900, barcaroller wrote:

I was wondering whether anybody has had any experience with both these Ruby
build tools. If so, which one would be more suitable for large projects
that contain both C++ and Java source code?

--

Jeremy Hinegardner jeremy@hinegardner.org

barcaroller wrote:

I was wondering whether anybody has had any experience with both these Ruby build tools. If so, which one would be more suitable for large projects that contain both C++ and Java source code?

I've used Rake on a few C/C++ projects myself - if you want to see an example of a fairly complex C project using Rake, check out the Rubinius source.

···

--
Alex

Alex Young wrote:

barcaroller wrote:

I was wondering whether anybody has had any experience with both these Ruby build tools. If so, which one would be more suitable for large projects that contain both C++ and Java source code?

I've used Rake on a few C/C++ projects myself - if you want to see an example of a fairly complex C project using Rake, check out the Rubinius source.

I don't think that Rake currently has the concept of a scanner for automatically discovering dependencies such as in header file
hierarchies. SCons for example has this built in. What is the
best way of going about auto generating dependencies within
Rake for C/C++ projects?

I would prefer to use Rake than SCons for C/C++

Brad

david karapetyan wrote:

Rant is a superset of Rake in that it has everything Rake has and more,

Although that may have once been true, it is certainly no longer the
case. Neither Rant nor Rake are supersets of the other, for both have
evolved beyond the early Rake functionality upon which Rant was based.
(Also note that the rake/rant comparison on the rant project page is
quite dated).

-- Jim Weirich

···

--
Posted via http://www.ruby-forum.com/\.

Brad Phelan wrote:

Alex Young wrote:

barcaroller wrote:

I was wondering whether anybody has had any experience with both these Ruby build tools. If so, which one would be more suitable for large projects that contain both C++ and Java source code?

I've used Rake on a few C/C++ projects myself - if you want to see an example of a fairly complex C project using Rake, check out the Rubinius source.

I don't think that Rake currently has the concept of a scanner for automatically discovering dependencies such as in header file
hierarchies. SCons for example has this built in. What is the
best way of going about auto generating dependencies within
Rake for C/C++ projects?

The same as for make - shell out to the compiler, then parse the result. gcc -MM is what I'm familiar with, I presume other compilers have similar switches. Rant does have this built in, but I'm not familiar with it (although having just researched it a little, I think I will make the effort now :slight_smile: )

···

--
Alex

my mistake.

···

On 8/15/07, Jim Weirich <jim@weirichhouse.org> wrote:

david karapetyan wrote:
> Rant is a superset of Rake in that it has everything Rake has and more,

Although that may have once been true, it is certainly no longer the
case. Neither Rant nor Rake are supersets of the other, for both have
evolved beyond the early Rake functionality upon which Rant was based.
(Also note that the rake/rant comparison on the rant project page is
quite dated).

-- Jim Weirich
--
Posted via http://www.ruby-forum.com/\.

The same as for make - shell out to the compiler, then parse the result. gcc -MM is what I'm familiar with, I presume other compilers have similar switches. Rant does have this built in, but I'm not familiar with it (although having just researched it a little, I think I will make the effort now :slight_smile: )

I found

  require 'rake/loaders/makefile'

   file ".depends.mf" => [SRC_LIST] do |t|
     sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}"
   end

   import ".depends.mf"

at

http://docs.rubyrake.org/read/chapter/4

Still a native Ruby solution would be nicer.

Brad

* Brad Phelan <bradphelan@xtargets.com> (2007-08-12) schrieb:

Still a native Ruby solution would be nicer.

Why, is you C compiler a Ruby solution?

mfg, simon .... l

Brad Phelan wrote:

Still a native Ruby solution would be nicer.

If someone wanted to contribute a dependency scanner for their favorite
language to the Rake project, I would be willing to consider it for
inclusion.

A C/C++ scanner shouldn't be that hard to write. Its just that I've not
working in a C/C++ project since starting Rake, so I've never had the
need to write one.

···

--
-- Jim Weirich
--
Posted via http://www.ruby-forum.com/\.

Jim Weirich wrote:

Brad Phelan wrote:

Still a native Ruby solution would be nicer.

If someone wanted to contribute a dependency scanner for their favorite language to the Rake project, I would be willing to consider it for inclusion.

A C/C++ scanner shouldn't be that hard to write. Its just that I've not working in a C/C++ project since starting Rake, so I've never had the need to write one.

--
-- Jim Weirich

With regards to the RANT project http://rubyforge.org/projects/make/
where I nicked the scanner this should do the job.

···

===========================================

module Rake
    module C
       module Include
          def Include.depends(file)
             File.open file do |f|
                txt = f.read
                parse_includes txt
             end
          end

          # Searches for all `#include' statements in the C/C++ source
          # from the string +src+.
          #
          # Returns two arguments:
          # 1. A list of all standard library includes (e.g. #include <stdio.h>).
          # 2. A list of all local includes (e.g. #include "stdio.h").
          def Include.parse_includes(src)
             if src.respond_to? :to_str
                src = src.to_str
             else
                raise ArgumentError, "src has to be a string"
             end
             s_includes =
             l_includes =
             in_block_comment = false
             prev_line = nil
             src.each { |line|
                line.chomp!
                if block_start_i = line.index("/*")
                   c_start_i = line.index("//")
                   if !c_start_i || block_start_i < c_start_i
                      if block_end_i = line.index("*/")
                         if block_end_i > block_start_i
                            line[block_start_i..block_end_i+1] = ""
                         end
                      end
                   end
                end
                if prev_line
                   line = prev_line << line
                   prev_line = nil
                end
                if line =~ /\\$/
                   prev_line = line.chomp[0...line.length-1]
                end
                if in_block_comment
                   in_block_comment = false if line =~ %r|\*/|
                   next
                end
                case line
                when /\s*#\s*include\s+"([^"]+)"/
                   l_includes << $1
                when /\s*#\s*include\s+<([^>]+)>/
                   s_includes << $1
                when %r|(?!//)[^/]*/\*|
                   in_block_comment = true
                end
             }
             [s_includes, l_includes]
          end
       end
    end
end

# RAKE Rule figures out the dependencies for the C file

rule( /\.o$/ =>

       proc do |task_name|
           a =
           name = task_name.sub(/\.[^.]+$/, '.c')
           s_includes, l_includes = Rake::C::Include.depends(name)
           a << name
           a << l_includes
           a
       end

     ) do |t|
      sh "cc #{t.source} -c -o #{t.name}"
end

The scanner is not recursive yet but should be simple
to implement but I have to run ......

Regards

--
Brad Phelan
http://xtargets.com

Brad Phelan wrote:

Jim Weirich wrote:

Brad Phelan wrote:

Still a native Ruby solution would be nicer.

If someone wanted to contribute a dependency scanner for their favorite language to the Rake project, I would be willing to consider it for inclusion.

A C/C++ scanner shouldn't be that hard to write. Its just that I've not working in a C/C++ project since starting Rake, so I've never had the need to write one.

--
-- Jim Weirich

With regards to the RANT project http://rubyforge.org/projects/make/
where I nicked the scanner this should do the job.

===========================================

module Rake
   module C
      module Include
         def Include.depends(file)
            File.open file do |f|
               txt = f.read
               parse_includes txt
            end
         end

         # Searches for all `#include' statements in the C/C++ source
         # from the string +src+.
         #
         # Returns two arguments:
         # 1. A list of all standard library includes (e.g. #include <stdio.h>).
         # 2. A list of all local includes (e.g. #include "stdio.h").
         def Include.parse_includes(src)
            if src.respond_to? :to_str
               src = src.to_str
            else
               raise ArgumentError, "src has to be a string"
            end
            s_includes =
            l_includes =
            in_block_comment = false
            prev_line = nil
            src.each { |line|
               line.chomp!
               if block_start_i = line.index("/*")
                  c_start_i = line.index("//")
                  if !c_start_i || block_start_i < c_start_i
                     if block_end_i = line.index("*/")
                        if block_end_i > block_start_i
                           line[block_start_i..block_end_i+1] = ""
                        end
                     end
                  end
               end
               if prev_line
                  line = prev_line << line
                  prev_line = nil
               end
               if line =~ /\\$/
                  prev_line = line.chomp[0...line.length-1]
               end
               if in_block_comment
                  in_block_comment = false if line =~ %r|\*/|
                  next
               end
               case line
               when /\s*#\s*include\s+"([^"]+)"/
                  l_includes << $1
               when /\s*#\s*include\s+<([^>]+)>/
                  s_includes << $1
               when %r|(?!//)[^/]*/\*|
                  in_block_comment = true
               end
            }
            [s_includes, l_includes]
         end
      end
   end
end

# RAKE Rule figures out the dependencies for the C file

rule( /\.o$/ =>

      proc do |task_name|
          a =
          name = task_name.sub(/\.[^.]+$/, '.c')
          s_includes, l_includes = Rake::C::Include.depends(name)
          a << name
          a << l_includes
          a
      end

    ) do |t|
     sh "cc #{t.source} -c -o #{t.name}"
end

The scanner is not recursive yet but should be simple
to implement but I have to run ......

Regards

--
Brad Phelan
http://xtargets.com

My simple test rake file was

···

++++++++++++++++++++++++++++++++++++++

require 'cscanner'

task :default => 'main.out'

file 'main.out' => [ 'main.o' ] do |t|
   sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
end

+++

and the C/H file was

+++
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
int main ( int argc, char * argv ){
    printf("Hello world");
    return 0;
}

++

#ifndef _MAIN_
#define _MAIN_
typedef struct {
    int a;
    int b;
} Foo;
#endif

and it seemed to work ok