Support installation of generated files
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.txt
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/module.xml
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-04-04 20:50:55 UTC (rev 14488)
@@ -614,60 +614,38 @@
 	// allow that to override use_pch if true
 }
 
-string
-MingwBackend::GetNonModuleInstallDirectories ( const string& installDirectory )
-{
-	string directories;
-	for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )
-	{
-		const InstallFile& installfile = *ProjectNode.installfiles[i];
-		string targetDirectory ( installDirectory + SSEP + installfile.base );
-		if ( directories.size () > 0 )
-			directories += " ";
-		directories += MingwModuleHandler::PassThruCacheDirectory (
-			FixupTargetFilename ( targetDirectory ),
-			true );
-	}
-	return directories;
-}
-
-string
-MingwBackend::GetInstallDirectories ( const string& installDirectory )
-{
-	return GetNonModuleInstallDirectories ( installDirectory );
-}
-
 void
-MingwBackend::GetNonModuleInstallFiles (
+MingwBackend::GetNonModuleInstallTargetFiles (
+	string installDirectory,
 	vector<string>& out ) const
 {
 	for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )
 	{
 		const InstallFile& installfile = *ProjectNode.installfiles[i];
-		out.push_back ( NormalizeFilename ( installfile.GetPath () ) );
+		string targetFilenameNoFixup = installDirectory + SSEP + installfile.base + SSEP + installfile.newname;
+		string targetFilename = MingwModuleHandler::PassThruCacheDirectory (
+			NormalizeFilename ( targetFilenameNoFixup ),
+			true );
+		out.push_back ( targetFilename );
 	}
 }
 
 void
-MingwBackend::GetInstallFiles (
-	vector<string>& out ) const
-{
-	GetNonModuleInstallFiles ( out );
-}
-
-void
-MingwBackend::GetNonModuleInstallTargetFiles (
+MingwBackend::GetModuleInstallTargetFiles (
 	string installDirectory,
 	vector<string>& out ) const
 {
-	for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )
+	for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
 	{
-		const InstallFile& installfile = *ProjectNode.installfiles[i];
-		string targetFilenameNoFixup = installDirectory + SSEP + installfile.base + SSEP + installfile.newname;
-		string targetFilename = MingwModuleHandler::PassThruCacheDirectory (
-			FixupTargetFilename ( targetFilenameNoFixup ),
-			true );
-		out.push_back ( targetFilename );
+		const Module& module = *ProjectNode.modules[i];
+		if ( module.installName.length () > 0 )
+		{
+			string targetFilenameNoFixup = installDirectory + SSEP + module.installBase + SSEP + module.installName;
+			string targetFilename = MingwModuleHandler::PassThruCacheDirectory (
+				NormalizeFilename ( targetFilenameNoFixup ),
+				true );
+			out.push_back ( targetFilename );
+		}
 	}
 }
 
@@ -678,36 +656,68 @@
 {
 	GetNonModuleInstallTargetFiles ( installDirectory,
 	                                 out );
+	GetModuleInstallTargetFiles ( installDirectory,
+	                              out );
 }
 
 void
