class Rmk::GCov

Call Doxygan to extract documentation

Constants

GCOVCLEAN
GCOVDATA
GCOVFILES
SUMMARY
TESTPREFIX

TODO: separate #tests

Attributes

basename[RW]

base file name for html/xml output (default: 'coverage')

branches[RW]

whether #gcovr shows #branches (default: false)

format[RW]

output of #gcovr: :html, :html_details, :xml, :xml_pretty, empty (default)

gcovr[RW]

#gcovr binary

options[RW]

extra #options to #gcovr

tests[R]

#tests that are to be executed

Public Class Methods

new() click to toggle source
Calls superclass method Rmk::Processor.new
# File tools/gcov.rb, line 30
def initialize
  super

  @slot = SLOTS[:test]
  @requires = [ CC, CXX, LD ]

  data = tool_params(:GCov, generator.configuration)
  @gcovr = data[:gcovr]
  @format = data[:format]
  @branches = data[:branches]
  @options = data[:options]
  @basename = data[:basename]

  generator.add_file test_files
  generator.add_file SUMMARY

  # Note: Does it make sense to separate tests? Is profile information updated?
  #       Should we delete .gcno / .gcda files?

  # TODO: test arguments (hash?)

  # TODO: extra tool "run_tests" ?
end

Public Instance Methods

active?() click to toggle source
# File tools/gcov.rb, line 135
def active?
  @active ||= ld.coverage?
end
define_test(id,command: nil,arguments: nil) click to toggle source

Define a test.

An empty command will be replaced by id.

If command does not contain +“/”+ the build directory is used as path.

# File tools/gcov.rb, line 64
def define_test(id,command: nil,arguments: nil)
  # TODO: optional 'dependencies'
  raise "define_test expects String as test id" unless id.is_a?(String)
  raise "gcov: Invalid test id '#{id}'" if id.empty? || id =~ /^\s"\\$/
  command = id unless command
  command = "$builddir/#{command}" unless command.include?('/')
  id=id.gsub('/','_').gsub('.','_')

  if tests.any? { |t| t[:id] == id }
    raise "gcov: multiple definitions for test '#{id}'"
  end

  tests << {
    id: id,
    command: command, arguments: arguments,
    out: "#{TESTPREFIX}#{id}"
  }
end
define_tests(*args) click to toggle source

Define multiple #tests.

Each argument is either a single test id

# File tools/gcov.rb, line 86
def define_tests(*args)
  args.each do |arg|
    if arg.is_a?(Symbol)
      raise %Q(gcov: 'define_tests' is invalid, did you forget '{}'?)
    end
    if arg.is_a?(Hash)
      raise "gcov: 'define_tests' expects field ':id'" unless arg[:id]
      define_test(arg[:id],command: arg[:command], arguments: args[:arguments])
    else
      define_test(arg)
    end
  end
end
exclude() click to toggle source
# File tools/gcov.rb, line 108
def exclude
  @exclude ||= []
end
exclude!(*args) click to toggle source
# File tools/gcov.rb, line 112
def exclude!(*args)
  @exclude = args
end
filter() click to toggle source
# File tools/gcov.rb, line 100
def filter
  @filter ||= []
end
filter!(*args) click to toggle source
# File tools/gcov.rb, line 104
def filter!(*args)
  @filter = args
end
gcovr_format_options() click to toggle source
# File tools/gcov.rb, line 116
def gcovr_format_options
  f = case format
      when :html then "--html-o $builddir/#{basename}.html"
      when :html_details then "--html-details -o $builddir/#{basename}.html"
      when :xml, :x then "--xml -o $builddir/#{basename}.xml"
      when :xml_pretty then "--xml-pretty -o $builddir/#{basename}.xml"
      when '', nil then ''
      else
        raise "Invalid format '#{format}' for gcovr output!"
      end
  return "#{f} --html-title $project" unless ld.vendor == :clang
  f
end
gcovr_report_options() click to toggle source
# File tools/gcov.rb, line 130
def gcovr_report_options
  return '-b' if branches
  return ''
end
ninja_build(writer = generator.ninja) click to toggle source
# File tools/gcov.rb, line 186
def ninja_build(writer = generator.ninja)
  writer.build(GCOVCLEAN,'gcov_clean', [], # Note: copied from generator:
               implicit: generator.rmakefile_deps.map { |f| File.expand_path(f.to_s) })
  generator.add_to_intermediate_target(:gcov_runtests, test_files)
  tests.each do |test|

    exe = ld.generated_executables.find_all { |e| e == test[:command] }

    writer.build(test[:out],"gcov_runtest_#{test[:id]}",
                 [ GCOVCLEAN, :libraries, exe.size == 1 ? exe.first : :binaries ]
                   .map { |t| generator.wrap_target(t) })
    # Note: Try to restrict dependencies on single binary.
  end

  writer.build(SUMMARY,'gcovr_summary', test_files)

  generator.add_to_intermediate_target(:gcov, SUMMARY)

  # Note: The dummy file is never built!
  writer.build('$builddir/dummy','gcov_cleanall', [])
  generator.add_to_intermediate_target(:gcov_clean, '$builddir/dummy')
end
ninja_rules(writer = generator.ninja) click to toggle source
# File tools/gcov.rb, line 172
def ninja_rules(writer = generator.ninja)
  writer.rule('gcov_cleanall', "rm -f #{GCOVFILES} $builddir/#{basename}*",
              description: 'coverage analysis: remove all files')

  writer.rule('gcov_clean', "rm -f #{GCOVDATA} && touch #{GCOVCLEAN}",
              description: 'coverage analysis: remove files')
  tests.each do |test|
    writer.rule("gcov_runtest_#{test[:id]}", test_command(test),
                description: "coverage analysis: run test '#{test[:id]}'")
  end
  writer.rule('gcovr_summary', summary_command,
              description: 'coverage analysis: summary')
end
ninja_variables(writer = generator.ninja) click to toggle source
# File tools/gcov.rb, line 166
def ninja_variables(writer = generator.ninja)
  writer.comment 'GCov'
  writer.variable('gcovr', gcovr)
  writer.newline
end
summary_command() click to toggle source
# File tools/gcov.rb, line 151
def summary_command
  if !active?
    logger.info "The gcov tool must be activated by {cc,cxx}.coverage."
    return "echo 'The gcov tool was not activated.'"
  end

  llvm = ld.vendor == :clang ? '--gcov-executable="llvm-cov gcov" ' : ''
  "rm -f $builddir/#{basename}*.html $builddir/#{basename}*.xml && "\
  "$gcovr #{llvm}"\
  "#{filter.map { |f| %Q{-f \"#{f}\"}}.join(' ')} "\
  "#{exclude.map { |e| %Q{-e \"#{e}\"}}.join(' ')} "\
  "-s -r $builddir/.. #{gcovr_format_options} "\
  "#{gcovr_report_options} #{options} > #{SUMMARY}"
end
test_command(test) click to toggle source
# File tools/gcov.rb, line 143
def test_command(test)
  if !active?
    return "echo gcov: skip test '#{test[:id]}' && echo skipped > #{test[:out]}"
  end
  "echo gcov test '#{test[:id]}' && "\
  "#{test[:command]} #{test[:arguments]} && echo ok > #{test[:out]}"
end
test_files() click to toggle source
# File tools/gcov.rb, line 139
def test_files
  tests.map { |t| t[:out] }
end