Files
gtav-src/tools_ng/lib/pipeline/coding/projbuild/config.rb
T
2025-09-29 00:52:08 +02:00

514 lines
12 KiB
Ruby
Executable File

#generic xml config data...
#bye bye vs project
require 'xml'
require 'active_support/ordered_hash'
require 'singleton'
module Pipeline
module ProjBuild
module Info
class PlatformInfo
include Singleton
attr_reader :platforms
def initialize()
@platforms = ActiveSupport::OrderedHash.new()
@platforms[:ps3] = "PS3"
@platforms[:psp2] = "PSP2"
@platforms[:win32] = "Win32"
@platforms[:win64] = "Win64"
@platforms[:xbox360] = "Xbox360"
end
def is_valid( platform_sym )
return true if @platforms[platform_sym] != nil
false
end
def get_platform_symbol( platform_str )
@platforms.keys.each { |symbol|
string = @platforms[symbol]
if string.eql?(platform_str) == true
return symbol
end
}
nil
end
def create_output_path( platform, target)
output_path = case platform
when :win32
"win32_#{target}"
when :win64
"win64_#{target}"
when :xbox360
"xenon_#{target}"
when :ps3
"psn_#{target}"
when :psp2
"psp2_#{target}"
end
output_path.downcase
end
end
class CustomBuild
attr_reader :command, :output, :dependencies
attr_writer :command, :output, :dependencies
def initialize()
@command = nil
@output = nil
@dependencies = nil
@description = nil
end
def initialize(command, output, dependencies, description)
@command = command
@output = output
@dependencies = dependencies
@description = description
end
def create_node()
xml_node = XML::Node.new("custombuild")
xml_node["Name"] = "custombuild"
xml_node["CommandLine"] = @command
xml_node["Outputs"] = @output if @output != nil
xml_node["AdditionalDependencies"] = @dependencies if @dependencies != nil
xml_node["Description"] = @description if @description != nil
xml_node
end
def find_dependencies( path, rel_path )
#todo: this works as well as the one in rageprojbuilder but doesn't
#find any files if there are based on other include paths that just relative
#to the custom build file
path = ::File.expand_path(path)
@deps = ActiveSupport::OrderedHash.new()
@scanned = ActiveSupport::OrderedHash.new()
find_dependencies_inner(path,nil)
dependencies = Array.new()
@deps.keys.each { |dep|
dependencies << dep.gsub(OS::Path.get_directory(path),rel_path)
}
@dependencies = dependencies.join(";")
#Don't print out the dependencies element of the custom build step if we don't have to.
@dependencies = nil if @dependencies.size == 0
end
protected
def find_dependencies_inner( path, parent_path )
return nil if @scanned[path]
return nil if ::File.exists?(path) == false
@scanned[path] = true
if parent_path != nil then
@deps[path] = true
end
parent_path = OS::Path.get_directory(path)
::File::open( path ) do |fp|
lines = fp.readlines( )
lines.each do |line|
if line.index("#include") != nil or line.index(".include") != nil then
re = /[\.|#]include "([a-zA-Z0-9_\.\/\\]+)"/
md = re.match(line)
next if md == nil
include_path = OS::Path.combine(parent_path,md[1])
find_dependencies_inner(include_path,parent_path)
end
end
end
end
end
class JobCustomBuild < CustomBuild
def initialize( path, file_info )
rel_path = ::File.dirname(file_info.path);
@command = "call $(RS_TOOLSROOT)\\script\\coding\\custom_steps\\make_spurs_job_pb $(InputDir) $(IntDir) $(InputName) &quot;$(ConfigurationName)&quot;"
@output = "$(IntDir)/$(InputName).job.obj"
find_dependencies(path, rel_path)
end
end
class FragCustomBuild < CustomBuild
def initialize( path )
@command = "call $(RS_TOOLSROOT)\\script\\coding\\custom_steps\\make_spu_frag_pb $(InputDir) $(IntDir) $(InputName) &quot;$(ConfigurationName)&quot;"
@output = "$(IntDir)/$(InputName).frag.obj"
#need to scan through the file to see if there are any other dependencies...
end
end
class TaskCustomBuild < CustomBuild
def initialize( path )
@command = "call $(RS_TOOLSROOT)\\script\\coding\\custom_steps\\make_spurs_task_pb $(InputDir) $(IntDir) $(InputName) &quot;$(ConfigurationName)&quot;"
@output = "$(IntDir)/$(InputName).task.obj"
#need to scan through the file to see if there are any other dependencies...
end
end
class FxCustomBuild < CustomBuild
def initialize( path, file_path, platform_sym )
rel_path = ::File.dirname(file_path);
platform_out = ActiveSupport::OrderedHash.new()
platform_out[:ps3] = "psn"
platform_out[:win32] = "win32_30"
platform_out[:win64] = "win32_30"
platform_out[:xbox360] = "fxl_final"
platform_out[:psp2] = "psp2"
#This custom step prior had:
#rem IncrediBuild_DontAllowRemote&#x0D;&#x0A;
#at the front to tell IncrediBuild that the custom build step would be executed only locally.
#The IncrediBuild database no longer supports this indicator and has deferred to a default
#of all custom build steps being executed locally unless specifying otherwise with:
# REM IncrediBuild_AllowRemote
#
@description = "Building embedded shader $(InputName) . . ."
@command = "cmd /c &quot;chdir $(InputDir) &amp;&amp; call $(RS_TOOLSROOT)\\script\\coding\\shaders\\makeembeddedshader.bat -platform #{platform_out[platform_sym]} $(InputName).fx&quot;"
@output = "$(InputDir)\\embedded_$(InputName)_#{platform_out[platform_sym]}.h"
find_dependencies(path, rel_path)
#need to scan through the file to see if there are any other dependencies...
end
end
class PscCustomBuild < CustomBuild
def initialize( path, file_path, vs2010 = false )
@vs2010 = vs2010
rel_path = ::File.dirname(file_path);
@dependencies_array = Array.new()
find_psc_dependencies(path, rel_path)
@description = "Generating parser code..."
if @vs2010
@command = "pushd $(InputDir) &amp;&amp; $(RS_TOOLSROOT)\\bin\\coding\\python\\parCodeGen.exe %(filename)%(extension) "
else
@command = "pushd $(InputDir) &amp;&amp; $(RS_TOOLSROOT)\\bin\\coding\\python\\parCodeGen.exe $(InputFileName) "
end
@dependencies_array.each { |x|
@command << "--depends #{x} "
}
@command << "&amp;&amp; popd"
@output = "$(InputDir)\\$(InputName)_parser.h" # do we need to list these too? $(InputName).h %(InputName).cpp"
@dependencies_array.push("$(RS_TOOLSROOT)\\bin\\coding\\python\\parCodeGen.zip") # add this so we rebuild the .pscs if the code generator changes
@dependencies = @dependencies_array.join(";")
#Don't print out the dependencies element of the custom build step if we don't have to.
@dependencies = nil if @dependencies.size == 0
end
@@import_token = "<import"
@@href_token = "href=\""
def find_psc_dependencies( path, relative_path )
@deps = ActiveSupport::OrderedHash.new()
@scanned = ActiveSupport::OrderedHash.new()
path = ::File.expand_path(path)
f = ::File.new(path)
lines = f.readlines
f.close
lines.each { |line|
line.strip!
if line.index(@@import_token) != nil
href_index = line.index(@@href_token) + @@href_token.length
end_quote_index = line.index("\"", href_index+1)
if end_quote_index != nil
href_attribute = line[href_index,end_quote_index-href_index]
new_dependency = process_import(href_attribute, relative_path)
@dependencies_array << new_dependency
find_psc_dependencies_inner(new_dependency,nil)
end
end
}
end
def find_psc_dependencies_inner( path, parent_path )
return nil if @scanned[path]
return nil if ::File.exists?(path) == false
@scanned[path] = true
if parent_path != nil then
@deps[path] = true
end
parent_path = OS::Path.get_directory(path)
f = ::File.new(path)
lines = f.readlines
f.close
lines.each { |line|
line.strip!
if line.index(@@import_token) != nil
href_index = line.index(@@href_token) + @@href_token.length
end_quote_index = line.index("\"", href_index+1)
if end_quote_index != nil
href_attribute = line[href_index,end_quote_index-href_index]
new_dependency = process_import(href_attribute, parent_path)
@dependencies_array << new_dependency
find_dependencies_inner(new_dependency,parent_path)
end
end
}
end
def process_import(href_attribute, parent_path)
#Once a new dependency is acquired, convert any environment variables
#it may contain. Since the psc files are based in Python, the syntax will be
#like: ${RS_BUILDBRANCH} or ${RS_TOOLSROOT}. Use $(RS_BUILDBRANCH) or $(RS_TOOLSROOT).
new_dependency = href_attribute.gsub("", "") #HACK: Without calling gsub and creating a copy, Ruby will use the same pointer in the below loop. Doing so will cause an obscure "string modified" exception.
has_matches = false
reg_expr = /([\$\{\[a-zA-Z0-9_\.]+\}\]*)/
href_attribute.gsub(reg_expr) { |match|
env_var_expr = /([a-zA-Z0-9_\.])+/
env_var_match = env_var_expr.match(match.to_s)
env_var_match.to_a.each { |env_var|
has_matches = true
new_dependency.gsub!(match, "$(#{env_var})")
}
}
if has_matches == false
new_dependency = OS::Path.combine(parent_path, href_attribute)
end
return new_dependency
end
end
class VSICustomBuild < CustomBuild
def initialize( path )
@command = "echo &gt; NUL"
@output = "\"$(IntDir)\\vsi.out\""
#need to scan through the file to see if there are any other dependencies...
end
end
class PreBuild
def initialize( buildsteps )
@buildsteps = buildsteps
end
def create_node()
xml_node = XML::Node.new("prebuild")
xml_node["count"] = @buildsteps.size.to_s
index = 0
@buildsteps.each { |buildstep|
xml_new = XML::Node.new("buildstep")
xml_new["cmd"] = buildstep
xml_new["index"] = index.to_s
index = index + 1
xml_node << xml_new
}
xml_node
end
end
class LibraryDirectory
attr_reader :path, :platform
def initialize( path, platform = nil)
@path = path
@platform = platform
end
def create_node()
xml_new = XML::Node.new("librarydirectory")
xml_new["path"] = @path
xml_new
end
end
class LibraryDirectories
def initialize( paths )
@paths = paths
end
def create_node()
xml_node = XML::Node.new("librarydirectories")
@paths.each { |path|
xml_new = path.create_node()
xml_node << xml_new
}
xml_node
end
end
class IncludePath
attr_reader :path, :platform
def initialize( path, platform = nil)
@path = path
@platform = platform
end
def create_node()
xml_new = XML::Node.new("includepath")
xml_new["path"] = @path
xml_new
end
end
class IncludePaths
def initialize( paths )
@paths = paths
end
def create_node()
xml_node = XML::Node.new("includepaths")
@paths.each { |path|
xml_new = path.create_node()
xml_node << xml_new
}
xml_node
end
end
class ForceIncludes
def initialize( header_files )
@header_files = header_files
end
def create_node()
xml_node = XML::Node.new("forceincludes")
@header_files.each { |path|
xml_new = XML::Node.new("forceinclude")
xml_new["path"] = path
xml_node << xml_new
}
xml_node
end
end
end
end
end