class Bake::Subst

Public Class Methods

empty(elem, var, mandatory, str) click to toggle source
# File lib/bake/subst.rb, line 48
def self.empty(elem, var, mandatory, str)
  if mandatory
    Bake.formatter.printError("Variable '$(#{var})' cannot be substituted, because #{str}", elem ? elem : @@config)
    ExitHelper.exit(1)
  else
    if Bake.options.verbose > 0
      msg = "Substitute variable '$(#{var})' with empty string, because #{str}"
      Bake.formatter.printInfo(msg, elem ? elem : @@config)
    end
  end
end
itute(config, projName, isMainProj, toolchain, referencedConfigs, configTcMap) click to toggle source
# File lib/bake/subst.rb, line 60
def self.itute(config, projName, isMainProj, toolchain, referencedConfigs, configTcMap)
  @@lazy = true
  @@config = config
  @@toolchain = toolchain
  @@referencedConfigs = referencedConfigs
  @@configTcMap = configTcMap
  if isMainProj
    @@toolchainName = config.defaultToolchain.basedOn
    @@outputDirUnresolved = []
  end

  @@configName = config.name
  @@projDir = config.parent.get_project_dir
  @@projName = projName
  @@unresolvedVars = []
  @@configFilename = config.file_name

  @@artifactName = ""
  if Metamodel::ExecutableConfig === config || Metamodel::LibraryConfig === config
    if not config.artifactName.nil?
      @@artifactName = config.artifactName.name
    else
      if Metamodel::ExecutableConfig === config
        @@artifactName = projName+Bake::Toolchain.outputEnding(toolchain)
      elsif Metamodel::LibraryConfig === config
        @@artifactName = "lib#{projName}.a"
      end
    end
  end

  if isMainProj
    @@userVarMap = {}
  else
    @@userVarMap = @@userVarMapMain.clone
  end

  config.set.each do |s|

    if (s.value != "" and s.cmd != "")
      Bake.formatter.printError("value and cmd attributes must be used exclusively", s)
      ExitHelper.exit(1)
    end

    if (s.value != "") or (s.cmd == "")
      setName = substString(s.name, s)
      if (setName.empty?)
        Bake.formatter.printWarning("Name of variable must not be empty - variable will be ignored", s)
      else
        @@userVarMap[s.name] = substString(s.value, s)
        if s.env
          ENV[s.name] = @@userVarMap[s.name]
          config.setEnvVar(s.name, @@userVarMap[s.name])
        end
      end
    else
      cmd_result = false
      consoleOutput = ""
      cmd = [substString(s.cmd, s)]
      begin
        Dir.chdir(@@projDir) do
          cmd_result, consoleOutput = ProcessHelper.run(cmd)
          @@userVarMap[s.name] = consoleOutput.chomp
          if s.env
            ENV[s.name] = @@userVarMap[s.name]
            config.setEnvVar(s.name, @@userVarMap[s.name])
          end
        end
      rescue Exception=>e
        consoleOutput = e.message
      end
      if (cmd_result == false)
        puts consoleOutput
        Bake.formatter.printError("Command not successful: #{cmd.join(" ")}", s)
        ExitHelper.exit(1)
      end
    end

  end

  @@userVarMapMain = @@userVarMap.clone if isMainProj

  unresolvedVarsWithoutOutputDir = []
  10.times do
    @@unresolvedVars = []
    subst(config)
    substToolchain(toolchain)
    unresolvedVarsWithoutOutputDir = (@@unresolvedVars - @@outputDirUnresolved)
    break if unresolvedVarsWithoutOutputDir.empty?
  end
  if (unresolvedVarsWithoutOutputDir.length > 0)
    unresolvedVarsWithoutOutputDir.each do |elem|
      Bake.formatter.printError("Could not resolve variable", elem)
    end
    ExitHelper.exit(1)
  end


end
lazyPaths() click to toggle source

this is done lazy because usually there is no need to calculate that

# File lib/bake/subst.rb, line 8
def self.lazyPaths
  return unless @@lazy

  cppCmd = @@toolchain[:COMPILER][:CPP][:COMMAND]
  cCmd = @@toolchain[:COMPILER][:C][:COMMAND]
  asmCmd = @@toolchain[:COMPILER][:ASM][:COMMAND]
  archiverCmd = @@toolchain[:ARCHIVER][:COMMAND]
  linkerCmd = @@toolchain[:LINKER][:COMMAND]

  if @@config.toolchain
    linkerCmd = @@config.toolchain.linker.command if @@config.toolchain.linker and @@config.toolchain.linker.command != ""
    archiverCmd = @@config.toolchain.archiver.command if @@config.toolchain.linker and @@config.toolchain.archiver.command != ""
    @@config.toolchain.compiler.each do |c|
      if c.command != ""
        if c.ctype == :CPP
          cppCmd = c.command
        elsif c.ctype == :C
          cCmd = c.command
        elsif c.ctype == :ASM
          asmCmd = c.command
        end
      end
    end
  end

  @@cppExe      = File.which(cppCmd)
  @@cExe        = File.which(cCmd)
  @@asmExe      = File.which(asmCmd)
  @@archiverExe = File.which(archiverCmd)
  @@linkerExe   = File.which(linkerCmd)

  @@lazy = false
