typedef set<string> set_string;\r
typedef map<string,Directory*> directory_map;\r
\r
+\r
+string\r
+v2s ( const string_list& v, int wrap_at )\r
+{\r
+ if ( !v.size() )\r
+ return "";\r
+ string s;\r
+ int wrap_count = 0;\r
+ for ( size_t i = 0; i < v.size(); i++ )\r
+ {\r
+ if ( !v[i].size() )\r
+ continue;\r
+ if ( wrap_at > 0 && wrap_count++ == wrap_at )\r
+ s += " \\\n\t\t";\r
+ else if ( s.size() )\r
+ s += " ";\r
+ s += v[i];\r
+ }\r
+ return s;\r
+}\r
+\r
+\r
class Directory\r
{\r
public:\r
directory_map subdirs;\r
Directory ( const string& name );\r
void Add ( const char* subdir );\r
- void GenerateTree ( const string& parent );\r
+ void GenerateTree ( const string& parent,\r
+ bool verbose );\r
private:\r
bool mkdir_p ( const char* path );\r
string ReplaceVariable ( string name,\r
}\r
\r
void\r
-Directory::GenerateTree ( const string& parent )\r
+Directory::GenerateTree ( const string& parent,\r
+ bool verbose )\r
{\r
string path;\r
\r
\r
path = parent + SSEP + name;\r
ResolveVariablesInPath ( buf, path );\r
- if ( CreateDirectory ( buf ) )\r
+ if ( CreateDirectory ( buf ) && verbose )\r
printf ( "Created %s\n", buf );\r
}\r
else\r
i != subdirs.end();\r
++i )\r
{\r
- i->second->GenerateTree ( path );\r
+ i->second->GenerateTree ( path, verbose );\r
}\r
}\r
\r
{\r
public:\r
MingwFactory() : Factory ( "mingw" ) {}\r
- Backend* operator() ( Project& project )\r
+ Backend* operator() ( Project& project, bool verbose )\r
{\r
- return new MingwBackend ( project );\r
+ return new MingwBackend ( project, verbose );\r
}\r
} factory;\r
\r
\r
-MingwBackend::MingwBackend ( Project& project )\r
- : Backend ( project ),\r
+MingwBackend::MingwBackend ( Project& project, bool verbose )\r
+ : Backend ( project, verbose ),\r
int_directories ( new Directory("$(INTERMEDIATE)") ),\r
out_directories ( new Directory("$(OUTPUT)") )\r
{\r
}\r
\r
void\r
-MingwBackend::Process ()\r
+MingwBackend::ProcessModules ()\r
{\r
- size_t i;\r
-\r
- DetectPCHSupport();\r
-\r
- CreateMakefile ();\r
- GenerateHeader ();\r
- GenerateGlobalVariables ();\r
- GenerateXmlBuildFilesMacro();\r
+ printf ( "Processing modules..." );\r
\r
vector<MingwModuleHandler*> v;\r
-\r
+ size_t i;\r
for ( i = 0; i < ProjectNode.modules.size (); i++ )\r
{\r
Module& module = *ProjectNode.modules[i];\r
delete v[i];\r
}\r
\r
+ printf ( "done\n" );\r
+}\r
+ \r
+void\r
+MingwBackend::Process ()\r
+{\r
+ DetectPipeSupport ();\r
+ DetectPCHSupport ();\r
+ CreateMakefile ();\r
+ GenerateHeader ();\r
+ GenerateGlobalVariables ();\r
+ GenerateXmlBuildFilesMacro ();\r
+ ProcessModules ();\r
+ GenerateInstallTarget ();\r
GenerateDirectories ();\r
CheckAutomaticDependencies ();\r
CloseMakefile ();\r
void\r
MingwBackend::CheckAutomaticDependencies ()\r
{\r
+ printf ( "Checking automatic dependencies..." );\r
AutomaticDependency automaticDependency ( ProjectNode );\r
automaticDependency.Process ();\r
- automaticDependency.CheckAutomaticDependencies ();\r
+ automaticDependency.CheckAutomaticDependencies ( verbose );\r
+ printf ( "done\n" );\r
}\r
\r
bool\r
void\r
MingwBackend::GenerateDirectories ()\r
{\r
- int_directories->GenerateTree ( "" );\r
- out_directories->GenerateTree ( "" );\r
+ printf ( "Creating directories..." );\r
+ int_directories->GenerateTree ( "", verbose );\r
+ out_directories->GenerateTree ( "", verbose );\r
+ printf ( "done\n" );\r
}\r
\r
string\r
}\r
\r
void\r
-MingwBackend::DetectPCHSupport()\r
+MingwBackend::DetectPipeSupport ()\r
+{\r
+ printf ( "Detecting compiler -pipe support..." );\r
+\r
+ string pipe_detection = "tools" SSEP "rbuild" SSEP "backend" SSEP "mingw" SSEP "pipe_detection.c";\r
+ string pipe_detectionObjectFilename = ReplaceExtension ( pipe_detection,\r
+ ".o" );\r
+ string command = ssprintf (\r
+ "gcc -pipe -c %s -o %s 2>%s",\r
+ pipe_detection.c_str (),\r
+ pipe_detectionObjectFilename.c_str (),\r
+ NUL );\r
+ int exitcode = system ( command.c_str () );\r
+ FILE* f = fopen ( pipe_detectionObjectFilename.c_str (), "rb" );\r
+ if ( f )\r
+ {\r
+ usePipe = (exitcode == 0);\r
+ fclose ( f );\r
+ unlink ( pipe_detectionObjectFilename.c_str () );\r
+ }\r
+ else\r
+ usePipe = false;\r
+\r
+ if ( usePipe )\r
+ printf ( "detected\n" );\r
+ else\r
+ printf ( "not detected\n" );\r
+\r
+ // TODO FIXME - eventually check for ROS_USE_PCH env var and\r
+ // allow that to override use_pch if true\r
+}\r
+\r
+void\r
+MingwBackend::DetectPCHSupport ()\r
{\r
-#ifdef WIN32\r
- string sNUL = "NUL";\r
-#else\r
- string sNUL = "/dev/null";\r
-#endif\r
+ printf ( "Detecting compiler pre-compiled header support..." );\r
+\r
string path = "tools" SSEP "rbuild" SSEP "backend" SSEP "mingw" SSEP "pch_detection.h";\r
- string cmd = ssprintf(\r
+ string cmd = ssprintf (\r
"gcc -c %s 2>%s",\r
path.c_str (),\r
- sNUL.c_str () );\r
- system ( cmd.c_str() );\r
+ NUL );\r
+ system ( cmd.c_str () );\r
path += ".gch";\r
\r
- FILE* f = fopen ( path.c_str(), "rb" );\r
+ FILE* f = fopen ( path.c_str (), "rb" );\r
if ( f )\r
{\r
use_pch = true;\r
- fclose(f);\r
- unlink ( path.c_str() );\r
+ fclose ( f );\r
+ unlink ( path.c_str () );\r
}\r
else\r
use_pch = false;\r
\r
+ if ( use_pch )\r
+ printf ( "detected\n" );\r
+ else\r
+ printf ( "not detected\n" );\r
+\r
// TODO FIXME - eventually check for ROS_USE_PCH env var and\r
// allow that to override use_pch if true\r
}\r
+\r
+string\r
+MingwBackend::GetNonModuleInstallDirectories ( const string& installDirectory )\r
+{\r
+ string directories;\r
+ for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )\r
+ {\r
+ const InstallFile& installfile = *ProjectNode.installfiles[i];\r
+ string targetDirectory ( installDirectory + SSEP + installfile.base );\r
+ if ( directories.size () > 0 )\r
+ directories += " ";\r
+ directories += MingwModuleHandler::PassThruCacheDirectory (\r
+ FixupTargetFilename ( targetDirectory ),\r
+ true );\r
+ }\r
+ return directories;\r
+}\r
+\r
+string\r
+MingwBackend::GetInstallDirectories ( const string& installDirectory )\r
+{\r
+ return GetNonModuleInstallDirectories ( installDirectory );\r
+}\r
+\r
+void\r
+MingwBackend::GetNonModuleInstallFiles (\r
+ vector<string>& out ) const\r
+{\r
+ for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )\r
+ {\r
+ const InstallFile& installfile = *ProjectNode.installfiles[i];\r
+ out.push_back ( NormalizeFilename ( installfile.GetPath () ) );\r
+ }\r
+}\r
+\r
+void\r
+MingwBackend::GetInstallFiles (\r
+ vector<string>& out ) const\r
+{\r
+ GetNonModuleInstallFiles ( out );\r
+}\r
+\r
+void\r
+MingwBackend::GetNonModuleInstallTargetFiles (\r
+ string installDirectory,\r
+ vector<string>& out ) const\r
+{\r
+ for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )\r
+ {\r
+ const InstallFile& installfile = *ProjectNode.installfiles[i];\r
+ string targetFilenameNoFixup = installDirectory + SSEP + installfile.base + SSEP + installfile.newname;\r
+ string targetFilename = MingwModuleHandler::PassThruCacheDirectory (\r
+ FixupTargetFilename ( targetFilenameNoFixup ),\r
+ true );\r
+ out.push_back ( targetFilename );\r
+ }\r
+}\r
+\r
+void\r
+MingwBackend::GetInstallTargetFiles (\r
+ string installDirectory,\r
+ vector<string>& out ) const\r
+{\r
+ GetNonModuleInstallTargetFiles ( installDirectory,\r
+ out );\r
+}\r
+\r
+void\r
+MingwBackend::OutputInstallfileTargets ( const string& installDirectory )\r
+{\r
+ for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )\r
+ {\r
+ const InstallFile& installfile = *ProjectNode.installfiles[i];\r
+ string targetFilenameNoFixup = installDirectory + SSEP + installfile.base + SSEP + installfile.newname;\r
+ string targetFilename = MingwModuleHandler::PassThruCacheDirectory (\r
+ FixupTargetFilename ( targetFilenameNoFixup ),\r
+ true );\r
+ string targetDirectory = MingwModuleHandler::PassThruCacheDirectory (\r
+ FixupTargetFilename ( installDirectory + SSEP + installfile.base ),\r
+ true );\r
+ fprintf ( fMakefile,\r
+ "%s: %s %s\n",\r
+ targetFilename.c_str (),\r
+ installfile.GetPath ().c_str (),\r
+ targetDirectory.c_str () );\r
+ fprintf ( fMakefile,\r
+ "\t$(ECHO_CP)\n" );\r
+ fprintf ( fMakefile,\r
+ "\t${cp} %s %s\n",\r
+ installfile.GetPath ().c_str (),\r
+ targetFilename.c_str () );\r
+ }\r
+}\r
+\r
+void\r
+MingwBackend::GenerateInstallTarget ()\r
+{\r
+ string installDirectoryNoFixup = "reactos";\r
+ string installDirectory = MingwModuleHandler::PassThruCacheDirectory (\r
+ NormalizeFilename ( installDirectoryNoFixup ),\r
+ true );\r
+ vector<string> vInstallTargetFiles;\r
+ GetInstallTargetFiles ( installDirectoryNoFixup,\r
+ vInstallTargetFiles );\r
+ string installTargetFiles = v2s ( vInstallTargetFiles, 5 );\r
+\r
+ fprintf ( fMakefile,\r
+ "install: %s %s\n",\r
+ installDirectory.c_str (),\r
+ installTargetFiles.c_str () );\r
+ OutputInstallfileTargets ( installDirectoryNoFixup );\r
+ fprintf ( fMakefile,\r
+ "\n" );\r
+}\r