# # File:: convert.rb # Command line wrapper for the projbuild system # # Pipeline:: # # Author:: Greg Smith # Date:: 5 February 2010 # # #----------------------------------------------------------------------------- # Uses #----------------------------------------------------------------------------- require 'pipeline/coding/projbuild.rb' require 'pipeline/coding/projconvert.rb' require 'pipeline/os/getopt' require 'pipeline/os/path' require 'pipeline/os/file' #----------------------------------------------------------------------------- # Helper Functions #----------------------------------------------------------------------------- def determine_input_format(in_file, output_format, options) file_only = File.basename(in_file).downcase makefile_txt = "Makefile.txt".downcase makefile_bat = "Makefile.bat".downcase preload_list_name = "Preload.list".downcase gather_items_name = "gatheritems.bat".downcase preload_list = OS::Path::combine(File.dirname(in_file), preload_list_name) out_generator = output_format if File.exist?(preload_list) == true if options != nil and options[:type] == :project in_format = :shadermakefile #A special case where makefile.bat is used along with a prewritten list of files; used for build shader libraries. out_generator = :shadermakefile else in_format = :ragegen end elsif file_only.eql?(gather_items_name) == true in_format = :qaitems out_generator = :qaitems elsif file_only.eql?(makefile_txt) == true in_format = :rageprojbuilder elsif file_only.eql?(makefile_bat) == true in_format = :ragegen elsif File.extname(file_only).eql?(".csproj") == true in_format = :csharp out_generator = :csharp elsif File.extname(file_only).eql?(".txt") == true in_format = :rageprojbuilder else in_format = nil in_file = nil out_generator = nil end return in_format, in_file, out_generator end def recurse_directory( recurse_dir, output_format, options, erroneous_files) project_files = [] project_files = OS::FindEx::find_files_recurse( recurse_dir ) errors = false project_files.each do |file| directory = File.dirname(file) in_generator, file, out_generator = determine_input_format(file, output_format, options) if in_generator != nil projConvert = Pipeline::ProjBuild::ProjConvert.new() if projConvert.execute(file, in_generator, out_generator, options) == false erroneous_files << file errors = true end end end return errors end def report_errors( files_array ) print "\nErrors have occurred! Check logs in rage\\framework\\tools\\logs\\convert for more information.\n" print "Files With Errors:\n" files_array.each do |error_file| print "\t#{error_file}\n" end end #----------------------------------------------------------------------------- # Implementation #----------------------------------------------------------------------------- COMMAND_OPTIONS = [ ["--help", "-h", Getopt::BOOLEAN, "Display help text." ], ["--in", "-i", Getopt::OPTIONAL, "File to import." ], ["--in_format", "-if", Getopt::OPTIONAL, "File format to import (e.g. ragegen, rageprojbuilder, vs2005, vs2008)." ], ["--out", "-o", Getopt::OPTIONAL, "File to export." ], ["--out_format", "-of", Getopt::OPTIONAL, "File format to export (e.g. ragegen, rageprojbuilder, vs2005, vs2008)." ], ["--dir", "-d", Getopt::OPTIONAL, "Directory to traverse and convert all underlying projects." ], ["--nosolutions", "-ns", Getopt::BOOLEAN, "Option to skip solution generation." ], ["--nocsharp", "-nc", Getopt::BOOLEAN, "Option to skip C# project generation." ], ["--unity_build_enabled", "-ns", Getopt::BOOLEAN, "Option to permit unity build. Remove if you do not wish to have a unity build built." ], ] TRAILING_DESC = { } # DW: Enforce log level info due to existing tools install issue with log level debug being set for new installs. g_Config = Pipeline::Config.instance( ) g_Config::log_level = 2 if g_Config::log_level < 2 opts, trailing = Pipeline::OS::Getopt.getopts( COMMAND_OPTIONS ) if ( opts["help"] ) then puts OS::Getopt.usage( COMMAND_OPTIONS, TRAILING_DESC ) exit( 1 ) end options = Hash.new trailing.each { |item| tokens = item.split("=") key = tokens[0].intern if key == :type then options[key] = tokens[1].intern else options[key] = tokens[1] end } root_dir = nil root_dir = opts["dir"].intern if opts["dir"] != nil root_dir = root_dir.to_s in_format = nil in_format = opts["in_format"].intern if opts["in_format"] != nil out_format = nil out_format = opts["out_format"].intern if opts["out_format"] != nil no_solution_generation = false if ( opts["nosolutions"] ) then no_solution_generation = true end no_csharp_generation = false if ( opts["nocsharp"] ) then no_csharp_generation = true end if ( opts["unity_build_enabled"] ) then unity_build_enabled = true end options[:type] = :project options[:out_format] = out_format config = Pipeline::Config.instance config.project.load_config config.project.codeconfigs.each do |codeconfig| # for now completely ignores options passed in - later we can allow options to be overrided - but not now during development - it's complex enough - DW options[:out_format] = codeconfig.compiler options[:unity_build_enabled] = codeconfig.unity_build.enabled if (not unity_build_enabled) and options[:unity_build_enabled] print "You switched off unity builds in the commandline so convert.rb won't generate anything if a unity build was specifically requested in the project.xml.\n" next end if root_dir.nil? or root_dir.eql?("") in_file = opts['in'] out_file = opts['out'] if in_file.nil? print "Input file is not specified! Unable to continue!\n" exit(1) end if out_file.nil? print "Output file iscls not specified! Unable to continue!\n" exit(1) end if out_format.nil? print "Output format is not specified! Unable to continue!\n" exit(1) end if in_format.nil? in_format, in_file = determine_input_format(in_file, options) end projConvert = Pipeline::ProjBuild::ProjConvert.new() if projConvert.execute(in_file, in_format, out_file, out_format, options) == false print "Error generating: #{out_file}!\n" else print "Project generation has succeeded!\n" end else erroneous_files = [] print "Recursing directory: #{root_dir}...\n" if no_csharp_generation == false then print "Processing C# projects...\n" search_file = '*.csproj' recurse_dir = Pipeline::OS::Path::combine(root_dir, search_file) errors = recurse_directory(recurse_dir, out_format, options, erroneous_files) if errors == true report_errors(erroneous_files) Pipeline::LogSystem.instance().shutdown(); exit(1) end end search_file = 'gatheritems.bat' recurse_dir = Pipeline::OS::Path::combine(root_dir, search_file) errors = recurse_directory(recurse_dir, out_format, options, erroneous_files) if errors == true report_errors(erroneous_files) Pipeline::LogSystem.instance().shutdown(); exit(1) end if ( no_solution_generation == false ) search_file = 'makefile.bat' #Note that solutions are only triggered off of files with this particular name. recurse_dir = Pipeline::OS::Path::combine(root_dir, search_file) print "Processing solutions...\n" options[:type] = :solution errors = recurse_directory(recurse_dir, out_format, options, erroneous_files) if errors == true report_errors(erroneous_files) Pipeline::LogSystem.instance().shutdown(); exit(1) end end search_file = 'makefile.bat' # This is the name of the file manually created that defines the vcproj contents. recurse_dir = Pipeline::OS::Path::combine(root_dir, search_file) print "Processing projects...\n" options[:type] = :project errors = recurse_directory(recurse_dir, out_format, options, erroneous_files) if errors == true report_errors(erroneous_files) Pipeline::LogSystem.instance().shutdown(); exit(1) end search_file = 'makefile.txt' # This is the name of the file manually created that defines the vcproj contents. recurse_dir = Pipeline::OS::Path::combine(root_dir, search_file) errors = recurse_directory(recurse_dir, out_format, options, erroneous_files) if errors == true report_errors(erroneous_files) Pipeline::LogSystem.instance().shutdown(); exit(1) end search_file = '*.projdef' # Specific extension to find files. recurse_dir = Pipeline::OS::Path::combine(root_dir, search_file) errors = recurse_directory(recurse_dir, out_format, options, erroneous_files) if errors == true report_errors(erroneous_files) Pipeline::LogSystem.instance().shutdown(); exit(1) end #Process all directories that have a .txt, which we assume is a project definition file. project_dirs = [] project_dirs = OS::FindEx::find_dirs_recurse( root_dir ) errors = false project_dirs.each do |dir| directory_name = File.basename(dir); file = OS::Path::combine(dir, directory_name + ".txt") next if File.exist?(file) == false in_generator, file, out_generator = determine_input_format(file, out_format, options) if in_generator != nil projConvert = Pipeline::ProjBuild::ProjConvert.new() if projConvert.execute(file, in_generator, out_generator, options) == false erroneous_files << file errors = true end end end if errors == true report_errors(erroneous_files) Pipeline::LogSystem.instance().shutdown(); exit(1) end print "Project generation has succeeded!\n" Pipeline::LogSystem.instance().shutdown(); end end