end
resolveOutputDir() click to toggle source
# File lib/bake/subst.rb, line 42
def self.resolveOutputDir()
  @@outputDirUnresolved.each do |elem|
    subst(elem) if elem
 end
end
subst(elem) click to toggle source
# File lib/bake/subst.rb, line 384
def self.subst(elem)
  elem.class.ecore.eAllAttributes_derived.each do |a|
    next if a.name == "file_name" or a.name == "line_number"
    return if Metamodel::Set === elem.class
    return if Metamodel::DefaultToolchain === elem
    return if Metamodel::Toolchain === elem.class
    next if a.eType.name != "EString"
    value = elem.getGeneric(a.name)
    if value.kind_of?(Array)
      substArr = value.map { |s| substString(s, elem, a.name) }
      elem.setGeneric(a.name, substArr)
    else
      substStr = substString(value, elem, a.name)
      elem.setGeneric(a.name, substStr)
    end
  end

  childsRefs = elem.class.ecore.eAllReferences.select{|r| r.containment}
  childsRefs.each do |c|
    elem.getGenericAsArray(c.name).each { |child| subst(child) }
  end
end
substString(str, elem=nil, attrName=nil) click to toggle source
# File lib/bake/subst.rb, line 159
    def self.substString(str, elem=nil, attrName=nil)
      substStr = ""
      posSubst = 0
      while (true)
        posStart = str.index("$(", posSubst)
        break if posStart.nil?
        posEnd = str.index(")", posStart)
        if posEnd.nil?
          Bake.formatter.printError("'$(' found but no ')'", elem)
          ExitHelper.exit(1)
        end
        posStartSub = str.index("$(", posStart+1)
        if (not posStartSub.nil? and posStartSub < posEnd) # = nested vars
          newStr = str[0,posStartSub] + substString(str[posStartSub..posEnd],elem)
          if (str.length + 1 > posEnd)
            str = newStr + str[posEnd+1..-1]
          else
            str = newStr
          end
          next
        end

        substStr << str[posSubst..posStart-1] if posStart>0

        var = str[posStart+2..posEnd-1].strip
        mandatory = false

        splittedVar = var.split(",").map { |v| v.strip() }
        splittedVar.each_with_index do |s,i|
          if s.end_with?("!")
            mandatory = true
            splittedVar[i] = s[0..-2]
          end
        end
        var = splittedVar.join(", ")

        if Bake.options.vars.has_key?(var)
          substStr << Bake.options.vars[var]
        elsif @@userVarMap.has_key?(var)
          substStr << @@userVarMap[var]
        elsif var == "MainConfigName"
          substStr << Bake.options.build_config
        elsif var == "MainProjectName"
          substStr << Bake.options.main_project_name
        elsif var == "MainProjectDir"
          substStr << Bake.options.main_dir
        elsif var == "WorkingDir"
          substStr << Bake.options.working_dir
        elsif var == "ConfigName"
         substStr << @@configName
        elsif var == "ToolchainName" and defined?@@toolchainName
         substStr << @@toolchainName
