class RakeCompile::Target

Attributes

libraries[RW]
name[R]
objects[R]
pch[RW]

Public Class Methods

define_executable_task(name) { |target| ... } click to toggle source
# File lib/rake-compile/target.rb, line 16
def self.define_executable_task(name)
  target = Target.new(name)

  yield target

  target.define_task() do |t|
    t.create_executable()
  end
end
define_static_library_task(name) { |target| ... } click to toggle source
# File lib/rake-compile/target.rb, line 26
def self.define_static_library_task(name)
  target = Target.new(name)

  yield target

  target.define_task() do |t|
    t.create_static_library()
  end
end
new(a_name) click to toggle source
# File lib/rake-compile/target.rb, line 36
def initialize(a_name)
  @name = a_name
  @objects = []

  self.setup_pch_task()
end

Public Instance Methods

add_object(source, object, flags=nil) click to toggle source
# File lib/rake-compile/target.rb, line 126
def add_object(source, object, flags=nil)
  object = File.absolute_path(object)
  @objects << object

  define_object_dependencies(source, object, flags)
end
add_object_from_source(source, flags=nil) click to toggle source
# File lib/rake-compile/target.rb, line 120
def add_object_from_source(source, flags=nil)
  object = File.join(RakeCompile::Application.app.build_directory, source.ext('.o'))

  add_object(source, object, flags)
end
add_objects_from_sources(filelist, flags=nil) click to toggle source
# File lib/rake-compile/target.rb, line 116
def add_objects_from_sources(filelist, flags=nil)
  filelist.each { |source| self.add_object_from_source(source, flags) }
end
append_pch_to_flags(pch_file, flags) click to toggle source
# File lib/rake-compile/target.rb, line 61
def append_pch_to_flags(pch_file, flags)
  flags = flags.dup

  # Remove the extension.  I'm not certain why this is necessary, but clang freaks out if you do not.
  pch_file = pch_file.ext('')
  pch_flag = " -include '#{pch_file}'"
  flags[:cc_flags] += pch_flag
  flags[:cpp_flags] += pch_flag
  flags
end
create_executable() click to toggle source
# File lib/rake-compile/target.rb, line 89
def create_executable()
  FileUtils.rm_f(self.name)

  RakeCompile.log("BIN".light_blue, self.name)
  linker = 'c++ -std=c++11'

  inputs = self.objects.join("' '")
  libs = self.libraries.join("' '")

  cmd = "#{linker}"
  cmd += " -o '#{self.name}'"
  cmd += " '#{inputs}'"
  cmd += " '#{libs}'" if libs.length > 0
  cmd += " #{RakeCompile::Application.app.full_ld_flags}"

  Rake::sh(cmd)
end
create_static_library() click to toggle source
# File lib/rake-compile/target.rb, line 107
def create_static_library()
  FileUtils.rm_f(self.name)

  inputs = self.objects.join("' '")

  RakeCompile.log("LIB".light_blue, self.name)
  Rake::sh("/usr/bin/ar crs '#{self.name}' '#{inputs}'")
end
define_object_dependencies(source, object, flags=nil) click to toggle source
# File lib/rake-compile/target.rb, line 133
def define_object_dependencies(source, object, flags=nil)
  flags ||= RakeCompile::Application.app.flags

  source = File.absolute_path(source)
  dependency_file = "#{object}.deps"

  deps = []
  if File.exist?(dependency_file)
    deps = dependencies_from_deps_file(dependency_file)

    # if it came back empty, remove the file
    FileUtils::rm(dependency_file) if deps.empty?
  end

  dir = File.dirname(dependency_file)
  directory dir

  # define a file task to create the deps file, which
  # depends on the dependencies themselves.  Also
  # depends on the directory that contains it
  if self.pch && (object != self.pch)
    file(dependency_file => self.pch)
    flags = append_pch_to_flags(self.pch, flags)
  end

  file dependency_file => dir
  file dependency_file => deps do
    RakeCompile.log("DEPS".red, object)
    deps = dependencies_for_source(source, flags)

    File.open(dependency_file, "w+") do |file|
      file << deps.join("\n")
      file << "\n"
    end
  end

  # and, now define the actual object file itself
  file object => [dir, dependency_file] do
    s = RakeCompile.compiler_for_source(source, flags)
    s += " -o '#{object}'"
    s += " -c '#{source}'"

    RakeCompile.log("OBJ".yellow, object)
    Rake::sh(s)
  end

  # make sure these are cleaned
  CLEAN.include(dependency_file)
  CLEAN.include(object)
end
define_task() { |self| ... } click to toggle source
# File lib/rake-compile/target.rb, line 72
def define_task()
  CLOBBER.include(self.name)

  dir = File.dirname(self.name)
  directory dir

  # Capture libraries, for use in the block below.  We need to dup the array,
  # because the app copy gets mutated, and we don't just want a reference.
  self.libraries = RakeCompile::Application.app.libraries.dup

  prereqs = [dir, self.objects, self.libraries].flatten

  multifile self.name => prereqs do
    yield self
  end
end
dependencies_for_source(source, flags) click to toggle source
# File lib/rake-compile/target.rb, line 184
def dependencies_for_source(source, flags)
  s = RakeCompile::compiler_for_source(source, flags)
  s += " -MM "
  s += "'#{source}'"

  puts s if verbose() != false
  output = `#{s}`.chomp()

  dependencies = output.split()
  dependencies.delete_at(0)  # remove the first element, which is the object file itself
  
  dependencies.reject! { |x| x.empty? || x == '\\' } # remove blanks and line continuations

  dependencies.collect { |x| File.absolute_path(x) }
end
dependencies_from_deps_file(path) click to toggle source
# File lib/rake-compile/target.rb, line 200
def dependencies_from_deps_file(path)
  deps = []
  File.open(path, 'r') do |file|
    deps = file.readlines()
  end

  deps.collect {|x| x.chomp() }.reject {|x| x.empty? }
end
setup_pch_task() click to toggle source
# File lib/rake-compile/target.rb, line 43
def setup_pch_task
  return if RakeCompile::Application.app.pch.nil?

  pch_source = RakeCompile::Application.app.pch
  header_output = File.join(RakeCompile::Application.app.build_directory, pch_source)
  header_output = File.absolute_path(header_output)
  self.pch = header_output + '.gch'

  define_object_dependencies(pch_source, self.pch)

  # The source header for a pch needs to be in the same location for some
  # compilers. So, we need to copy it.
  file self.pch => header_output
  file header_output => pch_source do
    FileUtils.cp(pch_source, header_output)
  end
end