1272 lines
36 KiB
Ruby
Executable File
1272 lines
36 KiB
Ruby
Executable File
#
|
|
# File:: vsshared.rb
|
|
#
|
|
# Pipeline::Shared class functions for parsing, loading and creating
|
|
# Visual Studio projects.
|
|
#
|
|
# Author:: Greg Smith <greg@rockstarnorth.com>
|
|
# Date:: 28 April 2010
|
|
#
|
|
#
|
|
require 'active_support/ordered_hash'
|
|
require 'pipeline/os/path'
|
|
require 'pipeline/os/file'
|
|
require 'pipeline/config/projects'
|
|
require 'pipeline/coding/projbuild/generators/vsutility.rb'
|
|
|
|
module Pipeline
|
|
|
|
module ProjBuild
|
|
|
|
class VSProjShared
|
|
|
|
@version = nil
|
|
CRLF = "
"
|
|
|
|
def VSProjShared.get_platform( token )
|
|
|
|
case token
|
|
when "x64"
|
|
return :win64
|
|
when "Xbox 360"
|
|
return :xbox360
|
|
when "Win32"
|
|
return :win32
|
|
when :ps3
|
|
return "PS3"
|
|
when :psp2
|
|
return "PSP2"
|
|
end
|
|
|
|
token.intern
|
|
end
|
|
|
|
def VSProjShared.get_platform_string( token )
|
|
|
|
case token
|
|
when :win64
|
|
return "x64"
|
|
when :xbox360
|
|
return "Xbox 360"
|
|
when :win32
|
|
return "Win32"
|
|
when :ps3
|
|
return "PS3"
|
|
when :psp2
|
|
return "PSP2"
|
|
end
|
|
|
|
token.to_s
|
|
end
|
|
|
|
def VSProjShared.parse_config_name( name )
|
|
|
|
|
|
#puts "parse_config_name #{name}"
|
|
|
|
tokens = name.strip.split("|")
|
|
|
|
platform = ""
|
|
target = ""
|
|
|
|
|
|
if tokens[0].index("SN PS3 SNC") == 0
|
|
return nil, nil if tokens[1] != "Win32"
|
|
|
|
platform = :ps3
|
|
target = tokens[0]
|
|
target.slice!(0..10)
|
|
elsif tokens[0].index("SN SNC") == 0
|
|
|
|
return nil, nil if tokens[1] != "Win32"
|
|
|
|
platform = :ps3
|
|
target = tokens[0]
|
|
target.slice!(0..6)
|
|
elsif tokens[0].index("SN PSP2 SNC") == 0 then
|
|
|
|
return nil, nil if tokens[1] != "Win32"
|
|
|
|
platform = :psp2
|
|
target = tokens[0]
|
|
target.slice!(0..11)
|
|
else
|
|
|
|
case tokens[1]
|
|
when "Win32"
|
|
platform = :win32
|
|
when "x64"
|
|
platform = :win64
|
|
when "Xbox 360"
|
|
platform = :xbox360
|
|
when "PS3"
|
|
platform = :ps3
|
|
when "PSP2"
|
|
platform = :psp2
|
|
end
|
|
|
|
target = tokens[0]
|
|
end
|
|
|
|
#puts "parse_config_name #{platform} #{target}"
|
|
|
|
return platform, target
|
|
end
|
|
|
|
def create_config_type( config )
|
|
|
|
return "1" if config == nil
|
|
return "1" if config.xml_data == nil
|
|
return "1" if config.xml_data.attributes["type"] == nil
|
|
|
|
type = config.xml_data.attributes["type"].intern
|
|
|
|
ret = case type
|
|
|
|
when :library
|
|
"4"
|
|
when :dll
|
|
"2"
|
|
when :exe
|
|
"1"
|
|
else "1"
|
|
end
|
|
|
|
ret
|
|
end
|
|
|
|
def create_character_set( config )
|
|
return "2" if config == nil
|
|
return "2" if config.xml_data == nil
|
|
return "2" if config.xml_data.attributes["character_set"] == nil
|
|
|
|
character_set = config.xml_data.attributes["character_set"].intern
|
|
|
|
ret = case character_set
|
|
|
|
when :notset
|
|
"0"
|
|
when :unicode
|
|
"1"
|
|
when :multibyte
|
|
"2"
|
|
else "2"
|
|
end
|
|
|
|
ret
|
|
end
|
|
|
|
def add_blank( xml_source, xml_node, node_name, name )
|
|
|
|
xml_source = xml_source.find_first("vc/#{name}")
|
|
|
|
xml_tool = XML::Node.new(node_name)
|
|
xml_tool_attributes = xml_tool.attributes
|
|
xml_tool_attributes["Name"] = name
|
|
|
|
clone_attributes(xml_source,xml_tool) if xml_source != nil
|
|
|
|
xml_node << xml_tool
|
|
end
|
|
|
|
def clone_attributes( xml_in, xml_out )
|
|
|
|
if ( xml_in.attributes? ) then
|
|
xml_in_attributes = xml_in.attributes
|
|
xml_in_attributes.each do |attribute|
|
|
|
|
if ( attribute.name != "Name" ) then
|
|
|
|
xml_out[attribute.name] = attribute.value
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_xml_path( xml_root, xml_path )
|
|
|
|
xml_current = xml_root
|
|
xml_tokens = xml_path.split("/")
|
|
|
|
xml_tokens.each { |xml_token|
|
|
|
|
vc_new = xml_root.find_first(xml_token)
|
|
|
|
if vc_new == nil then
|
|
|
|
vc_new = XML::Node.new(xml_token)
|
|
xml_current << vc_new
|
|
xml_current = vc_new
|
|
end
|
|
|
|
}
|
|
|
|
xml_current
|
|
end
|
|
|
|
def get_egrep_exe_path ( )
|
|
|
|
globals = Pipeline::Globals.instance()
|
|
exe_path = "#{globals.toolsbin}/coding/egrep.exe"
|
|
return exe_path
|
|
end
|
|
|
|
@@dir_tokens = ["%RAGE_DIR%"] #Tokens to be replaced by a relative path to the RAGE directory.
|
|
@@rage_dir_macro = "$(RAGE_DIR)"
|
|
|
|
# A post-write process to the project generation.
|
|
# Find and replace all tokens specified, such as $(RAGE_DIR).
|
|
def convert_paths( filename, path )
|
|
|
|
file = File.new(filename)
|
|
lines = file.readlines
|
|
file.close
|
|
|
|
#Re-write the project file with the replacement changes.
|
|
|
|
file = File.new(filename, 'w')
|
|
lines.each do |line|
|
|
|
|
@@dir_tokens.each do |token|
|
|
line.gsub!(token, @@rage_dir_macro)
|
|
line.gsub!(token.downcase, @@rage_dir_macro)
|
|
end
|
|
|
|
file.write(line)
|
|
end
|
|
file.close
|
|
|
|
return true
|
|
end
|
|
|
|
def VSProjShared.create_guid( guid_filename, p4 )
|
|
|
|
#If the GUID file does not exist, attempt to create it and add it to Perforce.
|
|
if File.exists?(guid_filename) == false
|
|
|
|
system("#{Globals::instance().toolsbin}\\coding\\uuidgen.exe -o#{guid_filename}")
|
|
full_path = File.expand_path(guid_filename)
|
|
|
|
if p4.nil? == false
|
|
p4.run_add(full_path)
|
|
end
|
|
|
|
#Verify that the guid file has been created. Otherwise, we have failed to create this project properly.
|
|
if File.exists?(guid_filename) == false
|
|
RageProjBuilderLoader.log.error("#{guid_filename} does not exist. Can not generate project file!")
|
|
return nil
|
|
end
|
|
end
|
|
guid = "#{File.readlines(guid_filename)[0]}"
|
|
guid.chomp! #Remove whitespace and newlines from the guid.
|
|
guid = "{#{guid.upcase}}"
|
|
|
|
return guid
|
|
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")
|
|
|
|
cpp_project_file = project_file + ".cpp"
|
|
found = false
|
|
specified_files.each do |file|
|
|
|
|
if file.eql?(cpp_project_file)
|
|
found = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if found == false
|
|
specified_files.insert(specified_files.size, cpp_project_file)
|
|
end
|
|
|
|
elsif File.exist?(project_file + ".c")
|
|
|
|
c_project_file = project_file + ".cpp"
|
|
found = false
|
|
specified_files.each do |file|
|
|
|
|
if file.eql?(c_project_file)
|
|
found = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if found == false
|
|
specified_files.insert(specified_files.size, c_project_file)
|
|
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|
|
|
|
|
found_file = File.basename(found_file)
|
|
file.write(found_file + "\n")
|
|
|
|
end
|
|
|
|
file.close
|
|
return project_definition_file_name
|
|
end
|
|
|
|
def copy_source_control_files(project_path, p4)
|
|
|
|
projbuild_root = Globals::instance().toolsconfig + "/projbuild"
|
|
src_vspscc_file = OS::Path::combine(projbuild_root, "template.vspscc")
|
|
src_vssscc_file = OS::Path::combine(projbuild_root, "template.vssscc")
|
|
|
|
vspscc_file = project_path + ".vspscc"
|
|
if File.exists?(vspscc_file) == false and File.exists?(src_vspscc_file) == true
|
|
OS::FileUtilsEx::copy_file(src_vspscc_file, vspscc_file)
|
|
end
|
|
|
|
vssscc_file = project_path + ".vssscc"
|
|
if File.exists?(vssscc_file) == false and File.exists?(src_vssscc_file) == true
|
|
OS::FileUtilsEx::copy_file(src_vssscc_file, vssscc_file)
|
|
end
|
|
|
|
#Add to source control.
|
|
if p4 != nil
|
|
edit_in_p4(p4, vspscc_file)
|
|
edit_in_p4(p4, vssscc_file)
|
|
end
|
|
end
|
|
|
|
|
|
def edit_in_p4(p4, file)
|
|
if p4.nil? == false and File.exist?(file)
|
|
|
|
if p4.connected?
|
|
print "#{file} was edited in p4"
|
|
p4.run_edit(file)
|
|
else
|
|
|
|
print "#{file} was not checked out because a connection to Perforce could not be established. Marking file as writable...\n"
|
|
FileUtils::chmod( 0666, file )
|
|
end
|
|
end
|
|
end
|
|
|
|
def add_in_p4(path)
|
|
FileUtils.cd(Pipeline::OS::Path.get_directory(path)) do
|
|
p4 = Perforce.new
|
|
if p4.connected?
|
|
p4.connect
|
|
if not p4.exists?( path )
|
|
p4.run_add( path )
|
|
p4.run_reopen( '-t', "+w", path )
|
|
end
|
|
else
|
|
print "#{path} was not checked out because a connection to Perforce could not be established.\n"
|
|
end
|
|
end
|
|
end
|
|
|
|
def revert_from_p4(p4, file)
|
|
if p4.nil? == false and File.exist?(file)
|
|
|
|
if p4.connected?
|
|
|
|
p4.run_revert(file)
|
|
else
|
|
|
|
print "#{@output_file} was not reverted out because a connection to Perforce could not be established.\n"
|
|
end
|
|
end
|
|
end
|
|
|
|
# added by request
|
|
def revert_unchanged(path)
|
|
# Revert if unchanged
|
|
fd = File.expand_path(path)
|
|
scm = Pipeline::Config::instance().scm
|
|
ragescm = Pipeline::Config::instance().ragescm
|
|
|
|
reverted = nil
|
|
FileUtils.cd(Pipeline::OS::Path.get_directory(fd)) do
|
|
if ( scm.exists?( fd ) ) then
|
|
reverted = scm.run_revert("-a", fd)
|
|
elsif ( ragescm.exists?( fd ) ) then
|
|
reverted = ragescm.run_revert("-a", fd)
|
|
end
|
|
end
|
|
|
|
@log.info("Reverted #{path} as it is unchanged.") if reverted and reverted.length > 0
|
|
end
|
|
|
|
@@version_names = nil
|
|
@@version_numbers = nil
|
|
def VSProjShared.create_version_names()
|
|
|
|
if @@version_names.nil?
|
|
@@version_names = Hash.new
|
|
@@version_names["vs2005"] = "_2005"
|
|
@@version_names["vs2008"] = "_2008"
|
|
@@version_names["vs2010"] = "_2010"
|
|
end
|
|
end
|
|
|
|
def VSProjShared.create_version_numbers()
|
|
|
|
if @@version_numbers.nil?
|
|
@@version_numbers = Hash.new
|
|
@@version_numbers["vs2005"] = "8.00"
|
|
@@version_numbers["vs2008"] = "9.00"
|
|
@@version_numbers["vs2010"] = "10.00"
|
|
end
|
|
end
|
|
|
|
def VSProjShared.get_project_suffix(output_format)
|
|
|
|
create_version_names()
|
|
|
|
@@vcproj_extension = ".vcproj"
|
|
|
|
output_file = @@version_names[output_format.to_s]
|
|
output_file += @@vcproj_extension
|
|
|
|
return output_file
|
|
end
|
|
|
|
def VSProjShared.get_project_suffix_2010(output_format)
|
|
|
|
create_version_names()
|
|
|
|
@@vcproj_extension = ".vcxproj"
|
|
|
|
output_file = @@version_names[output_format.to_s]
|
|
output_file += @@vcproj_extension
|
|
|
|
return output_file
|
|
end
|
|
|
|
|
|
def VSProjShared.get_version(output_format)
|
|
|
|
create_version_numbers()
|
|
|
|
output_version = @@version_numbers[output_format.to_s]
|
|
return output_version.to_s
|
|
end
|
|
end
|
|
|
|
class VSProjExporterShared < VSProjShared
|
|
|
|
def export( path, project, use_temporary_file = true)
|
|
|
|
@save_folder = File.expand_path(OS::Path::get_directory(path))
|
|
@log.info("Exporting #{project.name} to #{@save_folder}...")
|
|
|
|
temporary_filename = OS::Path.combine(Globals::instance().toolstemp,"temp.vcproj")
|
|
|
|
#HACK: For the 'ragegen' import process, all information is outputted to the temporary project file,
|
|
#not kept in memory to be regenerated. As a result, certain information is lost when re-saving
|
|
#the temporary file over the ragegen-created file.
|
|
if use_temporary_file == true
|
|
|
|
if ProjBuildData::instance().projects.values.size < 1
|
|
print "VSProjExporterShared :Generator did not create any projects to export!\n"
|
|
return false
|
|
end
|
|
|
|
@curr_project = project
|
|
@curr_project.rationalise
|
|
|
|
doc = XML::Document.new()
|
|
doc.root = export_project(@curr_project)
|
|
|
|
|
|
@log.info("Saving temporary file to #{temporary_filename}.")
|
|
doc.save(temporary_filename)
|
|
end
|
|
|
|
convert_paths(temporary_filename, path)
|
|
|
|
@log.info("Converting #{temporary_filename} to Visual Studio XML at #{path}.")
|
|
|
|
|
|
ret = VsXml::convert_to_vsxml(temporary_filename,path)
|
|
|
|
revert_unchanged(path)
|
|
|
|
return ret
|
|
end
|
|
|
|
protected
|
|
|
|
def create_tool_node()
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool["Name"] = "VCCustomBuildTool"
|
|
|
|
xml_tool
|
|
end
|
|
|
|
def internal_to_vs2005_custom_build( xml_tool, find_node )
|
|
|
|
find_node_attributes = find_node.attributes
|
|
xml_tool = create_tool_node() if xml_tool == nil
|
|
xml_tool_attributes = xml_tool.attributes
|
|
|
|
# DHM 2010/11/22 - this is nasty. Agreed, for some reason we
|
|
# get a TEXT node here; not sure why.
|
|
if ( 'element' == xml_tool.node_type_name ) then
|
|
|
|
if ( not find_node_attributes['CommandLine'].nil? ) then
|
|
xml_tool_attributes['CommandLine'] = find_node_attributes['CommandLine'].to_s
|
|
end
|
|
if ( not find_node_attributes['Outputs'].nil? ) then
|
|
xml_tool_attributes['Outputs'] = find_node_attributes['Outputs'].to_s
|
|
end
|
|
if ( not find_node_attributes['AdditionalDependencies'].nil? ) then
|
|
xml_tool_attributes['AdditionalDependencies'] = find_node_attributes['AdditionalDependencies'] .to_s
|
|
end
|
|
if ( not find_node_attributes['Description'].nil? ) then
|
|
xml_tool_attributes['Description'] = find_node_attributes['Description'].to_s
|
|
end
|
|
end
|
|
|
|
xml_tool
|
|
end
|
|
|
|
def create_file_config( filecfgs, platform_sym, target_sym, vs2010 )
|
|
|
|
xml_filecfg = filecfgs[platform_sym][target_sym]
|
|
|
|
if xml_filecfg == nil then
|
|
|
|
xml_filecfg = XML::Node.new("FileConfiguration")
|
|
xml_filecfg.attributes["Name"] = VSUtility.create_config_name(platform_sym,target_sym,vs2010)
|
|
xml_filecfg.attributes["ExcludedFromBuild"] = "false"
|
|
end
|
|
|
|
xml_filecfg
|
|
end
|
|
|
|
def export_files( filter, xml_node, path )
|
|
|
|
vs2010 = false
|
|
|
|
filter_config = Info::Config.merge(@curr_project.config,filter.config)
|
|
|
|
filter.files.each { |file|
|
|
|
|
@log.debug("export file #{file.path}")
|
|
|
|
file_config = Info::Config.merge(filter_config, file.config)
|
|
|
|
xml_file = XML::Node.new("File")
|
|
|
|
out_path = OS::Path.combine(path,file.path)
|
|
out_path = File.expand_path(out_path)
|
|
out_path = OS::Path.make_relative(out_path,@save_folder)
|
|
out_path = OS::Path.dos_format(out_path)
|
|
|
|
out_path = ".\\" + out_path if out_path.index("..") == 0
|
|
|
|
xml_file.attributes["RelativePath"] = out_path
|
|
|
|
#initialise custom data
|
|
fileconfigs = ActiveSupport::OrderedHash.new()
|
|
|
|
custom_builds = ActiveSupport::OrderedHash.new()
|
|
precomps = ActiveSupport::OrderedHash.new()
|
|
excluded_from_builds = ActiveSupport::OrderedHash.new()
|
|
|
|
@platforms.keys.each { |platform|
|
|
|
|
precomps[platform] = ActiveSupport::OrderedHash.new()
|
|
custom_builds[platform] = ActiveSupport::OrderedHash.new()
|
|
fileconfigs[platform] = ActiveSupport::OrderedHash.new()
|
|
excluded_from_builds[platform] = ActiveSupport::OrderedHash.new()
|
|
}
|
|
|
|
fileconfigs.keys.each { |platform_sym|
|
|
targets = fileconfigs[platform_sym] # DW - does nothing?!
|
|
|
|
@platforms[platform_sym].keys.each { |target|
|
|
|
|
precomps[platform_sym][target] = false
|
|
}
|
|
}
|
|
|
|
#global
|
|
|
|
if OS::Path.get_filename(file_config.root_node["precompiled_header_source"]) == OS::Path.get_filename(file.path) then
|
|
|
|
fileconfigs.keys.each { |platform_sym|
|
|
targets = fileconfigs[platform_sym] # DW - does nothing?!
|
|
|
|
@platforms[platform_sym].keys.each { |target|
|
|
|
|
precomps[platform_sym][target] = true
|
|
}
|
|
}
|
|
end
|
|
|
|
if (file.excluded_from_build)
|
|
fileconfigs.keys.each { |platform_sym|
|
|
targets = fileconfigs[platform_sym] # DW - does nothing?!
|
|
|
|
@platforms[platform_sym].keys.each { |target|
|
|
|
|
excluded_from_builds[platform_sym][target] = true
|
|
}
|
|
}
|
|
end
|
|
|
|
#per platform
|
|
|
|
@curr_project.platforms.each { |platform_sym,platform|
|
|
|
|
platform_config = Info::Config.merge(@curr_project.config,platform.config)
|
|
platform_file_config = Info::Config.merge(platform_config,file_config)
|
|
|
|
next if platform_file_config.root_node["precompiled_header_source"] == nil
|
|
|
|
if OS::Path.get_filename(platform_file_config.root_node["precompiled_header_source"]) == OS::Path.get_filename(file.path) then
|
|
|
|
@platforms[platform_sym].keys.each { |target|
|
|
|
|
precomps[platform_sym][target] = true
|
|
}
|
|
end
|
|
}
|
|
|
|
#per wildcard
|
|
|
|
#per wildcard, per platform
|
|
|
|
@platforms.keys.each { |platform|
|
|
|
|
next if @curr_project.platforms[platform].config == nil
|
|
files_nodes = @curr_project.platforms[platform].config.find("file")
|
|
|
|
next if files_nodes == nil
|
|
|
|
files_nodes.each { |file_node|
|
|
|
|
next if file_node["extension"] == nil
|
|
|
|
if OS::Path.get_extension(file.path) == file_node["extension"] then
|
|
|
|
find_node = file_node.find_first("custombuild")
|
|
|
|
@platforms[platform].keys.each { |target|
|
|
|
|
custom_builds[platform][target] = internal_to_vs2005_custom_build(custom_builds[platform][target],find_node)
|
|
}
|
|
end
|
|
}
|
|
files_nodes = nil
|
|
}
|
|
|
|
#per wildcard, per platform, per target
|
|
|
|
#per file
|
|
|
|
find_node = file_config.find_first("custombuild")
|
|
|
|
if find_node != nil
|
|
|
|
file.platforms.values.each { |platform|
|
|
|
|
if @platforms[platform.sym].nil? == false then
|
|
|
|
@platforms[platform.sym].keys.each { |target|
|
|
|
|
custom_builds[platform.sym][target] = internal_to_vs2005_custom_build(custom_builds[platform.sym][target],find_node)
|
|
}
|
|
end
|
|
}
|
|
end
|
|
|
|
#per file, per platform
|
|
|
|
file.platforms.values.each { |platform|
|
|
|
|
next if platform.config.nil?
|
|
|
|
find_node = platform.config.find_first("custombuild")
|
|
|
|
if find_node != nil then
|
|
|
|
if @platforms[platform.sym].nil? == false then
|
|
|
|
@platforms[platform.sym].keys.each { |target|
|
|
|
|
custom_builds[platform.sym][target] = internal_to_vs2005_custom_build(custom_builds[platform.sym][target],find_node)
|
|
}
|
|
end
|
|
end
|
|
}
|
|
|
|
#per file, per platform, per target
|
|
|
|
###########################################################################################################
|
|
###########################################################################################################
|
|
|
|
#create the output nodes...
|
|
|
|
|
|
#excluded from builds - added for unity builds
|
|
excluded_from_builds.each { |platform_sym,targets|
|
|
|
|
targets.each { |target_sym,excluded_from_build|
|
|
if (excluded_from_build)
|
|
xml_filecfg = fileconfigs[platform_sym][target_sym] = create_file_config(fileconfigs,platform_sym,target_sym,vs2010)
|
|
|
|
xml_filecfg.attributes["ExcludedFromBuild"] = "true"
|
|
end
|
|
}
|
|
}
|
|
|
|
#custom builds...
|
|
custom_builds.each { |platform_sym,targets|
|
|
|
|
targets.each { |target_sym,custom_build|
|
|
|
|
xml_filecfg = fileconfigs[platform_sym][target_sym] = create_file_config(fileconfigs,platform_sym,target_sym,vs2010)
|
|
|
|
xml_filecfg << custom_build
|
|
}
|
|
}
|
|
|
|
#precompiled header...
|
|
precomps.each { |platform_sym,targets|
|
|
|
|
targets.each { |target_sym,enabled|
|
|
|
|
if enabled then
|
|
|
|
xml_filecfg = fileconfigs[platform_sym][target_sym] = create_file_config(fileconfigs,platform_sym,target_sym,vs2010)
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool["Name"] = "VCCLCompilerTool"
|
|
|
|
if platform_sym == :xbox360 then
|
|
|
|
xml_tool["Name"] = "VCCLX360CompilerTool"
|
|
elsif platform_sym == :ps3 then
|
|
|
|
xml_tool["PrecompiledHeaderFile"] = "$(InputName).h.gch/$(ProjectName)_$(ConfigurationName).h.gch"
|
|
end
|
|
|
|
xml_tool["UsePrecompiledHeader"]="1"
|
|
|
|
xml_filecfg << xml_tool
|
|
end
|
|
}
|
|
}
|
|
|
|
fileconfigs.keys.each { |platform_sym|
|
|
targets = fileconfigs[platform_sym]
|
|
|
|
targets.each { |target_sym,fileconfig|
|
|
|
|
xml_file << fileconfig
|
|
}
|
|
}
|
|
|
|
xml_file << "\n"
|
|
xml_node << xml_file
|
|
}
|
|
|
|
filter.filters.each { |child_filter|
|
|
|
|
new_path = OS::Path.combine(path,child_filter.path)
|
|
|
|
#@log.info("child_filter.path #{child_filter.path} new_path #{new_path} child_filter.name #{child_filter.name}")
|
|
if (child_filter.name!="..//..//")
|
|
|
|
xml_filter = XML::Node.new("Filter")
|
|
xml_filter.attributes["Name"] = child_filter.name.split("/").last
|
|
xml_filter.attributes["Filter"] = " "
|
|
|
|
export_files(child_filter,xml_filter,new_path)
|
|
xml_node << xml_filter
|
|
end
|
|
}
|
|
end
|
|
|
|
def export_project( project )
|
|
|
|
vs2010 = false
|
|
|
|
config = project.config
|
|
|
|
@log.debug("exporting project")
|
|
|
|
xml_node = create_project_node(project)
|
|
platforms_out = ActiveSupport::OrderedHash.new()
|
|
|
|
project.platforms.keys.each { |key|
|
|
|
|
case key
|
|
when :ps3:
|
|
platforms_out["Win32"] = 1
|
|
when :psp2:
|
|
platforms_out["Win32"] = 1
|
|
when :win32:
|
|
platforms_out["Win32"] = 1
|
|
when :win64:
|
|
platforms_out["x64"] = 1
|
|
when :xbox360:
|
|
platforms_out["Xbox 360"] = 1
|
|
end
|
|
}
|
|
|
|
xml_platforms = XML::Node.new("Platforms")
|
|
|
|
platforms_out.keys.each { |platform_out|
|
|
|
|
xml_platform = XML::Node.new("Platform")
|
|
xml_platform.attributes["Name"] = platform_out
|
|
xml_platforms << xml_platform
|
|
}
|
|
|
|
xml_node << xml_platforms
|
|
xml_node << XML::Node.new("ToolFiles")
|
|
|
|
xml_configs = XML::Node.new("Configurations")
|
|
|
|
@platforms = ActiveSupport::OrderedHash.new()
|
|
|
|
project.platforms.each { |platform_sym,platform|
|
|
|
|
@log.debug("exporting platform #{platform_sym.to_s}")
|
|
|
|
platform_config = Info::Config.merge(config,platform.config)
|
|
|
|
@platforms[platform_sym] = ActiveSupport::OrderedHash.new()
|
|
|
|
platform.targets.each { |target_sym,target|
|
|
|
|
configuration_name = VSUtility.create_config_name(platform_sym,target_sym,vs2010)
|
|
|
|
#Determine the list of library dependencies.
|
|
additional_deps = VSUtility.get_library_dependencies( platform_config, target_sym )
|
|
|
|
target_config = Info::Config.merge(platform_config,target)
|
|
|
|
@platforms[platform_sym][target_sym] = 1
|
|
|
|
xml_config = XML::Node.new("Configuration")
|
|
xml_config.attributes["Name"] = VSUtility.create_config_name(platform_sym,target_sym,vs2010)
|
|
|
|
#An identifier for which version this object is compiled under.
|
|
#This is necessary as we are making conversions to new versions of Visual Studio, otherwise
|
|
#users will have issues with switching between versions and compiling right away.
|
|
#
|
|
version_tag = ""
|
|
version_tag = "_" + @version if @version != nil
|
|
|
|
if target_config.xml_data["output_path"] != nil
|
|
xml_config.attributes["OutputDirectory"] = target_config.xml_data["output_path"] + version_tag
|
|
else
|
|
xml_config.attributes["OutputDirectory"] = "$(ConfigurationName)_$(PlatformName)" + version_tag
|
|
end
|
|
|
|
xml_config.attributes["IntermediateDirectory"] = "$(OutDir)"
|
|
xml_config.attributes["ConfigurationType"] = create_config_type(target_config)
|
|
xml_config.attributes["InheritedPropertySheets"]="$(VCInstallDir)VCProjectDefaults\\UpgradeFromVC71.vsprops"
|
|
xml_config.attributes["CharacterSet"] = create_character_set(target_config)
|
|
|
|
platform_precompiled_header = nil
|
|
platform_precompiled_header = target_config.xml_data["precompiled_header"] if target_config.xml_data != nil
|
|
|
|
warning_level = nil
|
|
warning_level = target_config.xml_data["warning_level"] if target_config.xml_data != nil
|
|
|
|
warnings_as_errors = nil
|
|
warnings_as_errors = target_config.xml_data["warnings_as_errors"] if target_config.xml_data != nil
|
|
|
|
create_precompiled_header = false
|
|
create_precompiled_header = target_config.xml_data["create_precompiled_header"] == "true" if target_config.xml_data != nil
|
|
|
|
module_definition_file = nil
|
|
module_definition_file = target_config.xml_data["module_definition_file"] if target_config.xml_data != nil
|
|
|
|
xbox_title_id = nil
|
|
xbox_title_id = target_config.xml_data["xbox_title_id"] if target_config.xml_data != nil
|
|
|
|
xbox_spa_path = nil
|
|
xbox_spa_path = target_config.xml_data["xbox_spa_path"] if target_config.xml_data != nil
|
|
|
|
#library directories
|
|
lib_directories = Array.new()
|
|
# DHM 2010/11/22 NEXT LINE UNUSED?
|
|
#lib_node = target_config.xml_data.find("librarydirectories/librarydirectory")
|
|
libdirs = target_config.xml_data.find("librarydirectories/librarydirectory")
|
|
libdirs.each do |libdir|
|
|
lib_directories << libdir.attributes["path"]
|
|
end
|
|
libdirs = nil
|
|
|
|
#pre build event
|
|
cfg_prebuild = target_config.xml_data.find_first("prebuild")
|
|
|
|
if cfg_prebuild then
|
|
|
|
cmdlines = Array.new()
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool.attributes["Name"] = "VCPreBuildEventTool"
|
|
|
|
buildsteps = cfg_prebuild.find("buildstep")
|
|
buildsteps.each do |buildstep|
|
|
|
|
cmdlines << buildstep.attributes["cmd"]
|
|
end
|
|
|
|
xml_tool.attributes["CommandLine"] = cmdlines.join(CRLF)
|
|
xml_config << xml_tool
|
|
end
|
|
|
|
add_blank(target_config.xml_data, xml_config, "Tool", "VCPreBuildEventTool")
|
|
|
|
#pre link event
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool_attributes = xml_tool.attributes
|
|
xml_tool_attributes["Name"] = "VCPreLinkEventTool"
|
|
|
|
cfg_prelink = target_config.xml_data.find_first("prelink")
|
|
|
|
if ( cfg_prelink ) then
|
|
|
|
if ( cfg_prelink.attributes? ) then
|
|
|
|
cfg_prelink_attributes = cfg_prelink.attributes
|
|
xml_tool_attributes["Description"] = cfg_prelink_attributes["description"]
|
|
end
|
|
|
|
cmdlines = Array.new()
|
|
|
|
buildsteps = cfg_prelink.find("buildstep")
|
|
buildsteps.each { |buildstep|
|
|
|
|
cmdlines << buildstep.attributes["cmd"]
|
|
}
|
|
buildsteps = nil
|
|
|
|
xml_tool_attributes["CommandLine"] = cmdlines.join(CRLF)
|
|
end
|
|
|
|
xml_config << xml_tool
|
|
|
|
#library tool
|
|
|
|
root_node_attributes = target_config.root_node.attributes
|
|
if ( target_config.root_node.attributes? and
|
|
( not root_node_attributes["type"].nil? ) and
|
|
( :library == target_config.root_node.attributes["type"].intern ) ) then
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
|
|
xml_source = target_config.xml_data.find_first("vc/VCLibrarianTool")
|
|
if xml_source != nil
|
|
clone_attributes(xml_source, xml_tool)
|
|
end
|
|
|
|
xml_tool["Name"] = "VCLibrarianTool"
|
|
|
|
if xml_tool["AdditionalDependencies"] == nil
|
|
xml_tool["AdditionalDependencies"] = additional_deps.join(" ")
|
|
else
|
|
xml_tool["AdditionalDependencies"] += " " + additional_deps.join(" ") if additional_deps.size > 0
|
|
end
|
|
|
|
if xml_tool["AdditionalOptions"] == nil
|
|
if project.name.downcase.include?"ragemisc"
|
|
xml_tool["AdditionalOptions"] = "/ignore:4221 /ignore:4006"
|
|
else
|
|
xml_tool["AdditionalOptions"] = "/ignore:4221"
|
|
end
|
|
end
|
|
|
|
xml_tool["OutputFile"] = "$(OutDir)/$(ProjectName).lib"
|
|
|
|
xml_config << xml_tool
|
|
elsif
|
|
|
|
if platform_sym == :xbox360 then
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool["Name"] = "VCX360LinkerTool"
|
|
|
|
xml_source = target_config.xml_data.find_first("vc/#{xml_tool['Name']}")
|
|
clone_attributes(xml_source,xml_tool) if xml_source != nil
|
|
|
|
xml_tool["OutputFile"] = "$(RS_BUILDBRANCH)/#{project.name}_xenon_#{target_sym.to_s}.exe".downcase
|
|
|
|
xml_config << xml_tool
|
|
|
|
if xbox_title_id != nil or xbox_spa_path != nil
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool["Name"] = "VCX360ImageTool"
|
|
|
|
xml_source = target_config.xml_data.find_first("vc/#{xml_tool['Name']}")
|
|
clone_attributes(xml_source,xml_tool) if xml_source != nil
|
|
|
|
xml_tool["OutputFileName"] = "$(OutDir)\$(ProjectName)_$(OutDir).xex"
|
|
xml_tool["AdditionalSections"] = xbox_spa_path if xbox_spa_path != nil
|
|
xml_tool["TitleID"] = xbox_title_id if xbox_title_id != nil
|
|
xml_tool["ProjectDefaults"] = "XboxImageXexConfig"
|
|
xml_config << xml_tool
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool["Name"] = "VCX360DeploymentTool"
|
|
xml_tool["RemoteRoot"] = "xe:\\$(ProjectName)"
|
|
xml_tool["DeploymentFiles"] = "$(RemoteRoot)=$(ImagePath);$(RemoteRoot)=$(TEMP)\\rfs.dat;$(RemoteRoot)=$(TargetDir)$(TargetName).cmp"
|
|
xml_tool["DeploymentType"] = "0"
|
|
xml_config << xml_tool
|
|
|
|
else
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCX360ImageTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCX360DeploymentTool")
|
|
end
|
|
|
|
else
|
|
is_psp2_platform = false
|
|
is_ps3_platform = false
|
|
|
|
if (vs2010==true)
|
|
is_psp2_platform = platform_sym == :psp2
|
|
is_ps3_platform = platform_sym == :ps3
|
|
platform_sym
|
|
else
|
|
#PlayStation 3 configuratons are on the Win32. Assume a naming convention to give the correct extensions.
|
|
is_psp2_platform = configuration_name.index("SN PSP2") != nil
|
|
is_ps3_platform = configuration_name.index("SN PS3") != nil
|
|
end
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
xml_tool["Name"] = "VCLinkerTool"
|
|
|
|
xml_source = target_config.xml_data.find_first("vc/#{xml_tool['Name']}")
|
|
clone_attributes(xml_source,xml_tool) if xml_source != nil
|
|
|
|
#An available override in the project definition for the outputted file name.
|
|
#If an OutputFile attribute is available in the VCLinkerTool already, then
|
|
#we replace only the filename. If not, use the OutputFileName as a full path.
|
|
if target_config.xml_data.attributes["output_file_name"] != nil
|
|
|
|
if xml_tool["OutputFile"] != nil
|
|
|
|
output_file_name = target_config.xml_data.attributes["output_file_name"]
|
|
output_file_path = File.dirname(xml_tool["OutputFile"])
|
|
output_file_path = OS::Path.combine(output_file_path, output_file_name)
|
|
|
|
xml_tool["OutputFile"] = output_file_path
|
|
else
|
|
xml_tool["OutputFile"] = target_config.xml_data.attributes["output_file_name"]
|
|
end
|
|
else
|
|
|
|
if xml_tool["OutputFile"] == nil
|
|
|
|
if is_ps3_platform == true
|
|
xml_tool["OutputFile"] = "$(OutDir)\\$(ProjectName)_#{target_config.xml_data["output_path"]}_snc.ppu.self"
|
|
elsif is_psp2_platform == true
|
|
xml_tool["OutputFile"] = "$(OutDir)\\$(ProjectName)_#{target_config.xml_data["output_path"]}.self"
|
|
else
|
|
xml_tool["OutputFile"] = "$(OutDir)\\$(ProjectName)_#{target_config.xml_data["output_path"]}.exe"
|
|
end
|
|
end
|
|
|
|
#Otherwise, use the existing OutputFile name from the template.
|
|
end
|
|
|
|
if is_ps3_platform == true
|
|
|
|
#xml_tool["AdditionalOptions"] = "-strip-unused-data -strip-duplicates --notocrestore -Wl,--disable-warning=134 -Wl,--oformat=fself"
|
|
|
|
#NOTE: I'm uncertain
|
|
if xml_tool["AdditionalDependencies"] == nil
|
|
xml_tool["AdditionalDependencies"] = "-lm " + additional_deps.join(" ")
|
|
else
|
|
xml_tool["AdditionalDependencies"] += " " + additional_deps.join(" ") if additional_deps.size > 0
|
|
end
|
|
elsif is_psp2_platform == true
|
|
|
|
#NOTE: I'm uncertain
|
|
if xml_tool["AdditionalDependencies"] == nil
|
|
xml_tool["AdditionalDependencies"] = "-lm_stub " + additional_deps.join(" ")
|
|
else
|
|
xml_tool["AdditionalDependencies"] += " " + additional_deps.join(" ") if additional_deps.size > 0
|
|
end
|
|
else
|
|
|
|
if xml_tool["AdditionalDependencies"] == nil
|
|
xml_tool["AdditionalDependencies"] = additional_deps.join(" ")
|
|
else
|
|
xml_tool["AdditionalDependencies"] += " " + additional_deps.join(" ") if additional_deps.size > 0
|
|
end
|
|
|
|
if module_definition_file != nil
|
|
xml_tool["ModuleDefinitionFile"] = module_definition_file
|
|
end
|
|
end
|
|
|
|
if xml_tool["AdditionalLibraryDirectories"] == nil
|
|
xml_tool["AdditionalLibraryDirectories"] = lib_directories.join(";")
|
|
else
|
|
xml_tool["AdditionalLibraryDirectories"] += " " + lib_directories.join(";") if lib_directories.size > 0
|
|
end
|
|
|
|
xml_config << xml_tool
|
|
end
|
|
end
|
|
|
|
#compiler tool
|
|
|
|
xml_tool = XML::Node.new("Tool")
|
|
|
|
if platform_sym == :xbox360 then
|
|
|
|
xml_tool["Name"] = "VCCLX360CompilerTool"
|
|
else
|
|
|
|
xml_tool["Name"] = "VCCLCompilerTool"
|
|
end
|
|
|
|
xml_source = target_config.xml_data.find_first("vc/#{xml_tool['Name']}")
|
|
clone_attributes(xml_source,xml_tool) if xml_source != nil
|
|
|
|
xml_tool.attributes.get_attribute("PreprocessorDefinitions").remove! if xml_tool["PreprocessorDefinitions"]
|
|
xml_tool.attributes.get_attribute("ForcedIncludeFiles").remove! if xml_tool["ForcedIncludeFiles"]
|
|
xml_tool.attributes.get_attribute("AdditionalIncludeDirectories").remove! if xml_tool["AdditionalIncludeDirectories"]
|
|
|
|
if platform_precompiled_header == nil then
|
|
|
|
xml_tool["PrecompiledHeaderThrough"] = ""
|
|
xml_tool["UsePrecompiledHeader"] = "0"
|
|
else
|
|
|
|
xml_tool["PrecompiledHeaderThrough"] = platform_precompiled_header
|
|
|
|
if create_precompiled_header == true
|
|
xml_tool["UsePrecompiledHeader"] = "1"
|
|
else
|
|
xml_tool["UsePrecompiledHeader"] = "2"
|
|
end
|
|
end
|
|
|
|
if warning_level != nil
|
|
|
|
xml_tool["WarningLevel"] = warning_level
|
|
end
|
|
|
|
if warnings_as_errors != nil
|
|
|
|
if warnings_as_errors == "false" or warnings_as_errors == "0"
|
|
|
|
xml_tool["WarnAsError"] = "false"
|
|
else
|
|
|
|
xml_tool["WarnAsError"] = "true"
|
|
end
|
|
end
|
|
|
|
#defines
|
|
|
|
defines = Array.new()
|
|
|
|
define_nodes = target_config.xml_data.find("defines/define")
|
|
define_nodes.each do |define_node|
|
|
defines << define_node["value"]
|
|
end
|
|
define_nodes = nil
|
|
|
|
xml_tool.attributes["PreprocessorDefinitions"] = defines.join(";")
|
|
|
|
#force includes
|
|
forceincludes = VSUtility.get_force_includes(target_config)
|
|
xml_tool.attributes["ForcedIncludeFiles"] = forceincludes.join(";")
|
|
|
|
#include paths
|
|
inc_paths = Array.new()
|
|
include_nodes = target_config.xml_data.find("includepaths/includepath")
|
|
include_nodes.each do |include_path|
|
|
inc_paths << include_path.attributes["path"]
|
|
end
|
|
include_nodes = nil
|
|
|
|
xml_tool.attributes["AdditionalIncludeDirectories"] = inc_paths.join(";")
|
|
|
|
xml_config << xml_tool
|
|
|
|
#manifest
|
|
if platform_sym == :win64 then
|
|
xml_manifest = XML::Node.new("Tool")
|
|
xml_manifest["Name"] = "VCManifestTool"
|
|
xml_manifest["EmbedManifest"] = "false"
|
|
xml_config << xml_manifest
|
|
else
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCManifestTool")
|
|
end
|
|
|
|
#add these if they don't already exist!
|
|
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCCustomBuildTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCXMLDataGeneratorTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCWebServiceProxyGeneratorTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCMIDLTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCManagedResourceCompilerTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCResourceCompilerTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCPreLinkEventTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCALinkTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCXDCMakeTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCBscMakeTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCFxCopTool")
|
|
add_blank(target_config.xml_data,xml_config,"Tool","VCPostBuildEventTool")
|
|
|
|
xml_configs << xml_config
|
|
}
|
|
}
|
|
|
|
@log.debug("finished exporting platforms")
|
|
|
|
xml_node << xml_configs
|
|
xml_node << XML::Node.new("References")
|
|
xml_files = XML::Node.new("Files")
|
|
|
|
@log.debug("export files")
|
|
|
|
export_files(project,xml_files,project.path)
|
|
|
|
@log.debug("finished exporting")
|
|
|
|
xml_node << xml_files
|
|
|
|
xml_node
|
|
end
|
|
|
|
end
|
|
|
|
end #module ProjBuild
|
|
|
|
end #module Pipeline
|