#        elsif var == "PathToMainProject"
#          substStr << File.rel_from_to_project(@@config.parent.get_project_dir, Bake.options.main_dir, false)
#        elsif var == "PathToMainProjectSanitized"
#          path = File.rel_from_to_project(@@config.parent.get_project_dir, Bake.options.main_dir, false).gsub(/\.\./,"__").gsub(/:/,"")
#          path = path[1..-1] if path.start_with?("/")
#          substStr << path
#        elsif var == "UidNoMainConfigName"
#          substStr << CRC32.calc(File.rel_from_to_project(@@config.parent.get_project_dir, Bake.options.main_dir, false))
        elsif var == "Uid"
          substStr << CRC32.calc(File.rel_from_to_project(@@config.parent.get_project_dir, Bake.options.main_dir, false) + "," + Bake.options.build_config)
        elsif var == "ProjectName"
          substStr << @@projName
        elsif var == "FilterArguments" or (splittedVar.length == 2 and splittedVar[0] == "FilterArguments")
          if (var == "FilterArguments")
            # default = nothing
          else
            args = Bake.options.include_filter_args[splittedVar[1]]
            substStr << args if args
          end
        elsif var == "OriginalDir"
          org = File.dirname(elem.org_file_name)
          if (org == @@projDir)
            substStr << @@projDir
          else
            substStr << File.rel_from_to_project(@@projDir,File.dirname(elem.org_file_name),false)
          end
        elsif var == "ProjectDir" or (splittedVar.length == 2 and splittedVar[0] == "ProjectDir")
          if (var == "ProjectDir")
            substStr << @@projDir
          else
            out_proj_name = splittedVar[1]
            if @@referencedConfigs.has_key?out_proj_name
              configs = @@referencedConfigs[out_proj_name]
              config = configs.first
              substStr << File.rel_from_to_project(@@projDir,config.get_project_dir,false)
            else
              empty(elem, var, mandatory, "project #{out_proj_name} not found")
            end
          end
        elsif var == "OutputDir" or (splittedVar.length == 3 and splittedVar[0] == "OutputDir")
          if (var == "OutputDir")
            if (!elem.nil?)
              config = elem.getConfig
              out_proj_name = config.parent.name
              out_conf_name = config.name
            else
              out_proj_name = @@projName
              out_conf_name = @@configName
            end
          else
            out_proj_name = splittedVar[1]
            out_conf_name = splittedVar[2]
          end
          if @@referencedConfigs.has_key?out_proj_name
            configs = @@referencedConfigs[out_proj_name]
            config = configs.select {|c| c.name == out_conf_name }.first
            if config

              if config.toolchain && config.toolchain.outputDir && config.toolchain.outputDir != ""
                out_dir = config.toolchain.outputDir
              else
                out_dir = @@configTcMap[config][:OUTPUT_DIR]
              end
              if config.toolchain && config.toolchain.outputDirPostfix && config.toolchain.outputDirPostfix != ""
                out_dir_postfix = config.toolchain.outputDirPostfix
              else
                out_dir_postfix = @@configTcMap[config][:OUTPUT_DIR_POSTFIX]
              end

              if not out_dir
                qacPart = Bake.options.qac ? (".qac" + Bake.options.buildDirDelimiter) : ""
                if out_proj_name == Bake.options.main_project_name and out_conf_name == Bake.options.build_config
                  out_dir = "build" + Bake.options.buildDirDelimiter + qacPart + Bake.options.build_config
                else
                  out_dir = "build" + Bake.options.buildDirDelimiter + qacPart + out_conf_name + "_" + Bake.options.main_project_name + "_" + Bake.options.build_config
                end
              end
              out_dir += out_dir_postfix if out_dir_postfix

              if (out_dir.include?"$(")
                if !elem
                  Bake.formatter.printError("Variable OutputDir not used correctly in this config", @@config)
                  ExitHelper.exit(1)
                end
                substStr << str[posStart..posEnd]
                @@outputDirUnresolved << elem
              else
                out_dir = substString(out_dir, elem)
                if File.is_absolute?(out_dir)
                  substStr << out_dir
                else
                  if (elem.nil?)
                    projDir = @@projDir
                  else
                    projDir = elem.get_project_dir
                  end
                  substStr << Pathname.new(File.rel_from_to_project(projDir,config.get_project_dir,true)  + out_dir).cleanpath.to_s
                end
              end
            else
              empty(elem, var, mandatory, "config #{out_conf_name} not found for project #{out_proj_name}")
            end
          else
            empty(elem, var, mandatory, "project #{out_proj_name} not found")
          end
        elsif splittedVar.length > 1 and splittedVar[0] == "OutputDir"
          empty(elem, var, mandatory, "syntax of complex variable OutputDir is not $(OutputDir,<project name>,<config name>)")
        elsif var == "Time"
          substStr << Time.now.to_s
        elsif var == "Hostname"
          substStr << Socket.gethostname
        elsif var == "QacActive"
          substStr << (Bake.options.qac ? "yes" : "no")
        elsif var == "ArtifactName"
          substStr << @@artifactName
        elsif var == "ArtifactNameBase"
          substStr << @@artifactName.chomp(File.extname(@@artifactName))
        elsif var == "CPPPath"
          self.lazyPaths
          substStr << @@cppExe
        elsif var == "CPath"
          self.lazyPaths
          substStr << @@cExe
        elsif var == "ASMPath"
          self.lazyPaths
          substStr << @@asmExe
        elsif var == "ArchiverPath"
          self.lazyPaths
          substStr << @@archiverExe
        elsif var == "LinkerPath"
          self.lazyPaths
          substStr << @@linkerExe
        elsif var == "Roots"
          substStr << "___ROOTS___"
        elsif var == "/"
          substStr << File::SEPARATOR
        elsif var == ":"
          substStr << File::PATH_SEPARATOR
        elsif ENV[var]
          substStr << ENV[var]
        else
          if !(["ASMCompilerPrefix", "CompilerPrefix", "ArchiverPrefix", "LinkerPrefix"].include?(var))
            empty(elem, var, mandatory, "it's not set") if mandatory || Bake.options.verbose >= 2
          end
        end

        posSubst = posEnd + 1
      end
      substStr << str[posSubst..-1]
      @@unresolvedVars << elem if substStr.include?("$(")
      substStr
    end
substToolchain(elem) click to toggle source
# File lib/bake/subst.rb, line 364
def self.substToolchain(elem)
  if Hash === elem
    elem.each do |k, e|
      if Hash === e or Array === e
        substToolchain(e)
      elsif String === e
        elem[k] = substString(e)
      end
    end
  elsif Array === elem
    elem.each_with_index do |e, i|
      if Hash === e or Array === e
        substToolchain(e)
      elsif String === e
        elem[i] = substString(e)
      end
    end
  end
end