Class: Cxxproject::Linkable
- Inherits:
-
BuildingBlock
- Object
- BuildingBlock
- Cxxproject::Linkable
- Includes:
- HasIncludes, HasLibraries, HasSources
- Defined in:
- lib/cxxproject/buildingblocks/linkable.rb
Direct Known Subclasses
Constant Summary
Constants included from HasLibraries
HasLibraries::DEPENDENCY, HasLibraries::LIB, HasLibraries::LIB_WITH_PATH, HasLibraries::SEARCH_PATH, HasLibraries::USERLIB
Instance Attribute Summary
Attributes included from HasSources
Attributes inherited from BuildingBlock
#config_files, #config_name, #name, #output_dir, #output_dir_abs, #pre_step, #project_dir, #tags
Instance Method Summary collapse
- #adapt_path(v, d, prefix) ⇒ Object
- #calc_command_line ⇒ Object
- #cmd_lib_string(target_os) ⇒ Object
- #collect_unique(array, set) ⇒ Object
-
#convert_to_rake ⇒ Object
create a task that will link an executable from a set of object files.
- #create_run_task(executable, name) ⇒ Object
-
#deps ⇒ Object
OK.
-
#executable_name ⇒ Object
relative path OK.
- #get_output_name(linker) ⇒ Object
-
#get_task_name ⇒ Object
full path.
- #get_temp_filename ⇒ Object
-
#handle_whole_archive(building_block, res, linker, flag) ⇒ Object
res the array with command line arguments that is used as result linker the linker hash sym the symbol that is used to fish out a value from the linker.
-
#initialize(name) ⇒ Linkable
constructor
A new instance of Linkable.
- #is_whole_archive(building_block) ⇒ Object
- #linker_lib_string(target_os, linker) ⇒ Object
- #no_sources_found ⇒ Object
-
#set_executable_name(name) ⇒ Object
ensure it's relative.
- #set_linker_script(x) ⇒ Object
- #set_mapfile(x) ⇒ Object
- #target_os ⇒ Object
Methods included from HasIncludes
#includes, #local_includes, #set_includes, #set_local_includes
Methods included from HasSources
#add_to_sources_to_build, #additional_object_file_flags, #apply_depfile, #calc_command_line_for_source, #calc_compiler_strings, #calc_dirs_with_files, #collect_sources_and_toolchains, #convert_depfile, #create_object_file_task, #create_object_file_tasks, #define_string, #deps_in_depFiles, #enhance_with_additional_files, #exclude_sources, #get_define_string, #get_dep_file, #get_include_string, #get_object_file, #get_source_type, #get_sources_task_name, #include_string, #parse_includes, #prepare_tasks_for_objects, #process_console_output, #set_exclude_sources, #set_source_patterns, #set_sources, #set_tcs4source, #source_patterns, #sources, #tcs4source
Methods included from HasLibraries
#add_lib_element, #add_lib_elements, #lib_elements
Methods inherited from BuildingBlock
#add_output_dir_dependency, #additional_path_components, #calc_complete_output_dir, #catch_output, #check_config_file, #complete_init, #complete_output_dir, #has_tcs?, #printCmd, #process_result, #read_file_or_empty_string, #remove_empty_strings_and_join, #set_config_files, #set_config_name, #set_name, #set_output_dir, #set_project_dir, #set_tcs, #setup_rake_dependencies, #tcs, #typed_file_task
Methods included from HasDependencies
#add_unique, #all_dependencies, #all_dependencies_recursive, #collect_dependencies, #convert_named_values_to_string, #dependencies, #direct_deps, #helper_dependencies, #resolve_by_name, #set_dependencies, #set_helper_dependencies
Constructor Details
#initialize(name) ⇒ Linkable
Returns a new instance of Linkable.
30 31 32 33 34 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 30 def initialize(name) super(name) @linker_script = nil @mapfile = nil end |
Instance Method Details
#adapt_path(v, d, prefix) ⇒ Object
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 75 def adapt_path(v, d, prefix) tmp = nil if File.is_absolute?(v) tmp = v else prefix ||= File.rel_from_to_project(@project_dir, d.project_dir) tmp = File.add_prefix(prefix, v) end [tmp, prefix] end |
#calc_command_line ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 162 def calc_command_line linker = @tcs[:LINKER] cmd = [linker[:COMMAND]] # g++ cmd += linker[:MUST_FLAGS].split(" ") cmd += linker[:FLAGS] cmd += get_flags_for_output(linker) cmd << executable_name() # debug/x.exe # OK cmd += @objects cmd << linker[:SCRIPT] if @linker_script # -T cmd << @linker_script if @linker_script # xy/xy.dld cmd << linker[:MAP_FILE_FLAG] if @mapfile # -Wl,-m6 cmd += linker[:LIB_PREFIX_FLAGS].split(" ") # TODO ... is this still needed e.g. for diab cmd += linker_lib_string(target_os(), @tcs[:LINKER]) cmd += linker[:LIB_POSTFIX_FLAGS].split(" ") # TODO ... is this still needed e.g. for diab cmd end |
#cmd_lib_string(target_os) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 93 def cmd_lib_string(target_os) libraries='' deps.each do |d| if HasLibraries === d d.lib_elements.each do |elem| case elem[0] when HasLibraries::SEARCH_PATH tmp, prefix = adapt_path(elem[1], d, prefix) libraries << tmp libraries << File::PATH_SEPARATOR end end end end libraries end |
#collect_unique(array, set) ⇒ Object
65 66 67 68 69 70 71 72 73 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 65 def collect_unique(array, set) ret = [] array.each do |v| if set.add?(v) ret << v end end ret end |
#convert_to_rake ⇒ Object
create a task that will link an executable from a set of object files
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 181 def convert_to_rake() object_multitask = prepare_tasks_for_objects() res = typed_file_task get_rake_task_type(), get_task_name => object_multitask do cmd = calc_command_line Dir.chdir(@project_dir) do mapfileStr = @mapfile ? " >#{@mapfile}" : "" rd, wr = IO.pipe cmdLinePrint = cmd printCmd(cmdLinePrint, "Linking #{executable_name}", false) #OK cmd << { :out=> @mapfile ? "#{@mapfile}" : wr, # > xy.map :err=>wr } sp = spawn(*cmd) cmd.pop # for console print cmd << " >#{@mapfile}" if @mapfile consoleOutput = ProcessHelper.readOutput(sp, rd, wr) process_result(cmdLinePrint, consoleOutput, @tcs[:LINKER][:ERROR_PARSER], nil) check_config_file() post_link_hook(@tcs[:LINKER]) end end res. = res.immediate_output = true res.enhance(@config_files) res.enhance([@project_dir + "/" + @linker_script]) if @linker_script add_output_dir_dependency(get_task_name, res, true) add_grouping_tasks(get_task_name) setup_rake_dependencies(res, object_multitask) # check that all source libs are checked even if they are not a real rake dependency (can happen if "build this project only") begin libChecker = task get_task_name+"LibChecker" do if File.exists?(get_task_name) # otherwise the task will be executed anyway all_dependencies.each do |bb| if bb and StaticLibrary === bb f = bb.get_task_name # = abs path of library if not File.exists?(f) or File.mtime(f) > File.mtime(get_task_name) def res.needed? true end break end end end end end rescue def res.needed? true end end libChecker. = true res.enhance([libChecker]) return res end |
#create_run_task(executable, name) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 243 def create_run_task(executable, name) namespace 'run' do desc "run executable #{executable}" res = task name => executable do |t| lib_var = @tcs[:ENV][:LIB_VAR][@tcs[:TARGET_OS]] if lib_var != '' ENV[lib_var] = cmd_lib_string(@tcs[:TARGET_OS]) end sh ["\"#{executable}\"", ENV['args']].compact.join(' ') end res.type = Rake::Task::RUN res end end |
#deps ⇒ Object
OK
86 87 88 89 90 91 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 86 def deps # OK if @deps == nil @deps = collect_dependencies end @deps end |
#executable_name ⇒ Object
relative path OK
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 45 def executable_name() # relative path OK return @exe_name if @exe_name parts = [@output_dir] if @output_dir_abs parts = [@output_dir_relPath] if @output_dir_relPath parts += additional_path_components() end linker = @tcs[:LINKER] parts << get_output_name(linker) @exe_name = File.join(parts) @exe_name end |
#get_output_name(linker) ⇒ Object
40 41 42 43 44 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 40 def get_output_name(linker) prefix = get_output_prefix(linker) suffix = get_output_suffix(linker) return "#{prefix}#{name}#{suffix}" end |
#get_task_name ⇒ Object
full path
61 62 63 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 61 def get_task_name() # full path @project_dir + "/" + executable_name # OK end |
#get_temp_filename ⇒ Object
258 259 260 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 258 def get_temp_filename Dir.tmpdir + "/lake.tmp" end |
#handle_whole_archive(building_block, res, linker, flag) ⇒ Object
res the array with command line arguments that is used as result linker the linker hash sym the symbol that is used to fish out a value from the linker
152 153 154 155 156 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 152 def handle_whole_archive(building_block, res, linker, flag) if is_whole_archive(building_block) res.push(flag) if flag and !flag.empty? end end |
#is_whole_archive(building_block) ⇒ Object
158 159 160 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 158 def is_whole_archive(building_block) return building_block.instance_of?(StaticLibrary) && building_block.whole_archive end |
#linker_lib_string(target_os, linker) ⇒ Object
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 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 110 def linker_lib_string(target_os, linker) lib_path_set = Set.new res = [] deps.each do |d| handle_whole_archive(d, res, linker, linker[:START_OF_WHOLE_ARCHIVE][target_os]) if HasLibraries === d and d != self #OK d.lib_elements.each do |elem| case elem[0] when HasLibraries::LIB if not is_whole_archive(d) res.push("#{linker[:LIB_FLAG]}#{elem[1]}") end when HasLibraries::USERLIB res.push("#{linker[:USER_LIB_FLAG]}#{elem[1]}") when HasLibraries::LIB_WITH_PATH if is_whole_archive(d) res.push(d.get_archive_name) else tmp, prefix = adapt_path(elem[1], d, prefix) res.push(tmp) end when HasLibraries::SEARCH_PATH if is_whole_archive(d) res.push(d.get_archive_name) else tmp, prefix = adapt_path(elem[1], d, prefix) if not lib_path_set.include?(tmp) lib_path_set << tmp res.push("#{linker[:LIB_PATH_FLAG]}#{tmp}") end end end end end handle_whole_archive(d, res, linker, linker[:END_OF_WHOLE_ARCHIVE][target_os]) end res end |
#no_sources_found ⇒ Object
262 263 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 262 def no_sources_found() end |
#set_executable_name(name) ⇒ Object
ensure it's relative
36 37 38 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 36 def set_executable_name(name) # ensure it's relative @exe_name = name end |
#set_linker_script(x) ⇒ Object
20 21 22 23 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 20 def set_linker_script(x) @linker_script = x self end |
#set_mapfile(x) ⇒ Object
25 26 27 28 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 25 def set_mapfile(x) @mapfile = x self end |
#target_os ⇒ Object
265 266 267 |
# File 'lib/cxxproject/buildingblocks/linkable.rb', line 265 def target_os @tcs[:TARGET_OS] end |