-MingwBackend::OutputInstallfileTargets ( const string& installDirectory )
+MingwBackend::OutputInstallTarget ( const string& installDirectory,
+	                                const string& sourceFilename,
+	                                const string& targetFilename,
+	                                const string& targetDirectory )
 {
+	string normalizedTargetFilename = MingwModuleHandler::PassThruCacheDirectory (
+		NormalizeFilename ( installDirectory + SSEP + targetDirectory + SSEP + targetFilename ),
+		true );
+	string normalizedTargetDirectory = MingwModuleHandler::PassThruCacheDirectory (
+		NormalizeFilename ( installDirectory + SSEP + targetDirectory ),
+		true );
+	fprintf ( fMakefile,
+	          "%s: %s %s\n",
+	          normalizedTargetFilename.c_str (),
+	          sourceFilename.c_str (),
+	          normalizedTargetDirectory.c_str () );
+	fprintf ( fMakefile,
+	          "\t$(ECHO_CP)\n" );
+	fprintf ( fMakefile,
+	          "\t${cp} %s %s\n",
+	          sourceFilename.c_str (),
+	          normalizedTargetFilename.c_str () );
+}
+
+void
+MingwBackend::OutputNonModuleInstallTargets ( const string& installDirectory )
+{
 	for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )
 	{
 		const InstallFile& installfile = *ProjectNode.installfiles[i];
-		string targetFilenameNoFixup = installDirectory + SSEP + installfile.base + SSEP + installfile.newname;
-		string targetFilename = MingwModuleHandler::PassThruCacheDirectory (
-			FixupTargetFilename ( targetFilenameNoFixup ),
-			true );
-		string targetDirectory = MingwModuleHandler::PassThruCacheDirectory (
-			FixupTargetFilename ( installDirectory + SSEP + installfile.base ),
-			true );
-		fprintf ( fMakefile,
-		          "%s: %s %s\n",
-		          targetFilename.c_str (),
-		          installfile.GetPath ().c_str (),
-		          targetDirectory.c_str () );
-		fprintf ( fMakefile,
-		          "\t$(ECHO_CP)\n" );
-		fprintf ( fMakefile,
-		          "\t${cp} %s %s\n",
-		          installfile.GetPath ().c_str (),
-		          targetFilename.c_str () );
+		OutputInstallTarget ( installDirectory,
+	                          installfile.GetPath (),
+	                          installfile.newname,
+	                          installfile.base );
 	}
 }
 
 void
+MingwBackend::OutputModuleInstallTargets ( const string& installDirectory )
+{
+	for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
+	{
+		const Module& module = *ProjectNode.modules[i];
+		if ( module.installName.length () > 0 )
+		{
+			string sourceFilename = MingwModuleHandler::PassThruCacheDirectory (
+				NormalizeFilename ( module.GetPath () ),
+				true );
+			OutputInstallTarget ( installDirectory,
+		                          sourceFilename,
+		                          module.installName,
+		                          module.installBase );
+		}
+	}
+}
+
+void
 MingwBackend::GenerateInstallTarget ()
 {
 	string installDirectoryNoFixup = "reactos";
@@ -723,7 +733,8 @@
 	          "install: %s %s\n",
 	          installDirectory.c_str (),
 	          installTargetFiles.c_str () );
-	OutputInstallfileTargets ( installDirectoryNoFixup );
+	OutputNonModuleInstallTargets ( installDirectoryNoFixup );
+	OutputModuleInstallTargets ( installDirectoryNoFixup );
 	fprintf ( fMakefile,
 	          "\n" );
 }

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-04-04 20:50:55 UTC (rev 14488)
@@ -50,9 +50,16 @@
 	void GetInstallFiles ( std::vector<std::string>& out ) const;
 	void GetNonModuleInstallTargetFiles ( std::string installDirectory,
 	                                      std::vector<std::string>& out ) const;
+	void GetModuleInstallTargetFiles ( std::string installDirectory,
+	                                   std::vector<std::string>& out ) const;
 	void GetInstallTargetFiles ( std::string installDirectory,
 	                             std::vector<std::string>& out ) const;
-	void OutputInstallfileTargets ( const std::string& installDirectory );
+	void OutputInstallTarget ( const std::string& installDirectory,
+	                           const std::string& sourceFilename,
+	                           const std::string& targetFilename,
+	                           const std::string& targetDirectory );
+	void OutputNonModuleInstallTargets ( const std::string& installDirectory );
+	void OutputModuleInstallTargets ( const std::string& installDirectory );
 	void GenerateInstallTarget ();
 	FILE* fMakefile;
 	bool use_pch;

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-04-04 20:50:55 UTC (rev 14488)
@@ -97,7 +97,7 @@
 	}
 	return path;
 }
