require 'xml' require 'active_support/ordered_hash' require 'pipeline/coding/projbuild/project' require 'pipeline/coding/xml2vsxml' require 'pipeline/coding/projbuild/scriptutility' require 'pipeline/coding/projbuild/generators/vsshared' require 'pipeline/coding/projbuild/custom/custom_build_step' require 'pipeline/os/file' require 'pipeline/os/path' module Pipeline module ProjBuild # these projects are for conditional inclusion in VS2010 ps3 unity only. PS3_UNITY_PROJECTS = ["vs_project_frags","vs_project_game_jobs","vs_project_binkspu","vs_project_jobs","vs_project_tasks"] #HACK: Global search paths to be shared across all RageGenSolutionLoaders created. $search_guid_paths = Hash.new() class RageGenSolutionLoader @@log = nil def RageGenSolutionLoader.log @@log = Log.new( 'ragegensolutionloader' ) if @@log == nil @@log end def initialize() if $search_guid_paths == nil $search_guid_paths = Hash.new() end end def import( path, output_format, options ) RageGenSolutionLoader.log.debug("Trying to import #{path} with ragegen project loader.") selected_template = ScriptUtility.determine_solution_template(path) if selected_template == nil RageGenSolutionLoader.log.debug("Template doesn't exist: #{selected_template}!") return false end config_filename = "#{selected_template}.configs" if output_format == :vs2010 config_filename = "#{selected_template}_2010.configs" RageGenSolutionLoader.log.info("Reading 2010 configs file : #{config_filename}") end if File.exists?(config_filename) == false then print "Config file does not exist: #{config_filename}\n" RageGenSolutionLoader.log.debug("template doesn't exist: #{config_filename}") return false end solution_generation = ScriptUtility.acquire_variable(path, 'NO_SOLUTION_GENERATION') if solution_generation != nil and solution_generation != "" #Due to our reliance on the RageGen generation method to generate multiple projects #in one folder, the ability to circumvent solution generation is inserted here. print "No solution generation is switched on within #{path}. No solutions will be generated.\n" return true end testers_var = ScriptUtility.acquire_variable(path, 'TESTERS') testers_var = "" if testers_var.nil? archive = ScriptUtility.acquire_variable(path, 'ARCHIVE') testers_var += " " + archive if archive.nil? == false @tester_array = testers_var.split(" ") @working_directory = File.dirname(path) build_data = ProjBuildData::instance() build_data.reset success = true projects = Array.new() @tester_array.each do |tester| basename = OS::Path.get_basename(tester) solution_file = OS::Path::combine(@working_directory, basename) print "Generating #{solution_file}...\n" #Read the .config file for all configurations to add to the solution. platforms = ActiveSupport::OrderedHash.new() targets = ActiveSupport::OrderedHash.new() File.readlines(config_filename).each { |line| tokens = line.split("=") sln = tokens[0] proj = tokens[1] sln_tokens = sln.split("|") if sln_tokens.size == 1 line.strip! print "Unable to parse line \"#{line}\" in #{config_filename}!\n" next end sln_target = sln.split("|")[0].strip sln_platform = VSProjShared.get_platform(sln.split("|")[1].strip) if proj == nil then proj = sln end if platforms[sln_platform] == nil then platforms[sln_platform] = Hash.new() end platforms[sln_platform][sln_target] = proj } #load in the root project... guid_filename = OS::Path::combine(@working_directory, basename) + ".guid" guid = VSProjShared.create_guid(guid_filename, @p4) project = Info::Project.new(basename) project.guid = guid project.path = Dir.getwd platforms.keys.each { |sln_platform| targets = platforms[sln_platform] targets.keys.each { |sln_target| proj_cfg = targets[sln_target] proj_platform, proj_target = VSProjShared.parse_config_name(proj_cfg) build_data.add_projectconfig(sln_platform,sln_target,project.guid,proj_platform,proj_target) } } build_data.projects[project.guid] = project build_data.root_guid = guid #load in each of the dependent projects... search_paths = Array.new() xproj = ScriptUtility.acquire_variable(path, 'XPROJ') if xproj != nil xproj.split(' ').each { |xpath| search_paths << xpath } end self_search_path = File.dirname(path) + "/" self_search_path = OS::Path.normalise(self_search_path) search_paths << self_search_path search_paths << "%RAGE_DIR%\\stlport\\STLport-5.0RC5\\" search_paths << "%RAGE_DIR%\\base\\src\\" search_paths << "%RAGE_DIR%\\suite\\src\\" search_paths << "%RAGE_DIR%\\base\\samples\\" search_paths << "%RAGE_DIR%\\suite\\samples\\" search_paths << "%RAGE_DIR%\\base\\tools\\" search_paths << "%RAGE_DIR%\\suite\\tools\\" libs = ScriptUtility.acquire_expanded_libs(path, basename) Dir.chdir(OS::Path.get_directory(path)) { if libs != nil libs.each { |lib| lib_name = OS::Path.get_basename(lib) lib = OS::Path.normalise(lib) guid = nil guid_filename = nil if (lib.index(":") == nil) and (lib.index("/") == nil) then found = false ambiguous = false base_guid_name = "#{lib_name}.guid" search_paths.each { |search_path| search_path = ScriptUtility.convert_paths_in_line(search_path) if $search_guid_paths[base_guid_name] != nil found = true guid_filename = $search_guid_paths[base_guid_name] break else search_path = File.join(search_path, "**", base_guid_name) search_path.gsub!("\\", "/") found_files = Dir.glob( search_path ) if found_files.size == 1 found = true guid_filename = found_files[0] $search_guid_paths[base_guid_name] = guid_filename break elsif found_files.size > 1 ambiguous = true break end end } if found == false if ambiguous == true RageGenSolutionLoader.log.debug("Ambiguous project! Multiple objects found; unable to resolve without a more precise path for project: #{lib}!") print "Multiple GUID files have been found with the same name #{lib}.guid. Unable to proceed!\n" else RageGenSolutionLoader.log.debug("Unable to find any file for the library: #{lib}!") print "Unable to find the library GUID: #{lib}\n" return end next end else lib = OS::Path.remove_extension(lib) lib = File.expand_path(lib) guid_filename = "#{lib}.guid" end guid_filename = OS::Path::make_relative( guid_filename, @working_directory ) guid = VSProjShared.create_guid(guid_filename, @p4) if guid == nil RageGenSolutionLoader.log.debug("Unable to acquire guid #{guid_filename}!") print "Unable to acquire guid #{guid_filename}!\n" return end guid = guid.strip.upcase child_project = Info::Project.new(lib_name) child_project.guid = guid child_project.path = OS::Path.get_directory(guid_filename) search_guid = child_project.guid[1..-2] ignore_guids = ENV['IGNORE_GUIDS'] ignore_guids = ScriptUtility.acquire_variable(path, 'IGNORE_GUIDS') if ignore_guids == nil #Assume that the startup project is dependent on all child projects. if ignore_guids == nil or ignore_guids.index(search_guid) == nil then project.dep_guids << child_project.guid end platforms.keys.each { |sln_platform| targets = platforms[sln_platform] targets.each_pair { |sln_target,proj_cfg| proj_platform, proj_target = VSProjShared.parse_config_name(proj_cfg) build_data.add_projectconfig(sln_platform,sln_target,child_project.guid,proj_platform,proj_target) } } build_data.dependent_projects[child_project.guid] = child_project } end } projects << project end return true, projects end end class RageGenProjectLoader < VSProjShared @@log = nil def RageGenProjectLoader.log @@log = Log.new( 'ragegenprojectloader' ) if @@log == nil @@log end def initialize(unity) @unity = unity config = Pipeline::Config.instance @p4 = SCM::Perforce.new() @p4.port = config.sc_server @p4.client = config.sc_workspace @p4.user = config.sc_username @p4.connect() end def find_files(path, extension, array) #Handle any regular expressions found_files = [] found_files = OS::FindEx::find_files_recurse( path + extension ) found_files.each do |found_file| array.insert(array.size, found_file) end end def process_qa_items(input_path) input_dir = File.dirname(input_path) found_files = OS::FindEx::find_files( OS::Path::combine(input_dir, "*.cpp") ) if found_files.size > 0 qaitems_header_path = OS::Path::combine(input_dir, "qaitems.h") qaitems_source_path = OS::Path::combine(input_dir, "qaitems.cpp") edit_in_p4(@p4, qaitems_header_path) edit_in_p4(@p4, qaitems_source_path) source_file_path = OS::Path::combine( input_dir, "*.cpp") grep_exe = get_egrep_exe_path() result = system(grep_exe + ' -h "^QA_ITEM" ' + source_file_path + ' > ' + qaitems_header_path) if result == false if File.exists?(qaitems_header_path) File.delete(qaitems_header_path) end revert_from_p4(@p4, qaitems_header_path) return end edit_in_p4(@p4, qaitems_header_path) #QA Items have been found, so add qaitems as a tester to regenerate and add to source control. @testers = @testers + " qaitems" result = system( grep_exe + ' -s -h "^QA_ITEM_DRAW" ' + qaitems_header_path ) if result == false if ENV["RAGE_DIR"] != nil system('copy' + ENV["RAGE_DIR"] + '\qa\src\unittest\qaitemsdraw.cpp ' + qaitems_source_path) end edit_in_p4(@p4, qaitems_source_path) return end @xdefine_var = @xdefine_var + " QA_ITEMS_DEPEND_ON_SAMPLE_GRCORE" end end def create_project_definition_file( directory, project_name, guid, specified_files ) project_definition_file_name = OS::Path::combine(directory, "#{project_name}.rsp") project_file = OS::Path::combine(directory, project_name) if File.exist?(project_file + ".cpp") project_file_source = project_file + ".cpp" duplicate_file = false specified_files.each do |file| if project_file_source == file duplicate_file = true break end end if duplicate_file == false specified_files.insert(specified_files.size, project_file_source) end elsif File.exist?(project_file + ".c") project_file_source = project_file + ".c" duplicate_file = false specified_files.each do |file| if project_file_source == file duplicate_file = true break end end if duplicate_file == false specified_files.insert(specified_files.size, project_file_source) end end #Add all extra files to the list. # TODO: Re-evaluate if this is ever necessary. if specified_files.size == 0 specified_files = [] specified_files = OS::FindEx::find_files( Pipeline::OS::Path::combine(directory, "*.h") ) #/.*[.]h|.*[.]cpp|(.*)[.]c/ specified_files += OS::FindEx::find_files( Pipeline::OS::Path::combine(directory, "*.cpp") ) specified_files += OS::FindEx::find_files( Pipeline::OS::Path::combine(directory, "*.c") ) end file = File.new(project_definition_file_name, 'w') #First line is always the project name file.write(project_name + "\n") #Second line is always the guid. file.write(guid + "\n") specified_files.each do |found_file| file.write(found_file + "\n") end file.close return project_definition_file_name end def import( path, output_format, options ) RageGenProjectLoader.log.info("RageGenProjectLoader import #{path} path output_format #{output_format}") @working_directory = File.dirname(path) #Makefile Variables @testers = ScriptUtility.acquire_variable( path, 'TESTERS' ) @testers = "" if @testers.nil? @xdefine_var = ScriptUtility.acquire_variable(path, 'XDEFINE') @xdefine_var = "" if @xdefine_var.nil? @custom_var = ScriptUtility.acquire_variable(path, 'CUSTOM') @custom_var = "" if @custom_var.nil? @archive = ScriptUtility.acquire_variable(path, 'ARCHIVE') #Add the VSI.nul object to the CUSTOM variable if on TESTER_BASE has been determined. tester_base = ScriptUtility.acquire_variable(path, 'TESTER_BASE') if @archive == nil #Deal with the QA Items process_qa_items(path) end ENV["TESTERS"] = @testers @tester_array = @testers.split(" ") @process_array = @tester_array @process_array << @archive if @archive != nil success = true projects = Array.new() #RageGenProjectLoader.log.info("@process_array is a #{@process_array.class}") @process_array.each do |process_project| process_project += VSProjShared.get_project_suffix(output_format) vcproj = OS::Path::combine(@working_directory, process_project) result, project = import_project(path, vcproj, output_format, options) if result == true projects << project end end return success, projects end def import_project(path, output, output_format, options) return false if File.exists?(path) == false version_suffix = VSProjShared.get_project_suffix(output_format) output_name = File.basename(output, version_suffix) #Remove the version suffix. output_path = OS::Path.get_directory(output) selected_template = nil if options[:template].nil? == false and File.exist?(options[:template]) == true projbuild_root = Globals::instance().toolsconfig + "/projbuild" selected_template = OS::Path::combine(projbuild_root, selected_template) #RageGenProjectLoader.log.info("Selected_template found BY RAGEGEN IS #{selected_template}") else selected_template = ScriptUtility.determine_project_template(path, output_name) #RageGenProjectLoader.log.info("Selected_template found BY RAGEGEN IS #{selected_template} ( ScriptUtility.determine_project_template)") end if selected_template.nil? #Defer this to possibly another generator. This is not an error. RageGenProjectLoader.log.debug("Unable to determine a template to use for project #{output_name}! This may be generated via another means.") return true end RageGenProjectLoader.log.debug("Trying to import #{path} with ragegen project loader.") if File.exists?(selected_template) == false template_filename = selected_template + VSProjShared.get_project_suffix(output_format) #RageGenProjectLoader.log.info("TEMPLATE FILENAME USED BY RAGEGEN IS #{template_filename}") if template_filename.nil? print "Bad Template File\n" RageGenProjectLoader.log.error("Unable to properly acquire a template file!") return false elsif File.exists?(template_filename) == false print "Unable to find template file: #{template_filename}.\n" RageGenProjectLoader.log.error("Unable to find template file #{template_filename}!") return false end end expanded_files = [] # A list of all files with their extensions to add to the project combined_files_value = ScriptUtility.acquire_variable( path, "FILES" ) if combined_files_value != nil value_files = combined_files_value.split(" ") value_files.each do |value_file| filename = OS::Path::combine(@working_directory, value_file) filename = File.expand_path(filename) find_files(filename, ".h", expanded_files) find_files(filename, ".c", expanded_files) find_files(filename, ".cpp", expanded_files) if File.exist?(filename) expanded_files << value_file end end end #Find a list of all header files included in this combined file. combined_files_value = ScriptUtility.acquire_variable( path, "HEADONLY" ) if combined_files_value != nil header_files = combined_files_value.split(" ") header_files.each do |header_file| header_file = header_file + ".h" expanded_files << header_file end end combined_files_value = ScriptUtility.acquire_variable( path, "CCODEONLY" ) if combined_files_value != nil c_files = combined_files_value.split(" ") c_files.each do |c_file| c_file = c_file + ".c" expanded_files << c_file end end combined_files_value = ScriptUtility.acquire_variable( path, "CODEONLY" ) if combined_files_value != nil cpp_files = combined_files_value.split(" ") cpp_files.each do |cpp_file| #Ensure we're testing for existence from the correct root. full_path_file = OS::Path::combine(output_path, cpp_file) full_path_file = File.expand_path(full_path_file) if File.exist?(full_path_file + ".cpp") expanded_files << cpp_file + ".cpp" elsif File.exist?(full_path_file + ".c") expanded_files << cpp_file + ".c" else File.exist?(full_path_file) expanded_files << cpp_file end end end #Any additional custom files. combined_files_value = @custom_var if combined_files_value != nil expanded_files += combined_files_value.split(" ") end #Additional Resource objects. combined_files_value = ScriptUtility.acquire_variable( path, "RESOURCES" ) if combined_files_value != nil expanded_files += combined_files_value.split(" ") end #Additional Embedded Shaders. embedded_shaders = nil combined_files_value = ScriptUtility.acquire_variable( path, "EMBEDDEDSHADERS" ) if combined_files_value != nil embedded_shaders = combined_files_value.split(" ") expanded_files += embedded_shaders end RageGenProjectLoader.log.info("RAGEGEN IS USING THE TEMPLATE : #{template_filename}.") parser = XML::Parser.file(template_filename) doc = parser.parse correct_version = VSProjShared.get_version(output_format) if doc.root.attributes["Version"] != correct_version then #print "Bad version number!\n" #RageGenProjectLoader.log.info("Template is not the correct Visual Studio version: #{doc.root.attributes['Version']} not #{correct_version}.") #return false end RageGenProjectLoader.log.debug("Parsing #{path} with ragegen project loader.") guid_filename = OS::Path::combine(@working_directory, output_name) + ".guid" guid = VSProjShared.create_guid(guid_filename, @p4) project_definition_file_name = create_project_definition_file(@working_directory, output_name, guid, expanded_files) if File.exists?(project_definition_file_name) == false RageGenProjectLoader.log.debug("Project definition file at: #{project_definition_file_name} could not be generated.") return false; end #Assume this is a project definition file. files = File.readlines(project_definition_file_name) project_name = files.delete_at(0).strip guid = files.delete_at(0).strip files.collect { |x| x.strip! } guid_filename = OS::Path.remove_extension(path) + ".guid" if File.exists?(guid_filename) then guid = File.readlines(guid_filename)[0].upcase RageGenProjectLoader.log.debug("guid filename #{guid_filename}, guid changed to: #{guid}") end temporary_filename = OS::Path.combine(Globals::instance().toolstemp,"temp.vcproj") #RageGenProjectLoader.log.info("Filling temporary vcproj #{temporary_filename}.") doc.root.attributes["Name"] = project_name doc.root.attributes["ProjectGUID"] = "{#{guid}}" #Acquire a list of all the pertinent environment variables here. @xproj_var = ScriptUtility.acquire_variable(path, 'XPROJ') @xproj_var = "" if @xproj_var.nil? @xinclude_var = ScriptUtility.acquire_variable(path, 'XINCLUDE') @xinclude_var = "" if @xinclude_var.nil? @temp_additional_includes = [] @temp_additional_includes = @xproj_var.split(" ") @temp_additional_includes.concat(@xinclude_var.split(" ")) @additional_includes = [] @temp_additional_includes.each do |include| include = ScriptUtility.find_include_definition( include ) found_duplicate = false @additional_includes.each do |added_include| if include.eql?(added_include) == true found_duplicate = true break end end if found_duplicate == false @additional_includes.insert(@additional_includes.size, include) end end @force_include = ScriptUtility.acquire_variable(path, 'FORCE_INCLUDE') @force_include = "" if @force_include.nil? @xbox_title_id = ScriptUtility.acquire_variable(path, 'XBOX_TITLE_ID') @xbox_spa_path = ScriptUtility.acquire_variable(path, 'XBOX_SPA_PATH') @warning_level = ScriptUtility.acquire_variable(path, 'WARNINGS') @parser_files = ScriptUtility.acquire_variable(path, 'PARSE') @output_name_pattern_var = ScriptUtility.acquire_variable(path, 'OUTPUT_NAME_PATTERN') @template_name = File.basename(selected_template) doc.find("/VisualStudioProject/Configurations/Configuration").each { |config_node| platform_config = config_node.attributes["OutputDirectory"] platform,config = VSProjShared.parse_config_name(config_node.attributes["Name"]) output_pattern = nil output_pattern_pdb = nil @embedded_lib_var = nil case platform when :xbox360: @embedded_lib_var_name = 'EMBEDDEDLIB_XENON' when :ps3: @embedded_lib_var_name = 'EMBEDDEDLIB_PSN' when :win32 @embedded_lib_var_name = 'EMBEDDEDLIB_WIN32' when :win64 @embedded_lib_var_name = 'EMBEDDEDLIB_WIN64' end @embedded_lib_var = ScriptUtility.acquire_variable(path, @embedded_lib_var_name) if @embedded_lib_var_name.nil? @embedded_lib_var = "" if @embedded_lib_var.nil? if @output_name_pattern_var != nil output_pattern_noext = @output_name_pattern_var output_pattern_noext = output_pattern_noext.gsub(/PLATFORM_CONFIG/,platform_config) if platform_config != nil output_pattern = "" output_pattern_pdb = "" case platform when :xbox360: output_pattern = output_pattern_noext.gsub(/EXT/,"xex") when :ps3: output_pattern = output_pattern_noext.gsub(/EXT/,"self") when :psp2: output_pattern = output_pattern_noext.gsub(/EXT/,"self") else output_pattern = output_pattern_noext.gsub(/EXT/,"exe") end output_pattern_pdb = output_pattern_noext.gsub(/EXT/,"pdb") end config_node.find("Tool").each { |node| case node.attributes["Name"] when "VCPreBuildEventTool": if @parser_files != nil then #Add pre-build event attributes #Preserve any additional pre-build steps. if node.attributes["CommandLine"] != nil node.attributes["Description"] = "Executing pre-build steps..." node.attributes["CommandLine"] = node.attributes["CommandLine"] + "\n" else node.attributes["Description"] = "Generating parser code..." node.attributes["CommandLine"] = "" end node.attributes["CommandLine"] = node.attributes["CommandLine"] + '$(RS_TOOLSROOT)\\bin\\coding\\python\\parCodeGen.exe ' + @parser_files end when "VCCLCompilerTool", "VCCLX360CompilerTool": if node.attributes["AdditionalIncludeDirectories"] != nil then if @xproj_var != nil node.attributes["AdditionalIncludeDirectories"] = node.attributes["AdditionalIncludeDirectories"] + ";" + @additional_includes.join(";") end end if node.attributes["ForcedIncludeFiles"] != nil and @force_include != nil then node.attributes["ForcedIncludeFiles"] = node.attributes["ForcedIncludeFiles"].gsub(/FORCE_INCLUDE/,@force_include) end if node.attributes["PreprocessorDefinitions"] != nil and @xdefine_var != nil then node.attributes["PreprocessorDefinitions"] = node.attributes["PreprocessorDefinitions"].gsub(/XDEFINE/,@xdefine_var) end if node.attributes["ProgramDataBaseFileName"] != nil then if output_pattern_pdb.nil? if node.attributes["ProgramDataBaseFileName"] != nil node.attributes["ProgramDataBaseFileName"] = node.attributes["ProgramDataBaseFileName"].gsub(/OUTPUT_FILE_NAME/, output_name) node.attributes["ProgramDataBaseFileName"] = node.attributes["ProgramDataBaseFileName"].gsub(/#{@template_name}/, output_name) end else node.attributes["ProgramDataBaseFileName"] = output_pattern_pdb end end if node.attributes["WarningLevel"] != nil then if @warning_level.nil? == false node.attributes["WarningLevel"] = @warning_level end end when "VCLibrarianTool": if output_pattern.nil? if node.attributes["OutputFile"] != nil node.attributes["OutputFile"] = node.attributes["OutputFile"].gsub(/OUTPUT_FILE_NAME/, output_name) node.attributes["OutputFile"] = node.attributes["OutputFile"].gsub(/#{@template_name}/, output_name) end else node.attributes["OutputFile"] = output_pattern end if node.attributes["AdditionalDependencies"] != nil and @embedded_lib_var != nil then node.attributes["AdditionalDependencies"] = node.attributes["AdditionalDependencies"].gsub(@embedded_lib_var_name, @embedded_lib_var.split(" ").join(";")) end when "VCX360ImageTool": if output_pattern.nil? if node.attributes["OutputFileName"] != nil node.attributes["OutputFileName"] = node.attributes["OutputFileName"].gsub(/OUTPUT_FILE_NAME/, output_name) else node.attributes["OutputFileName"] = "" end else node.attributes["OutputFileName"] = output_pattern end if node.attributes["AdditionalSections"] != nil and @xbox_title_id != nil and @xbox_spa_path != nil then node.attributes["AdditionalSections"] = node.attributes["AdditionalSections"].gsub(/XboxSpaLinkOpt/,"#{@xbox_title_id}=#{@xbox_spa_path}") else node.attributes["AdditionalSections"] = "" end if node.attributes["TitleID"] != nil and @xbox_title_id != nil then #Backwards Compatibility - if the title id does not have 0x prefix in front of it. if @xbox_title_id.index("0x") != 0 node.attributes["TitleID"] = node.attributes["TitleID"].gsub(/XboxTitleId/, "0x" + @xbox_title_id) else node.attributes["TitleID"] = node.attributes["TitleID"].gsub(/XboxTitleId/, @xbox_title_id) end else node.attributes["TitleID"] = "" end if node.attributes["ProjectDefaults"] != nil then node.attributes["ProjectDefaults"] = node.attributes["ProjectDefaults"].gsub(/XboxImageXexConfig/,"") end when "VCX360DeploymentTool": if node.attributes["DeploymentFiles"] != nil then replaceval = ENV['XBOX_DEPLOYMENT_FILES'] replaceval = "" if replaceval == nil node.attributes["DeploymentFiles"] = node.attributes["DeploymentFiles"].gsub(/XBOX_DEPLOYMENT_FILES/,replaceval) end when "VCLinkerTool","VCX360LinkerTool": if output_pattern.nil? if node.attributes["OutputFile"] != nil node.attributes["OutputFile"] = node.attributes["OutputFile"].gsub(/OUTPUT_FILE_NAME/, output_name) node.attributes["OutputFile"] = node.attributes["OutputFile"].gsub(/#{@template_name}/, output_name) end else if (node.attributes["Name"]=="VCX360LinkerTool" and output_format.to_s.include?("2010")) node.attributes["OutputFile"] = "$(TargetPath)" else node.attributes["OutputFile"] = output_pattern end end # override all 2010 output paths - due to weird VS2010 msbuild warnings if (output_format.to_s.include?("2010")) node.attributes["OutputFile"] = "$(TargetPath)" end if node.attributes["ProgramDatabaseFile"] != nil then if output_pattern_pdb.nil? if node.attributes["ProgramDatabaseFile"] node.attributes["ProgramDatabaseFile"] = node.attributes["ProgramDatabaseFile"].gsub(/OUTPUT_FILE_NAME/, output_name) node.attributes["ProgramDatabaseFile"] = node.attributes["ProgramDatabaseFile"].gsub(/#{@template_name}/, output_name) end else node.attributes["ProgramDatabaseFile"] = output_pattern_pdb end end end } } file_node = doc.find_first("/VisualStudioProject/Files") RageGenProjectLoader.log.error("Cant find /VisualStudioProject/Files #{doc}") unless file_node files.each { |filename| out_path = OS::Path.combine(output_path,filename) out_path = File.expand_path(out_path) out_path = OS::Path.make_relative(out_path,output_path) out_path = OS::Path.dos_format(out_path) new_node = XML::Node.new("File") new_node["RelativePath"] = out_path #Add any custom file configurations for this file. if embedded_shaders != nil base_filename = File.basename(out_path) embedded_shaders.each do |embedded_shader| if base_filename.eql?(embedded_shader) == true embedded_shader = OS::Path::combine(@working_directory, embedded_shader) #For every configuration add a new FileConfiguration doc.find("/VisualStudioProject/Configurations/Configuration").each do |config_node| config_name = config_node.attributes["Name"] platform,target = VSProjShared.parse_config_name(config_name) custom_step = Info::FxCustomBuild.new(embedded_shader, out_path, platform) custom_step_node = custom_step.create_node() file_configuration_node = XML::Node.new("FileConfiguration") file_configuration_node["Name"] = config_name file_configuration_node << custom_step_node new_node << file_configuration_node end end end else #For all non-standard files, look for a custom object in the projbuild root to use as a template. extension = File.extname(filename) extension = extension[1...extension.size] if extension.eql?("cpp") == false and extension.eql?("c") == false and extension.eql?("h") == false and extension.eql?("nul") == false custom_root = ScriptUtility.get_custom_root() custom_path = OS::Path::combine(custom_root, "#{extension}.custom") full_path = OS::Path::combine(@working_directory, filename) if File.exist?(custom_path) == true #For every configuration add a new FileConfiguration doc.find("/VisualStudioProject/Configurations/Configuration").each do |config_node| config_name = config_node.attributes["Name"] file_configuration = CustomBuildStep::get_file_configuration(custom_path, full_path, config_name) next if file_configuration.nil? file_configuration_node = XML::Node.new("FileConfiguration") tool_node = XML::Node.new(file_configuration) file_configuration_node["Name"] = config_name file_configuration_node << tool_node new_node << file_configuration_node end end end end file_node << new_node } #RageGenProjectLoader.log.info("Saving temporary file to #{temporary_filename}.") doc.save(temporary_filename) #RageGenProjectLoader.log.info("Passing #{temporary_filename} to Visual Studio loader.") if output_format == :vs2005 result, curr_project = VS2005VSProjLoader.new().import(temporary_filename, output_path) elsif output_format == :vs2008 or output_format == :vs2010 result, curr_project = VS2008VSProjLoader.new().import(temporary_filename, output_path) end if (output_format == :vs2010) # ====================================== DW - THIS NEEDS SORTED OUT ==================================================== # under VS2010 you need to add references for everything so that they are linked in #RageGenProjectLoader.log.info("DW attempting to add to the doc the library dependencies") testers_var = ScriptUtility.acquire_variable(path, 'TESTERS') testers_var = "" if testers_var.nil? #RageGenSolutionLoader.log.info("DW attempting to add to the doc the library dependencies testers_var #{testers_var}") archive = ScriptUtility.acquire_variable(path, 'ARCHIVE') testers_var += " " + archive if archive.nil? == false @tester_array = testers_var.split(" ") @working_directory = File.dirname(path) build_data = ProjBuildData::instance() build_data.reset success = true projects = Array.new() @tester_array.each do |tester| #RageGenSolutionLoader.log.info("DW attempting to add to the doc the library dependencies : running tester #{tester}") basename = OS::Path.get_basename(tester) libs = ScriptUtility.acquire_expanded_libs(path, basename) #RageGenSolutionLoader.log.info("libs #{libs.length} #{libs}") Dir.chdir(OS::Path.get_directory(path)) { if libs != nil libs.each { |lib| lib_name = OS::Path.get_basename(lib) next if lib_name.downcase.include?("shaders") #RageGenSolutionLoader.log.info("libs #{libs.length} #{libs}") ps3_unity_only = false PS3_UNITY_PROJECTS.each do |proj| if (lib.downcase.include?proj) ps3_unity_only = true end end if (ps3_unity_only) next unless @unity==true end lib = OS::Path.normalise(lib) guid = nil guid_filename = nil lib = OS::Path.remove_extension(lib) lib = File.expand_path(lib) guid_filename = "#{lib}.guid" guid_filename = OS::Path::make_relative( guid_filename, @working_directory ) guid = VSProjShared.create_guid(guid_filename, @p4) if guid == nil RageGenSolutionLoader.log.debug("Unable to acquire guid #{guid_filename}!") print "Unable to acquire guid #{guid_filename}!\n" return end guid = guid.strip.upcase child_project = Info::Project.new(lib_name) child_project.guid = guid child_project.path = OS::Path.get_directory(guid_filename) search_guid = child_project.guid[1..-2] ignore_guids = ENV['IGNORE_GUIDS'] ignore_guids = ScriptUtility.acquire_variable(path, 'IGNORE_GUIDS') if ignore_guids == nil #Assume that the startup project is dependent on all child projects. if ignore_guids == nil or ignore_guids.index(search_guid) == nil then curr_project.dep_guids << child_project.guid end #RageGenSolutionLoader.log.info("#Adding dependent project #{child_project.guid} #{child_project}") build_data.dependent_projects[child_project.guid] = child_project #RageGenSolutionLoader.log.info("curr_project.config.xml_data #{curr_project.config.xml_data}") project_refs_node = XML::Node.new("ProjectReferences") project_ref_node = XML::Node.new("ProjectReference") project_node = XML::Node.new("Project") unity = "" unity = "_unity" if @unity==true and not lib_name.downcase.include?"shaders" and ps3_unity_only==false #RageGenSolutionLoader.log.info("Unity is #{unity} #{@unity} for #{lib_name} ps3_unity_only = #{ps3_unity_only}") project_node.content = "#{child_project.guid}" project_ref_node["Include"] = "#{child_project.path}/#{lib_name}_2010#{unity}.vcxproj" if ps3_unity_only==true # this does not work - msbuild doesn;t support conditional project references! # Condition="'$(Configuration)|$(Platform)'=='Debug|Xbox 360'" # RageGenSolutionLoader.log.info("This project is conditional in MSBuild") project_ref_node["Condition"] = "'$(Platform)'=='PS3'" end project_ref_node << project_node project_refs_node << project_ref_node curr_project.config.xml_data << project_refs_node #RageGenSolutionLoader.log.info("================curr_project.config.xml_data===================\n #{curr_project.config.xml_data}") #curr_project.config.xml_data.find("ProjectReferences/ProjectReference") } # end libs.each end # if libs != nil } # end Dir.chdir end #end @tester_array.each end # end if (output_format == :vs2010) File.delete(project_definition_file_name) return result, curr_project end end class RageGenGenerator @@unity_build_filenames = nil # if true filenames that are created have "_unity" in them. def set_unity_build_filenames( set ) #RageGenProjectLoader.log.info(".............Set unity build filenames #{set}") @@unity_build_filenames = set end def get_unity_build_filenames( ) @@unity_build_filenames end def export( path, project, options = nil ) true end def import( path, options = nil ) RageGenProjectLoader.log.info("RageGenGenerator import path #{path} options #{options} unity #{get_unity_build_filenames()}") return false if options == nil case options[:type] when :solution: loader = RageGenSolutionLoader.new() return loader.import(path, options[:out_format], options) when :project: loader = RageGenProjectLoader.new(get_unity_build_filenames()) return loader.import(path, options[:out_format], options) end false end end end #module ProjBuild end #module Pipeline