304 lines
9.0 KiB
Ruby
Executable File
304 lines
9.0 KiB
Ruby
Executable File
#
|
|
# File:: %RS_TOOLSLIB%/util/findMakefiles.rb
|
|
# Description:: ironruby script that recursively scans for projgen.config files and all recognised makefiles
|
|
# it then produces a series of local *.makefiles files.
|
|
# - each file contains the correct build directive to build the makefiles with the appropriate settings
|
|
#
|
|
# Author:: Derek Ward <derek.ward@rockstarnorth.com>
|
|
# Date:: 04th October 2012
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'RSG.Base.dll'
|
|
require 'mscorlib'
|
|
require 'System.Core'
|
|
require 'pathname'
|
|
|
|
require 'RSG.Pipeline.Core.dll'
|
|
require 'RSG.Base.Configuration.dll'
|
|
require 'RSG.Base.Windows.dll'
|
|
require 'RSG.SourceControl.Perforce.dll'
|
|
|
|
include System::IO
|
|
include RSG::Base::Logging
|
|
include RSG::Base::Logging::Universal
|
|
include RSG::Base::OS
|
|
include RSG::Base::Configuration
|
|
include RSG::Base::Windows
|
|
include RSG::Pipeline::Core
|
|
include RSG::SourceControl::Perforce
|
|
|
|
require 'pipeline/os/options'
|
|
include Pipeline
|
|
|
|
using_clr_extensions RSG::Base::Extensions
|
|
using_clr_extensions System::Linq
|
|
|
|
module FindMakeFiles
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Constants
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Order matters, slndefs should be converted after makefiles.
|
|
MAKEFILE_SEARCHES = [ "*.makefile", "makefile.txt", "*.slndef" ]
|
|
BUILDFILE_SEARCHES = [ "projgen.config" ]
|
|
|
|
AUTHOR = 'RSGEDI Tools'
|
|
EMAIL = 'RSGEDI Tools <*tools@rockstarnorth.com>'
|
|
|
|
OPTIONS = [
|
|
LongOption::new( 'nonrecursive', LongOption::ArgType.None, '1', 'Do not recurse.' ),
|
|
LongOption::new( 'exclude', LongOption::ArgType.Required, 'x', 'Exclusion Regex' )
|
|
]
|
|
|
|
class Utility
|
|
#------------------------------------------------------------------
|
|
# search routine
|
|
def Utility::search_files( searches, list, searchOptions, exclusionRegex, log )
|
|
searches.each do |search|
|
|
files = Directory::GetFiles(Dir.pwd, search, searchOptions )
|
|
files = files.collect { |f| File.expand_path(f) }
|
|
|
|
excluded = 0
|
|
if exclusionRegex # delete_if doesnt work!!!!
|
|
newfiles = []
|
|
files.each do |f|
|
|
if (f=~exclusionRegex)
|
|
excluded += 1
|
|
log.Message " excluding #{f}"
|
|
else
|
|
newfiles << f
|
|
end
|
|
end
|
|
files = newfiles
|
|
end
|
|
|
|
list.concat files
|
|
log.Message "- Discovered #{files.length} x #{search} : #{excluded} excluded" if (files.length>0)
|
|
end
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
if ( __FILE__ == $0 ) then
|
|
# Initialise log and console output.
|
|
|
|
puts "a"
|
|
LogFactory.Initialize()
|
|
puts "b"
|
|
g_Log = LogFactory.method(:CreateUniversalLog).call( 'findMakefiles' )
|
|
puts "c"
|
|
LogFactory.CreateApplicationConsoleLogTarget( )
|
|
puts "d"
|
|
|
|
g_Options = OS::Options::new( OPTIONS )
|
|
puts "e"
|
|
|
|
begin
|
|
|
|
if ( g_Options.is_enabled?( 'help' ) )
|
|
g_Log.Message "#{__FILE__}"
|
|
g_Log.Message "Usage:"
|
|
g_Log.Message g_Options.usage()
|
|
exit( 1 )
|
|
end
|
|
|
|
g_Recurse = g_Options.get( 'nonrecursive' ) ? false : true
|
|
searchOptions = g_Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly
|
|
|
|
g_ExclusionRegex = nil
|
|
|
|
if g_Options.has_option?( 'exclude' )
|
|
regex = g_Options.get( 'exclude' )
|
|
g_ExclusionRegex = Regexp.new( regex, 'i')
|
|
g_Log.Message " "
|
|
g_Log.Message "Excluding #{regex}"
|
|
g_Log.Message " "
|
|
end
|
|
|
|
makefiles = []
|
|
buildfiles = []
|
|
|
|
#
|
|
# Search recursively for specific files.
|
|
#
|
|
|
|
g_Log.Message " "
|
|
g_Log.Message "--------------------- Recursive Directory Search --------------------" if g_Recurse
|
|
g_Log.Message "------------------- Non Recursive Directory Search ------------------" unless g_Recurse
|
|
g_Log.Message " Searching within #{Dir.pwd}..."
|
|
|
|
Utility::search_files(MAKEFILE_SEARCHES, makefiles, searchOptions, g_ExclusionRegex, g_Log)
|
|
Utility::search_files(BUILDFILE_SEARCHES, buildfiles,searchOptions, g_ExclusionRegex, g_Log)
|
|
|
|
g_Log.Message " "
|
|
g_Log.Message " Searching (walking up) #{Dir.pwd}..."
|
|
# these buildfiles can be in a folder above!
|
|
BUILDFILE_SEARCHES.each do |search|
|
|
path_name = Pathname.new(Dir.pwd)
|
|
begin
|
|
path_name = path_name.parent
|
|
if (path_name!=nil)
|
|
files = Directory::GetFiles(path_name.to_s, search, SearchOption.TopDirectoryOnly)
|
|
files = files.collect { |f| File.expand_path(f) }
|
|
|
|
excluded = 0
|
|
if g_ExclusionRegex
|
|
newfiles = []
|
|
files.each do |f|
|
|
if (f=~g_ExclusionRegex)
|
|
excluded += 1
|
|
#g_Log.Message " excluding #{f}"
|
|
else
|
|
newfiles << f
|
|
end
|
|
end
|
|
files = newfiles
|
|
end
|
|
|
|
g_Log.Message "- Discovered #{files.length} x #{search} : #{excluded} excluded" if (files.length>0)
|
|
|
|
buildfiles.concat files
|
|
end
|
|
end while (path_name!=nil && !path_name.root?)
|
|
end
|
|
|
|
g_Log.Message "---------------------------------------------------------------------"
|
|
|
|
#
|
|
# Get all the build files.
|
|
#
|
|
# - DW: TODO will conversion order become a concern?
|
|
# Actually I don't think I can practically guarantee any order by virtue of the batching I do.... bah
|
|
buildfiles = buildfiles.sort{|x, y| File.dirname(y).length <=> File.dirname(x).length}
|
|
|
|
buildfile_hash = {}
|
|
|
|
buildfiles.each do |build_file|
|
|
f = File.open(build_file)
|
|
lines = f.readlines
|
|
|
|
fileScope = nil
|
|
tmpFile = nil
|
|
squiggle_depth = 0
|
|
|
|
lines.each do |line|
|
|
|
|
#g_Log.Message ">>>#{line}"
|
|
|
|
if (/\s*#(.*)/.match(line)) # ignore comments
|
|
# deliberately left empty
|
|
elsif fileScope != nil
|
|
squiggle_depth += 1 if line.trim.ends_with("{")
|
|
squiggle_depth -= 1 if line.trim.ends_with("}")
|
|
|
|
if squiggle_depth<=0
|
|
fileScope = nil
|
|
tmpFile = nil
|
|
else
|
|
g_Log.Message "Writing #{fileScope} : #{line}"
|
|
tmpFile.write(line)
|
|
end
|
|
|
|
elsif (/(.*)\s*\{/.match(line))
|
|
filename = $1
|
|
g_Log.Message "Matched filename #{filename}"
|
|
fileScope = Environment.ExpandEnvironmentVariables(filename)
|
|
g_Log.Message "Creating #{fileScope}"
|
|
tmpFile = File.open(fileScope)
|
|
squiggle_depth += 1
|
|
elsif (/\s*(.+)\s*/.match(line)) # this is what we are looking for.
|
|
setup_file = $1
|
|
# TODO : figure out why this aint workin
|
|
#setup_file = System::Object::Environment::ExpandEnvironmentVariables(setup_file)
|
|
#setup_file = File.expand_path(setup_file)
|
|
#g_Log.Message setup_file
|
|
buildfile_hash[setup_file] = build_file
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
#
|
|
# Order hash - we have to match with the deepest project.config
|
|
#
|
|
|
|
all_makefiles = {}
|
|
buildfile_hash.each_key do |key|
|
|
all_makefiles[key] = []
|
|
end
|
|
|
|
# I know hashes are unordered - this is ruby magic.
|
|
buildfile_sorted = buildfile_hash.sort_by { |key, val| File.dirname(val).length }.reverse
|
|
g_Log.Message " "
|
|
|
|
g_Log.Message "-------------------------- ProjGen.Configs --------------------------"
|
|
buildfile_sorted.each do |h|
|
|
g_Log.Message "#{h[1]}:"
|
|
g_Log.Message "\t( #{h[0]} )"
|
|
end
|
|
g_Log.Message "---------------------------------------------------------------------"
|
|
g_Log.Message " "
|
|
|
|
#
|
|
# Construct a hash keyed by setup file and the makefiles beneath to process,
|
|
#
|
|
|
|
makefiles.each do |makefile|
|
|
|
|
found = false
|
|
|
|
# this deepest buildfile needs to match first
|
|
buildfile_sorted.each do |a|
|
|
setup_file = a[0]
|
|
buildfile = a[1]
|
|
#g_Log.Message "matching #{buildfile} for #{makefile}"
|
|
dir = File.dirname(buildfile)
|
|
if (makefile.include?(dir))
|
|
#g_Log.Message "#{f} chooses build setup file #{setup_file}"
|
|
all_makefiles[setup_file] << makefile
|
|
found = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if (!found)
|
|
g_Log.Error( "Makefile can't find a projgen.config in its source tree and above #{makefile}" )
|
|
end
|
|
|
|
end
|
|
|
|
#
|
|
# each key is serialised to a ,makefiles file so that it can be converted externally
|
|
# DW: - if I had designed the project generator to be a dll ( but I didn't ) I could have run it directly in here
|
|
#
|
|
i = 0
|
|
all_makefiles.each_pair do |build_file, makefiles|
|
|
if (makefiles.length>0)
|
|
File.open("#{i}.makefiles", 'w') do |f|
|
|
f.puts("build #{build_file}\n")
|
|
makefiles.each do |makefile|
|
|
f.puts("#{makefile}\n")
|
|
end
|
|
end
|
|
i+=1
|
|
end
|
|
end
|
|
|
|
rescue SystemExit => ex
|
|
exit( ex.status )
|
|
|
|
rescue Exception => ex
|
|
ConsoleLog::new( )
|
|
Log::Log__Error( "Unhandled error in findMakefiles.rb" )
|
|
Log::Log__Error( ex.backtrace.join("\n" ) + "\n" + ex.Message )
|
|
end
|
|
end
|
|
|
|
end # module findMakeFiles
|