11 typedef set
<string
> set_string
;
13 static class MingwFactory
: public Backend::Factory
16 MingwFactory() : Factory ( "mingw" ) {}
17 Backend
* operator() ( Project
& project
)
19 return new MingwBackend ( project
);
24 MingwBackend::MingwBackend ( Project
& project
)
30 MingwBackend::CreateDirectoryTargetIfNotYetCreated ( const string
& directory
)
32 directories
.insert ( directory
);
36 MingwBackend::GetDirectoryDependency ( const string
& directory
)
38 return directory
+ SSEP
"$(CREATED)";
43 MingwBackend::Process ()
49 GenerateGlobalVariables ();
51 GenerateInitTarget ();
52 GenerateXmlBuildFilesMacro();
53 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
55 Module
& module
= *ProjectNode
.modules
[i
];
56 ProcessModule ( module
);
58 GenerateDirectoryTargets ();
59 CheckAutomaticDependencies ();
64 MingwBackend::CreateMakefile ()
66 fMakefile
= fopen ( ProjectNode
.makefile
.c_str (), "w" );
68 throw AccessDeniedException ( ProjectNode
.makefile
);
69 MingwModuleHandler::SetMakefile ( fMakefile
);
70 MingwModuleHandler::SetUsePch ( use_pch
);
74 MingwBackend::CloseMakefile () const
81 MingwBackend::GenerateHeader () const
83 fprintf ( fMakefile
, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
87 MingwBackend::GenerateProjectCFlagsMacro ( const char* assignmentOperation
,
88 IfableData
& data
) const
95 assignmentOperation
);
96 for ( i
= 0; i
< data
.includes
.size(); i
++ )
101 data
.includes
[i
]->directory
.c_str() );
104 for ( i
= 0; i
< data
.defines
.size(); i
++ )
106 Define
& d
= *data
.defines
[i
];
111 if ( d
.value
.size() )
117 fprintf ( fMakefile
, "\n" );
121 MingwBackend::GenerateGlobalCFlagsAndProperties (
122 const char* assignmentOperation
,
123 IfableData
& data
) const
127 for ( i
= 0; i
< data
.properties
.size(); i
++ )
129 Property
& prop
= *data
.properties
[i
];
130 fprintf ( fMakefile
, "%s := %s\n",
132 prop
.value
.c_str() );
135 if ( data
.includes
.size() || data
.defines
.size() )
137 GenerateProjectCFlagsMacro ( assignmentOperation
,
141 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
143 If
& rIf
= *data
.ifs
[i
];
144 if ( rIf
.data
.defines
.size()
145 || rIf
.data
.includes
.size()
146 || rIf
.data
.ifs
.size() )
150 "ifeq (\"$(%s)\",\"%s\")\n",
151 rIf
.property
.c_str(),
153 GenerateGlobalCFlagsAndProperties (
164 MingwBackend::GenerateProjectLFLAGS () const
167 for ( size_t i
= 0; i
< ProjectNode
.linkerFlags
.size (); i
++ )
169 LinkerFlag
& linkerFlag
= *ProjectNode
.linkerFlags
[i
];
170 if ( lflags
.length () > 0 )
172 lflags
+= linkerFlag
.flag
;
178 MingwBackend::GenerateGlobalVariables () const
180 #define TOOL_PREFIX "$(Q)$(INTERMEDIATE)tools" SSEP
181 fprintf ( fMakefile
, "winebuild = " TOOL_PREFIX
"winebuild" SSEP
"winebuild" EXEPOSTFIX
"\n" );
182 fprintf ( fMakefile
, "bin2res = " TOOL_PREFIX
"bin2res" SSEP
"bin2res" EXEPOSTFIX
"\n" );
183 fprintf ( fMakefile
, "cabman = " TOOL_PREFIX
"cabman" SSEP
"cabman" EXEPOSTFIX
"\n" );
184 fprintf ( fMakefile
, "cdmake = " TOOL_PREFIX
"cdmake" SSEP
"cdmake" EXEPOSTFIX
"\n" );
185 fprintf ( fMakefile
, "rsym = " TOOL_PREFIX
"rsym" EXEPOSTFIX
"\n" );
186 fprintf ( fMakefile
, "wrc = " TOOL_PREFIX
"wrc" SSEP
"wrc" EXEPOSTFIX
"\n" );
187 fprintf ( fMakefile
, "\n" );
188 GenerateGlobalCFlagsAndProperties (
190 ProjectNode
.non_if_data
);
191 fprintf ( fMakefile
, "PROJECT_RCFLAGS = $(PROJECT_CFLAGS)\n" );
192 fprintf ( fMakefile
, "PROJECT_LFLAGS = %s\n",
193 GenerateProjectLFLAGS ().c_str () );
194 fprintf ( fMakefile
, "\n" );
198 MingwBackend::IncludeInAllTarget ( const Module
& module
) const
200 if ( module
.type
== ObjectLibrary
)
202 if ( module
.type
== BootSector
)
204 if ( module
.type
== Iso
)
210 MingwBackend::GenerateAllTarget () const
212 fprintf ( fMakefile
, "all:" );
214 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
216 Module
& module
= *ProjectNode
.modules
[i
];
217 if ( IncludeInAllTarget ( module
) )
219 if ( wrap_count
++ == 5 )
220 fprintf ( fMakefile
, " \\\n\t\t" ), wrap_count
= 0;
223 FixupTargetFilename ( module
.GetPath () ).c_str () );
226 fprintf ( fMakefile
, "\n\t\n\n" );
230 MingwBackend::GetBuildToolDependencies () const
233 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
235 Module
& module
= *ProjectNode
.modules
[i
];
236 if ( module
.type
== BuildTool
)
238 if ( dependencies
.length () > 0 )
240 dependencies
+= module
.GetDependencyPath ();
247 MingwBackend::GenerateInitTarget () const
251 GetBuildToolDependencies ().c_str () );
257 MingwBackend::GenerateXmlBuildFilesMacro() const
260 "XMLBUILDFILES = %s \\\n",
261 ProjectNode
.GetProjectFilename ().c_str () );
262 string xmlbuildFilenames
;
263 int numberOfExistingFiles
= 0;
264 for ( size_t i
= 0; i
< ProjectNode
.xmlbuildfiles
.size (); i
++ )
266 XMLInclude
& xmlbuildfile
= *ProjectNode
.xmlbuildfiles
[i
];
267 if ( !xmlbuildfile
.fileExists
)
269 numberOfExistingFiles
++;
270 if ( xmlbuildFilenames
.length () > 0 )
271 xmlbuildFilenames
+= " ";
272 xmlbuildFilenames
+= NormalizeFilename ( xmlbuildfile
.topIncludeFilename
);
273 if ( numberOfExistingFiles
% 5 == 4 || i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
277 xmlbuildFilenames
.c_str ());
278 if ( i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
287 xmlbuildFilenames
.c_str () );
289 xmlbuildFilenames
.resize ( 0 );
291 numberOfExistingFiles
++;
298 MingwBackend::CheckAutomaticDependencies ()
300 AutomaticDependency
automaticDependency ( ProjectNode
);
301 automaticDependency
.Process ();
302 automaticDependency
.CheckAutomaticDependencies ();
306 MingwBackend::ProcessModule ( Module
& module
)
308 MingwModuleHandler
* h
= MingwModuleHandler::InstanciateHandler (
309 module
.node
.location
,
312 MingwModuleHandler::string_list clean_files
;
313 if ( module
.host
== HostDefault
)
315 module
.host
= h
->DefaultHost();
316 assert ( module
.host
!= HostDefault
);
318 h
->Process ( module
, clean_files
);
319 h
->GenerateCleanTarget ( module
, clean_files
);
323 MingwBackend::IncludeDirectoryTarget ( const string
& directory
) const
325 if ( directory
== "$(INTERMEDIATE)tools")
332 MingwBackend::GenerateDirectoryTargets ()
334 if ( directories
.size () == 0 )
337 set_string::iterator i
;
338 for ( i
= directories
.begin ();
339 i
!= directories
.end ();
342 if ( IncludeDirectoryTarget ( *i
) )
346 GetDirectoryDependency ( *i
).c_str () );
353 directories
.clear ();
357 FixupTargetFilename ( const string
& targetFilename
)
359 return string("$(INTERMEDIATE)") + NormalizeFilename ( targetFilename
);
363 MingwBackend::DetectPCHSupport()
368 string sNUL
= "/dev/null";
370 string path
= "tools" SSEP
"rbuild" SSEP
"backend" SSEP
"mingw" SSEP
"pch_detection.h";
371 string cmd
= ssprintf(
375 system ( cmd
.c_str() );
378 FILE* f
= fopen ( path
.c_str(), "rb" );
383 unlink ( path
.c_str() );
388 // TODO FIXME - eventually check for ROS_USE_PCH env var and
389 // allow that to override use_pch if true