tags:

views:

171

answers:

2

I'm writing a Rakefile for a C++ project. I want it to identify #includes automatically, forcing the rebuilding of object files that depend on changed source files. I have a working solution, but I think it can be better. I'm looking for suggestions for:

  • Suggestions for improving my function
  • Libraries, gems, or tools that do the work for me
  • Links to cool C++ Rakefiles that I should check out that do similar things

Here's what I have so far. It's a function that returns the list of dependencies given a source file. I feed in the source file for a given object file, and I want a list of files that will force me to rebuild my object file.

def find_deps( file )
  deps = Array.new
  # Find all include statements
  cmd = "grep -r -h -E \"#include\" #{file}"
  includes = `#{cmd}`
  includes.each do |line|
    dep = line[ /\.\/(\w+\/)*\w+\.(cpp|h|hpp)/ ]
    unless dep.nil?
      deps << dep # Add the dependency to the list
      deps += find_deps( dep )
    end
  end
  return deps
end

I should note that all of my includes look like this right now:

#include "./Path/From/Top/Level/To/My/File.h" // For top-level files like main.cpp 
#include "../../../Path/From/Top/To/My/File.h" // Otherwise

Note that I'm using double quotes for includes within my project and angle brackets for external library includes. I'm open to suggestions on alternative ways to do my include pathing that make my life easier.

+4  A: 

Use the gcc command to generate a Make dependency list instead, and parse that:

g++ -M -MM -MF - inputfile.cpp

See man gcc or info gcc for details.

greyfade
+2  A: 

I'm sure there are different schools of thought with respect to what to put in #include directives. I advise against putting the whole path in your #includes. Instead, set up the proper include paths in your compile command (with -I). This makes it easier to relocate files in the future and more readable (in my opinion). It may sound minor, but the ability to reorganize as a project evolves is definitely valuable.

Using the preprocessor (see @greyfade) to generate the dependency list has the advantage that it will expand the header paths for you based on your include dirs.


Update: see also the Importing Dependencies section of the Rakefile doc for a library that reads the makefile dependency format.

Dave Bacher