Class: Bake::Blocks::Executable

Inherits:
BlockBase show all
Defined in:
lib/blocks/executable.rb

Instance Attribute Summary

Attributes inherited from BlockBase

#tcs

Instance Method Summary collapse

Methods inherited from BlockBase

#calcOutputDir, #check_config_file, #config_changed?, #defaultToolchainTime, isCmdLineEqual?, prepareOutput, #printCmd, #process_console_output, #process_result, writeCmdLineFile

Constructor Details

#initialize(block, config, referencedConfigs, tcs, compileBlock) ⇒ Executable

Returns a new instance of Executable.



9
10
11
12
13
14
15
16
17
# File 'lib/blocks/executable.rb', line 9

def initialize(block, config, referencedConfigs, tcs, compileBlock)
  super(block, config, referencedConfigs, tcs)
  @compileBlock = compileBlock

  calcArtifactName
  calcMapFile
  calcLinkerScript

end

Instance Method Details

#calcArtifactNameObject



23
24
25
26
27
28
29
30
# File 'lib/blocks/executable.rb', line 23

def calcArtifactName
  if not @config.artifactName.nil? and @config.artifactName.name != "" 
    baseFilename = @config.artifactName.name
  else
    baseFilename = "#{@projectName}#{@tcs[:LINKER][:OUTPUT_ENDING]}"
  end
  @exe_name ||= File.join([@output_dir, baseFilename])
end

#calcCmdlineFileObject



32
33
34
# File 'lib/blocks/executable.rb', line 32

def calcCmdlineFile()
  @exe_name + ".cmdline"
end

#calcLinkerScriptObject



19
20
21
# File 'lib/blocks/executable.rb', line 19

def calcLinkerScript
  @linker_script = @config.linkerScript.nil? ? nil : @block.convPath(@config.linkerScript) 
end

#calcMapFileObject



36
37
38
39
40
41
42
43
44
45
# File 'lib/blocks/executable.rb', line 36

def calcMapFile
  @mapfile = nil
  if (not Bake.options.docu) and (not Bake.options.lint) and (not @config.mapFile.nil?)
    if @config.mapFile.name == ""
      @mapfile = @exe_name.chomp(File.extname(@exe_name)) + ".map"
    else
      @mapfile = @config.mapFile.name 
    end
  end
end

#cleanObject



152
153
154
155
156
157
158
159
160
# File 'lib/blocks/executable.rb', line 152

def clean
  Dir.chdir(@projectDir) do
    if File.exist?@output_dir 
      puts "Deleting folder #{@output_dir}" if Bake.options.verbose >= 2
      FileUtils.rm_rf(@output_dir)
    end
  end unless Bake.options.filename
  return true
end

#depHasError(block) ⇒ Object



47
48
49
50
51
52
53
54
55
# File 'lib/blocks/executable.rb', line 47

def depHasError(block)
  block.dependencies.each do |dep|
    subBlock = Blocks::ALL_BLOCKS[dep]
    return true unless subBlock.result
    return depHasError(subBlock)
  end
  
  return false
end

#executeObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/blocks/executable.rb', line 86

def execute
  
  Dir.chdir(@projectDir) do
    return false if depHasError(@block)
    
    libs, linker_libs_array = LibElements.calc_linker_lib_string(@block, @tcs)
    
    cmdLineCheck = false
    cmdLineFile = calcCmdlineFile()
    reason = needed?(libs)
    if not reason
      cmdLineCheck = true
      reason = config_changed?(cmdLineFile)
    end
    return true unless reason
    


    linker = @tcs[:LINKER]
    
    cmd = Utils.flagSplit(linker[:COMMAND], false) # g++

    cmd += linker[:MUST_FLAGS].split(" ")
    cmd += Bake::Utils::flagSplit(linker[:FLAGS],true)
    
      
    cmd << linker[:EXE_FLAG]
    if linker[:EXE_FLAG_SPACE]
      cmd << @exe_name
    else
      cmd[cmd.length-1] += @exe_name
    end

    cmd += @compileBlock.objects
    cmd << linker[:SCRIPT] if @linker_script # -T

    cmd << @linker_script if @linker_script # xy/xy.dld

    cmd += linker[:MAP_FILE_FLAG].split(" ") if @mapfile # -Wl,-m6

    if not linker[:MAP_FILE_PIPE] and @mapfile 
      cmd[cmd.length-1] << @mapfile 
    end
    cmd += Bake::Utils::flagSplit(linker[:LIB_PREFIX_FLAGS],true) # "-Wl,--whole-archive "

    cmd += linker_libs_array
    cmd += Bake::Utils::flagSplit(linker[:LIB_POSTFIX_FLAGS],true) # "-Wl,--no-whole-archive "

    
    mapfileStr = (@mapfile and linker[:MAP_FILE_PIPE]) ? " >#{@mapfile}" : ""
    
    # pre print because linking can take much time

    cmdLinePrint = cmd.dup
    outPipe = (@mapfile and linker[:MAP_FILE_PIPE]) ? "#{@mapfile}" : nil
    cmdLinePrint << "> #{outPipe}" if outPipe
    
    return true if cmdLineCheck and BlockBase.isCmdLineEqual?(cmd, cmdLineFile)
    
    ToCxx.linkBlock
    
    BlockBase.prepareOutput(@exe_name)
    
    printCmd(cmdLinePrint, "Linking #{@exe_name}", reason, false)
    BlockBase.writeCmdLineFile(cmd, cmdLineFile)
    success, consoleOutput = ProcessHelper.run(cmd, false, false, outPipe)
    process_result(cmdLinePrint, consoleOutput, linker[:ERROR_PARSER], nil, reason, success)
    
    check_config_file()
    return success
  end
end

#needed?(libs) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/blocks/executable.rb', line 57

def needed?(libs)
  return false if Bake.options.prepro
  return "because linkOnly was specified" if Bake.options.linkOnly
  
  # exe

  return "because executable does not exist" if not File.exists?(@exe_name)

  eTime = File.mtime(@exe_name)
  
  # linkerscript

  if @linker_script
    return "because linker script does not exist - will most probably result in an error" if not File.exists?(@linker_script)
    return "because linker script is newer than executable" if eTime < File.mtime(@linker_script)
  end
  
  # sources

  @compileBlock.objects.each do |obj|
    return "because object #{obj} does not exist" if not File.exists?(obj)
    return "because object #{obj} is newer than executable" if eTime < File.mtime(obj)
  end
  
  # libs

  libs.each do |lib|
    return "because library #{lib} does not exist" if not File.exists?(lib)
    return "because library #{lib} is newer than executable" if eTime < File.mtime(lib)
  end
  false
end