-	
+
 /*static*/ string
 MingwModuleHandler::PassThruCacheDirectory (
 	const string &file, bool out )

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-04-04 20:50:55 UTC (rev 14488)
@@ -133,7 +133,9 @@
 	  host (HostDefault)
 {
 	if ( node.name != "module" )
-		throw Exception ( "internal tool error: Module created with non-<module> node" );
+		throw InvalidOperationException ( __FILE__,
+		                                  __LINE__,
+		                                  "Module created with non-<module> node" );
 
 	path = FixSeparator ( modulePath );
 
@@ -202,6 +204,18 @@
 	att = moduleNode.GetAttribute ( "prefix", false );
 	if ( att != NULL )
 		prefix = att->value;
+
+	att = moduleNode.GetAttribute ( "installbase", false );
+	if ( att != NULL )
+		installBase = att->value;
+	else
+		installBase = "";
+
+	att = moduleNode.GetAttribute ( "installname", false );
+	if ( att != NULL )
+		installName = att->value;
+	else
+		installName = "";
 }
 
 Module::~Module ()

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-04-04 20:50:55 UTC (rev 14488)
@@ -171,6 +171,8 @@
 	bool cplusplus;
 	std::string prefix;
 	HostType host;
+	std::string installBase;
+	std::string installName;
 
 	Module ( const Project& project,
 	         const XMLElement& moduleNode,

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.txt
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.txt	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.txt	2005-04-04 20:50:55 UTC (rev 14488)
@@ -107,7 +107,7 @@
 There can be zero or more modules per xml build file.
 
 Syntax:
-	<module name="msvcrt" type="win32dll" extension=".dll" entrypoint="_DllMain@12" baseaddress="0x70000000" mangledsymbols="true">
+	<module name="msvcrt" type="win32dll" extension=".dll" entrypoint="_DllMain@12" baseaddress="0x70000000" mangledsymbols="true" installbase="system32" installname="msvcrt.dll" >
 		...
 	</module>
 
@@ -118,6 +118,8 @@
 	entrypoint - Entrypoint symbol of the generated file if such file is generated for the particular module type.
 	baseaddress - Base address of the generated file if such file is generated for the particular module type.
 	mangledsymbols - Controls wether or not to pass --kill-at to dlltool. If this attribute has the value false then --kill-at is passed to dlltool. If the value is true, then --kill-at is not passed to dlltool. If the generated file exports C++ classes then this need to be true.
+	installbase - Base directory of the generated file in the installation directory. This attribute is optional.
+	installname - Name of generated file in the installation directory. This attribute is optional, but if not specified, the generated file is not copied to the installation directory.
 
 Value:
 	None.

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/module.xml
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/module.xml	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/module.xml	2005-04-04 20:50:55 UTC (rev 14488)
@@ -7,7 +7,7 @@
 		</module>
 	</directory>
 	<directory name="dir2">
-		<module name="module2" type="kernelmodedll">
+		<module name="module2" type="kernelmodedll" installbase="reactos" installname="module2.ext">
 			<dependency>module1</dependency>
 			<library>module1</library>
 			<file>file3.c</file>

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp	2005-04-04 19:39:44 UTC (rev 14487)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp	2005-04-04 20:50:55 UTC (rev 14488)
@@ -10,6 +10,7 @@
 
 	Module& module1 = *project.modules[0];
 	IS_TRUE(module1.type == BuildTool);
+	
 	ARE_EQUAL(2, module1.non_if_data.files.size());
 	ARE_EQUAL("dir1" SSEP "file1.c", module1.non_if_data.files[0]->name);
 	ARE_EQUAL("dir1" SSEP "file2.c", module1.non_if_data.files[1]->name);
@@ -18,6 +19,9 @@
 
 	Module& module2 = *project.modules[1];
 	IS_TRUE(module2.type == KernelModeDLL);
+	ARE_EQUAL("reactos", module2.installBase);
+	ARE_EQUAL("module2.ext", module2.installName);
+
 	ARE_EQUAL(2, module2.non_if_data.files.size());
 	ARE_EQUAL("dir2" SSEP "file3.c", module2.non_if_data.files[0]->name);
 	ARE_EQUAL("dir2" SSEP "file4.c", module2.non_if_data.files[1]->name);