#include "../../pch.h"\r
\r
#include "mingw.h"\r
+#include <assert.h>\r
\r
using std::string;\r
using std::vector;\r
void\r
MingwBackend::Process ()\r
{\r
+ DetectPCHSupport();\r
+\r
CreateMakefile ();\r
GenerateHeader ();\r
GenerateGlobalVariables ();\r
GenerateAllTarget ();\r
+ GenerateInitTarget ();\r
+ GenerateXmlBuildFilesMacro();\r
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )\r
{\r
Module& module = *ProjectNode.modules[i];\r
ProcessModule ( module );\r
}\r
+ CheckAutomaticDependencies ();\r
CloseMakefile ();\r
}\r
\r
}\r
\r
void\r
-MingwBackend::CloseMakefile ()\r
+MingwBackend::CloseMakefile () const\r
{\r
if (fMakefile)\r
fclose ( fMakefile );\r
}\r
\r
void\r
-MingwBackend::GenerateHeader ()\r
+MingwBackend::GenerateHeader () const\r
{\r
fprintf ( fMakefile, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );\r
}\r
\r
-string\r
-MingwBackend::GenerateProjectCFLAGS ()\r
+void\r
+MingwBackend::GenerateProjectCFlagsMacro ( const char* assignmentOperation,\r
+ const vector<Include*>& includes,\r
+ const vector<Define*>& defines ) const\r
{\r
size_t i;\r
- string clags;\r
- for ( i = 0; i < ProjectNode.includes.size (); i++ )\r
+\r
+ fprintf (\r
+ fMakefile,\r
+ "PROJECT_CFLAGS %s",\r
+ assignmentOperation );\r
+ for ( i = 0; i < includes.size(); i++ )\r
{\r
- Include& include = *ProjectNode.includes[i];\r
- if (clags.length () > 0)\r
- clags += " ";\r
- clags += "-I" + include.directory;\r
+ fprintf (\r
+ fMakefile,\r
+ " -I%s",\r
+ includes[i]->directory.c_str() );\r
}\r
- \r
- for ( i = 0; i < ProjectNode.defines.size (); i++ )\r
+\r
+ for ( i = 0; i < defines.size(); i++ )\r
{\r
- Define& define = *ProjectNode.defines[i];\r
- if ( clags.length () > 0 )\r
- clags += " ";\r
- clags += "-D" + define.name;\r
- if ( define.value.size() > 0 )\r
- {\r
- clags += "=";\r
- clags += define.value;\r
- }\r
+ Define& d = *defines[i];\r
+ fprintf (\r
+ fMakefile,\r
+ " -D%s",\r
+ d.name.c_str() );\r
+ if ( d.value.size() )\r
+ fprintf (\r
+ fMakefile,\r
+ "=%s",\r
+ d.value.c_str() );\r
}\r
- return clags;\r
+ fprintf ( fMakefile, "\n" );\r
}\r
\r
void\r
-MingwBackend::GenerateGlobalVariables ()\r
+MingwBackend::GenerateGlobalCFlagsAndProperties (\r
+ const char* assignmentOperation,\r
+ const vector<Property*>& properties,\r
+ const vector<Include*>& includes,\r
+ const vector<Define*>& defines,\r
+ const vector<If*>& ifs ) const\r
{\r
size_t i;\r
\r
- fprintf ( fMakefile, "host_gcc = gcc\n" );\r
- fprintf ( fMakefile, "host_ar = ar\n" );\r
- fprintf ( fMakefile, "host_ld = ld\n" );\r
- fprintf ( fMakefile, "rm = del /f /q\n" );\r
- fprintf ( fMakefile, "gcc = gcc\n" );\r
- fprintf ( fMakefile, "ld = ld\n" );\r
- fprintf ( fMakefile, "ar = ar\n" );\r
- fprintf ( fMakefile, "dlltool = dlltool\n" );\r
- fprintf ( fMakefile, "PROJECT_CFLAGS = %s\n", GenerateProjectCFLAGS ().c_str () );\r
- for ( i = 0; i < ProjectNode.properties.size(); i++ )\r
+ for ( i = 0; i < properties.size(); i++ )\r
{\r
- Property& prop = *ProjectNode.properties[i];\r
+ Property& prop = *properties[i];\r
fprintf ( fMakefile, "%s := %s\n",\r
prop.name.c_str(),\r
prop.value.c_str() );\r
}\r
+\r
+ if ( includes.size() || defines.size() )\r
+ {\r
+ GenerateProjectCFlagsMacro ( assignmentOperation,\r
+ includes,\r
+ defines );\r
+ }\r
+\r
+ for ( i = 0; i < ifs.size(); i++ )\r
+ {\r
+ If& rIf = *ifs[i];\r
+ if ( rIf.defines.size() || rIf.includes.size() || rIf.ifs.size() )\r
+ {\r
+ fprintf (\r
+ fMakefile,\r
+ "ifeq (\"$(%s)\",\"%s\")\n",\r
+ rIf.property.c_str(),\r
+ rIf.value.c_str() );\r
+ GenerateGlobalCFlagsAndProperties (\r
+ "+=",\r
+ rIf.properties,\r
+ rIf.includes,\r
+ rIf.defines,\r
+ rIf.ifs );\r
+ fprintf (\r
+ fMakefile,\r
+ "endif\n\n" );\r
+ }\r
+ }\r
+}\r
+\r
+string\r
+MingwBackend::GenerateProjectLFLAGS () const\r
+{\r
+ string lflags;\r
+ for ( size_t i = 0; i < ProjectNode.linkerFlags.size (); i++ )\r
+ {\r
+ LinkerFlag& linkerFlag = *ProjectNode.linkerFlags[i];\r
+ if ( lflags.length () > 0 )\r
+ lflags += " ";\r
+ lflags += linkerFlag.flag;\r
+ }\r
+ return lflags;\r
+}\r
+\r
+void\r
+MingwBackend::GenerateGlobalVariables () const\r
+{\r
+ fprintf ( fMakefile, "mkdir = tools" SSEP "rmkdir" EXEPOSTFIX "\n" );\r
+ fprintf ( fMakefile, "winebuild = tools" SSEP "winebuild" SSEP "winebuild" EXEPOSTFIX "\n" );\r
+ fprintf ( fMakefile, "bin2res = tools" SSEP "bin2res" SSEP "bin2res" EXEPOSTFIX "\n" );\r
+ fprintf ( fMakefile, "cabman = tools" SSEP "cabman" SSEP "cabman" EXEPOSTFIX "\n" );\r
+ fprintf ( fMakefile, "cdmake = tools" SSEP "cdmake" SSEP "cdmake" EXEPOSTFIX "\n" );\r
+ fprintf ( fMakefile, "rsym = tools" SSEP "rsym" EXEPOSTFIX "\n" );\r
+ fprintf ( fMakefile, "wrc = tools" SSEP "wrc" SSEP "wrc" EXEPOSTFIX "\n" );\r
fprintf ( fMakefile, "\n" );\r
+ GenerateGlobalCFlagsAndProperties (\r
+ "=",\r
+ ProjectNode.properties,\r
+ ProjectNode.includes,\r
+ ProjectNode.defines,\r
+ ProjectNode.ifs );\r
+ fprintf ( fMakefile, "PROJECT_RCFLAGS = $(PROJECT_CFLAGS)\n" );\r
+ fprintf ( fMakefile, "PROJECT_LFLAGS = %s\n",\r
+ GenerateProjectLFLAGS ().c_str () );\r
+ fprintf ( fMakefile, "\n" );\r
+}\r
+\r
+bool\r
+MingwBackend::IncludeInAllTarget ( const Module& module ) const\r
+{\r
+ if ( module.type == ObjectLibrary )\r
+ return false;\r
+ if ( module.type == BootSector )\r
+ return false;\r
+ if ( module.type == Iso )\r
+ return false;\r
+ return true;\r
}\r
\r
void\r
-MingwBackend::GenerateAllTarget ()\r
+MingwBackend::GenerateAllTarget () const\r
{\r
fprintf ( fMakefile, "all:" );\r
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )\r
{\r
Module& module = *ProjectNode.modules[i];\r
- fprintf ( fMakefile,\r
- " %s",\r
- FixupTargetFilename ( module.GetPath () ).c_str () );\r
+ if ( IncludeInAllTarget ( module ) )\r
+ {\r
+ fprintf ( fMakefile,\r
+ " %s",\r
+ FixupTargetFilename ( module.GetPath () ).c_str () );\r
+ }\r
}\r
fprintf ( fMakefile, "\n\t\n\n" );\r
}\r
\r
+string\r
+MingwBackend::GetBuildToolDependencies () const\r
+{\r
+ string dependencies;\r
+ for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )\r
+ {\r
+ Module& module = *ProjectNode.modules[i];\r
+ if ( module.type == BuildTool )\r
+ {\r
+ if ( dependencies.length () > 0 )\r
+ dependencies += " ";\r
+ dependencies += module.GetDependencyPath ();\r
+ }\r
+ }\r
+ return dependencies;\r
+}\r
+\r
void\r
-MingwBackend::ProcessModule ( Module& module )\r
+MingwBackend::GenerateInitTarget () const\r
+{\r
+ fprintf ( fMakefile,\r
+ "init:");\r
+ fprintf ( fMakefile,\r
+ " $(ROS_INTERMEDIATE)." SSEP "tools" );\r
+ fprintf ( fMakefile,\r
+ " %s",\r
+ GetBuildToolDependencies ().c_str () );\r
+ fprintf ( fMakefile,\r
+ " %s",\r
+ "include" SSEP "reactos" SSEP "buildno.h" );\r
+ fprintf ( fMakefile,\r
+ "\n\t\n\n" );\r
+\r
+ fprintf ( fMakefile,\r
+ "$(ROS_INTERMEDIATE)." SSEP "tools:\n" );\r
+ fprintf ( fMakefile,\r
+ "ifneq ($(ROS_INTERMEDIATE),)\n" );\r
+ fprintf ( fMakefile,\r
+ "\t${nmkdir} $(ROS_INTERMEDIATE)\n" );\r
+ fprintf ( fMakefile,\r
+ "endif\n" );\r
+ fprintf ( fMakefile,\r
+ "\t${nmkdir} $(ROS_INTERMEDIATE)." SSEP "tools\n" );\r
+ fprintf ( fMakefile,\r
+ "\n" );\r
+}\r
+\r
+void\r
+MingwBackend::GenerateXmlBuildFilesMacro() const\r
+{\r
+ fprintf ( fMakefile,\r
+ "XMLBUILDFILES = %s \\\n",\r
+ ProjectNode.GetProjectFilename ().c_str () );\r
+ string xmlbuildFilenames;\r
+ int numberOfExistingFiles = 0;\r
+ for ( size_t i = 0; i < ProjectNode.xmlbuildfiles.size (); i++ )\r
+ {\r
+ XMLInclude& xmlbuildfile = *ProjectNode.xmlbuildfiles[i];\r
+ if ( !xmlbuildfile.fileExists )\r
+ continue;\r
+ numberOfExistingFiles++;\r
+ if ( xmlbuildFilenames.length () > 0 )\r
+ xmlbuildFilenames += " ";\r
+ xmlbuildFilenames += NormalizeFilename ( xmlbuildfile.topIncludeFilename );\r
+ if ( numberOfExistingFiles % 5 == 4 || i == ProjectNode.xmlbuildfiles.size () - 1 )\r
+ {\r
+ fprintf ( fMakefile,\r
+ "\t%s",\r
+ xmlbuildFilenames.c_str ());\r
+ if ( i == ProjectNode.xmlbuildfiles.size () - 1 )\r
+ {\r
+ fprintf ( fMakefile,\r
+ "\n" );\r
+ }\r
+ else\r
+ {\r
+ fprintf ( fMakefile,\r
+ " \\\n",\r
+ xmlbuildFilenames.c_str () );\r
+ }\r
+ xmlbuildFilenames.resize ( 0 );\r
+ }\r
+ numberOfExistingFiles++;\r
+ }\r
+ fprintf ( fMakefile,\r
+ "\n" );\r
+}\r
+\r
+void\r
+MingwBackend::CheckAutomaticDependencies ()\r
+{\r
+ AutomaticDependency automaticDependency ( ProjectNode );\r
+ automaticDependency.Process ();\r
+ automaticDependency.CheckAutomaticDependencies ();\r
+}\r
+\r
+void\r
+MingwBackend::ProcessModule ( Module& module ) const\r
{\r
MingwModuleHandler* h = MingwModuleHandler::LookupHandler (\r
module.node.location,\r
module.type );\r
h->Process ( module );\r
+ h->GenerateDirectoryTargets ();\r
}\r
\r
string\r
FixupTargetFilename ( const string& targetFilename )\r
{\r
- return string("$(ROS_INTERMEDIATE)") + targetFilename;\r
+ return string("$(ROS_INTERMEDIATE)") + NormalizeFilename ( targetFilename );\r
+}\r
+\r
+void\r
+MingwBackend::DetectPCHSupport()\r
+{\r
+ string path = "tools" SSEP "rbuild" SSEP "backend" SSEP "mingw" SSEP "pch_detection.h";\r
+ system ( ssprintf("gcc -c %s", path.c_str()).c_str() );\r
+ path += ".gch";\r
+\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
+ }\r
+ else\r
+ use_pch = false;\r
+\r
+ // TODO FIXME - eventually check for ROS_USE_PCH env var and\r
+ // allow that to override use_pch if true\r
}\r