module Rmk
Constants
- DEBUG_TRUE
- DEFAULT_MOC
- DEFAULT_RCC
- PACKAGE_ATTRIBUTES
#check_package_attributes recognizes these :nodoc:
- PRIV_FILE_NAME
- PROJ_FILE_NAME
- SLOTS
mapping of slot symbols to integers: slots define order of evaluation
Public Instance Methods
get instance of archive tool AR
# File tools/ar.rb, line 3 def ar @@tools[AR] ||= AR.new end
available library packages
# File lib/dsl.rb, line 101 def available_packages @@available_packages end
get instance of C compiler tool CC
# File tools/cc.rb, line 3 def cc @@tools[CC] ||= CC.new end
get instance of Ccache tool
# File tools/ccache.rb, line 3 def ccache @@tools[Ccache] ||= Ccache.new end
Test if cfg is a valid configuration, raise error or return
cfg.
# File lib/rmk.rb, line 32 def check_configuration(cfg) unless @@configurations.include?(cfg) raise "undefined configuration '#{cfg}' "\ "(not in #{@@configurations.inspect})" end cfg end
check if name is a known attribute (avoid mistakes from typos)
:nodoc:
# File lib/dsl.rb, line 365 def check_package_attributes(name) p = available_packages[name.to_s] raise "undefined package '#{name}'" unless p p.each_key do |k| unless k.is_a?(Symbol) logger.warn "attribute key '#{k}' should be symbol in package '#{name}'" end next if PACKAGE_ATTRIBUTES.include?(k) next if Array(p[:extra_attributes]).include?(k) logger.warn "unknown attribute '#{k}' in package '#{name}'" logger.warn " at #{p[:update_at].inspect}" if p[:update_at] end end
get instance of CompDB tool
# File tools/compdb.rb, line 3 def compdb @@tools[CompDB] ||= CompDB.new end
available #configurations
# File lib/rmk.rb, line 22 def configurations @@configurations end
# File lib/generator.rb, line 21 def create_generator(options) Generator.new(options) end
get instance of C++ compiler tool CC
# File tools/cxx.rb, line 5 def cxx @@tools[CXX] ||= CXX.new end
default configuration (symbol)
# File lib/rmk.rb, line 27 def default_configuration :default end
define tool parameters for all #configurations (in block + { |params,cfg| … }+)
# File lib/dsl.rb, line 54 def define_all_tool_params(tool) expect_symbol(tool) @@tools_params[tool] ||= {} configurations.each do |cfg| @@tools_params[tool][cfg] ||= {} params = @@tools_params[tool][cfg] yield params, cfg end end
Define a new package (which may or may not exist).
Recognized options
:description-
String :url-
String(detailsdescription) :comment-
String(detailsdescription) :requires-
package name or array of package names
:requires_tools-
Symbolfor class or array of symbols :lib-
library name w/o prefix or extension or array of libs
:path-
library search path or aray of paths
:include-
include path as for
cc.includeor array of paths :define-
definition(s) as for
cc.defineandcxx.define :cflags-
flag(s) as for
cc.flags :cxxflags-
flag(s) as for
cc.flags :hooks-
evaluated on #use_package
:extra_attributes-
define new user attributes
:main_patterns-
additional Regexp patterns defining executable
("with main()")
See also #use_package.
# File lib/dsl.rb, line 344 def define_package(name) logger.debug "define_package '#{name}'" p = (available_packages[name.to_s] ||= {}) (p[:update_at] ||= []) << caller(1..1).first yield p check_package_attributes(name) end
define tool parameters (in block + { |params| … }+)
# File lib/dsl.rb, line 40 def define_tool_params(tool, cfg) expect_symbol(tool) check_configuration(cfg) @@tools_params[tool] ||= {} @@tools_params[tool][cfg] ||= {} params = @@tools_params[tool][cfg] yield params end
define hook that is executed as +hook(project,options)+ on
use_project.
# File lib/dsl.rb, line 232 def define_use_project_hook(hook) @@use_project_hooks << hook end
get instance of Doxygen tool
# File tools/doxygen.rb, line 20 def doxygen @@tools[Doxygen] ||= Doxygen.new end
Dump data to YAML file. Place, e.g., in `RMakefile` for debugging, e.g., as +dump('/tmp/packages.yaml',available_packages)
# File lib/dsl.rb, line 473 def dump(filename, what) logger.warn "dump data to '#{filename}'" File.open(filename, 'w+b') do |f| f.write(YAML.dump(what)) end end
same as #emptylib
# File tools/emptylib.rb, line 11 def empty_library emptylib end
get instance of Emptylib tool
# File tools/emptylib.rb, line 6 def emptylib @@tools[Emptylib] ||= Emptylib.new end
#subproject has no effect for
mathing paths (use, e.g., in RMakefile.priv)
# File lib/dsl.rb, line 407 def exclude_subprojects_matching(pattern) p = if pattern.is_a?(Regexp) pattern else /^#{pattern}$/ end generator.exclude_subproject_patterns << p end
# File lib/dsl.rb, line 5 def expect_symbol(s) return if s.is_a?(Symbol) raise "expect symbol instead of '#{s}' of type '#{s.class}'" end
used library packages w/o those from dependencies
# File lib/dsl.rb, line 96 def explicitly_used_packages @@explicitly_used_packages end
get instance of ExtraNinja tool
# File tools/extraninja.rb, line 3 def extra_ninja(&block) (@@tools[AddExtraNinjaCode] ||= AddExtraNinjaCode.new).add(&block) end
block +{ |cfg| … }+ is evaluated for all but configs
# File lib/dsl.rb, line 208 def for_all_configurations_except(*configs) configs.each { |cfg| check_configuration(cfg) } yield(generator.configuration) unless configs.include?(generator.configuration) end
get instance of GCov tool
# File tools/gcov.rb, line 3 def gcov @@tools[GCov] ||= GCov.new end
# File lib/generator.rb, line 16 def generator raise 'require Generator.new' unless @@generator @@generator end
Test if package name is available.
# File lib/dsl.rb, line 320 def has_package?(name) !available_packages[name.to_s].nil? end
Read and evaluate Ruby files. Evaluates pattern to list files,
filtered by exclude_pattern. Then calls require
for .rb files or load otherwise. Returns list of
imported files.
-
pattern path as for
Dir.glob -
exclude_pattern exclude matching files
# File lib/dsl.rb, line 453 def import_files(pattern, exclude_pattern = nil) logger.debug "import files '#{pattern}' (exclude='#{exclude_pattern}')" Dir.glob(pattern).find_all do |f| exclude_pattern.nil? || (f =~ exclude_pattern).nil end.map do |f| path = File.expand_path(f) if f =~ /\.rb$/ logger.debug "- require '#{path}' " require(File.expand_path(path)) else logger.debug "- load '#{path}' " load(File.expand_path(path)) end f end end
block +{ |package| … }+ will be passed to #update_package on #use_package.
Must not update :requires list!
# File lib/dsl.rb, line 394 def lazy_update_package(name, &block) logger.debug ":lazy_update_package '#{name}'" p = available_packages[name.to_s] raise "undefined package '#{name}'" unless p (p[:lazy_updates] ||= []) << block end
get instance of linker tool LD
# File tools/ld.rb, line 3 def ld @@tools[LD] ||= LD.new end
# File lib/rmk.rb, line 15 def logger @@log end
get instance of linker tool Mex
# File tools/mex.rb, line 3 def mex unless @@tools[Mex] use_package('mex') @@tools[Mex] ||= Mex.new end @@tools[Mex] end
get instance of Moc tool
# File tools/moc.rb, line 5 def moc @@tools[Moc] ||= Moc.new end
block +{ |cfg| … }+ is evaluated only for configs
# File lib/dsl.rb, line 202 def only_for_configuration(*configs) configs.each { |cfg| check_configuration(cfg) } yield(generator.configuration) if configs.include?(generator.configuration) end
define #phony target
from other
# File lib/dsl.rb, line 433 def phony(target, other) extra_ninja do |writer| writer.comment 'user defined phony target' writer.phony(target, other) writer.newline end end
promote target of sub project (same name or
newname)
# File lib/dsl.rb, line 442 def phony_sub(sub, target, newname = nil) # TODO: test if sub exists phony(project_target(newname || target), subproject_target(sub, target)) end
get “wrapped” target name
# File lib/dsl.rb, line 422 def project_target(target) "${project}_#{target}" # #{generator.lib_base_name} end
Is proj used (so far)?
# File lib/dsl.rb, line 244 def project_used?(proj) !used_project_options(proj).nil? end
get instance of Rcc tool
# File tools/rcc.rb, line 5 def rcc @@tools[Rcc] ||= Rcc.new end
# File lib/generator.rb, line 25 def recreate_generator(options) @@generator = nil create_generator(options) end
request recursive generation
# File lib/dsl.rb, line 402 def subproject(*paths) generator.define_subproject(*paths) end
get “wrapped” sub-project target
# File lib/dsl.rb, line 427 def subproject_target(sub, target) p = "#{generator.proj_base}/#{sub}" "#{generator.proj_library_base_name(p)}_#{target}" end
request recursive generation
# File lib/dsl.rb, line 417 def subproject_without_library(*paths) generator.define_subproject_without_library(*paths) end
Get #symbol for a tool,
e.g., +symbol(cxx)+ yields :CXX. Don't call in
configuration code, because, e.g., cxx will create a new
CXX instance and implicitly use_tool!
# File lib/dsl.rb, line 13 def symbol(tool) if tool.is_a?(Symbol) tool elsif tool.is_a?(Class) tool.to_s.sub('Rmk::', '').to_sym else symbol(tool.class) end end
Get preset parameters for tool in configuration
cfg. Note that tool must be a Symbol
(of the class name), because parametrization should not create instances of
tools!
# File lib/dsl.rb, line 26 def tool_params(tool, cfg) expect_symbol(tool) check_configuration(cfg) data = @@tools_params[tool] raise "no entry for tool '#{tool}'" unless data data = data[cfg] raise "no entry for '#{cfg}' tool '#{tool}'" unless data data end
get instance of Touch tool
# File tools/touch.rb, line 3 def touch @@tools[Touch] ||= Touch.new end
update existing set of parameters for all #configurations (in block + { |params,cfg| … }+)
# File lib/dsl.rb, line 75 def update_all_tool_params(tool, _cfg) configurations.each do |cfg| yield tool_params(tool, cfg), cfg end end
update an existing package (in block +{ |package| … }+)
# File lib/dsl.rb, line 382 def update_package(name) logger.debug "update_package '#{name}'" p = available_packages[name.to_s] raise "undefined package '#{name}'" unless p (p[:update_at] ||= []) << caller(1..1).first yield p check_package_attributes(name) end
update existing set of parameters (in block + { |params,cfg| … }+)
# File lib/dsl.rb, line 69 def update_tool_params(tool, cfg) yield tool_params(tool, cfg) end
specify that libs should be used
# File lib/dsl.rb, line 106 def use_package(*libs) libs.map(&:to_s).each do |name| lib = @@available_packages[name] raise "unknown package '#{name}'" unless lib next if @@used_packages[name] if @@using_required_package_count.zero? @@log.debug "use package '#{name}'" else @@log.debug "use package '#{name}' (required by other)" end # NOTE: Currently all options are applied to cxx, cc, ld. # Should be able to differentiate processors! if lib[:hooks] [lib[:hooks]].flatten.each do |hook| unless hook.respond_to? :call raise "hook must be callable (package '#{name}')" end hook.call(lib) end end if lib[:main_patterns] patterns = Array(lib[:main_patterns]) @@log.debug "Add patterns #{patterns.inspect} for specifying executable." Rmk.cxx.add_main_pattern(patterns) Rmk.cc.add_main_pattern(patterns) end if lib[:requires] @@using_required_package_count += 1 use_package(*lib[:requires]) @@using_required_package_count -= 1 end if lib[:lazy_updates] lib[:lazy_updates].each do |block| update_package(name, &block) end lib[:lazy_updates] = nil # remove after use end Rmk.ld.add_path(*lib[:path]) if lib[:path] Rmk.ld.add_library(*lib[:lib]) if lib[:lib] if lib[:include] Rmk.cxx.include_path(*lib[:include]) Rmk.cc.include_path(*lib[:include]) end if lib[:define] Rmk.cxx.define(lib[:define]) Rmk.cc.define(lib[:define]) end Rmk.cxx.flags.add(lib[:cxxflags]) if lib[:cxxflags] Rmk.cc.flags.add(lib[:cflags]) if lib[:cflags] if lib[:requires_tools] Array(lib[:requires_tools]).each do |tool| begin klass = Kernel.const_get(tool.to_s) rescue StandardError unless klass.is_a?(Class) raise "expected class name for '#{klass.inspect}'" end end @@log.debug "#{name} requires tool #{klass}" @@tools[klass] ||= klass.new end end @@used_packages[name] = lib @@explicitly_used_packages[name] = lib if @@using_required_package_count.zero? end.compact end
Use only packages from libs that are available.
For all in libs that satisfy has_package? call #use_package and yield package
name (in block +{ |name| …}+).
# File lib/dsl.rb, line 191 def use_package_if_available(*libs) libs.each do |p| name = p.to_s if has_package?(name) use_package(name) yield(name) end end end
Specify that proj should be used.
-
projcan be an array -
Each item can be a string or a
Hash. -
Hashes
phave the project name with key:projectthe remainder is used as options to Rmk::Processor#add_project.
# File lib/dsl.rb, line 253 def use_project(*proj) # TODO: document syntax "use_project name, opt1: val1, opt2: val2" if proj.size == 2 && proj.last.is_a?(Hash) proj.last[:project] = proj.first proj = [proj.last] end # TODO: check for valid options (similar as for package) # :proj_root -- should be done by use_project # TODO: simplify method proj.each do |p| project, options = if p.is_a?(Hash) raise "missing project name in Hash '#{p.inspect}'" unless p[:project] [p[:project], p] else [p, {}] end if project_used?(project) logger.warn "use_project '#{project}' specified twice (redundant)." if options != used_project_options(project) logger.warn "use_project '#{project}' with different options " \ '(using initial definition):' logger.warn " using #{used_project_options(project).inspect}, " \ "ignoring #{options.inspect}." end next end if options[:proj_root] root = Pathname.new(options[:proj_root]).expand_path if root == Rmk.generator.proj_root options.delete(:proj_root) logger.warn "use_project '#{project}' with 'proj_root' equal to " \ 'current root (not required).' else # TODO: relative paths are w.r.t. cwd!?! unless File.directory?(root) raise "use_project '#{project}' with nonexistent proj_root '#{root}'." end end options[:proj_root] = root end options[:config] = generator.configuration if options[:config].nil? @@used_projects[project] = options @@use_project_hooks.each { |hook| hook.call(project, options) } tools = Rmk.generator.tool_chain [cc, cxx, ld].each { |tool| tools << tool unless tools.include?(tool) } tools.find_all { |tool| tool.respond_to?(:add_project) } .each { |tool| tool.add_project(project, options) } # TODO: what if tool is "not yet used" # TODO: store projects in list # TODO: inefficient (filter tool chain) # TODO: method+cache above end end
specify that tools should be used
# File lib/dsl.rb, line 214 def use_tool(*tools) tools.each do |tool| if tool.is_a?(Class) @tools[tool] ||= tool.new elsif (tool.is_a?(String) || tool.is_a?(Symbol)) && respond_to?(tool.to_sym) send(tool.to_sym) elsif tool.is_a?(NinjaGenerator) # do nothing else raise "unknown tool '#{tool}" end end end
Is tool used? The tool argument is the class name as a #symbol or a string.
# File lib/rmk.rb, line 44 def use_tool?(tool) klass = Kernel.const_get(tool) return false unless klass raise 'invalid use of use_tool?' unless klass.is_a?(Class) @@tools.key?(klass) rescue StandardError false end
used library packages (list “instances” for “meta-packages”)
# File lib/dsl.rb, line 91 def used_packages @@used_packages end
Get options Hash for proj if used, nil otherwise.
# File lib/dsl.rb, line 239 def used_project_options(proj) @@used_projects[proj] end