* Build cabman and zlib
[reactos.git] / reactos / tools / rbuild / backend / mingw / mingw.cpp
1
2 #include "../../pch.h"
3
4 #include "mingw.h"
5 #include <assert.h>
6
7 using std::string;
8 using std::vector;
9
10 static class MingwFactory : public Backend::Factory
11 {
12 public:
13 MingwFactory() : Factory ( "mingw" ) {}
14 Backend* operator() ( Project& project )
15 {
16 return new MingwBackend ( project );
17 }
18 } factory;
19
20
21 MingwBackend::MingwBackend ( Project& project )
22 : Backend ( project )
23 {
24 }
25
26 void
27 MingwBackend::Process ()
28 {
29 CreateMakefile ();
30 GenerateHeader ();
31 GenerateGlobalVariables ();
32 GenerateAllTarget ();
33 for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
34 {
35 Module& module = *ProjectNode.modules[i];
36 ProcessModule ( module );
37 }
38 CloseMakefile ();
39 }
40
41 void
42 MingwBackend::CreateMakefile ()
43 {
44 fMakefile = fopen ( ProjectNode.makefile.c_str (), "w" );
45 if ( !fMakefile )
46 throw AccessDeniedException ( ProjectNode.makefile );
47 MingwModuleHandler::SetMakefile ( fMakefile );
48 }
49
50 void
51 MingwBackend::CloseMakefile () const
52 {
53 if (fMakefile)
54 fclose ( fMakefile );
55 }
56
57 void
58 MingwBackend::GenerateHeader () const
59 {
60 fprintf ( fMakefile, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
61 }
62
63 void
64 MingwBackend::GenerateProjectCFlagsMacro ( const char* assignmentOperation,
65 const vector<Include*>& includes,
66 const vector<Define*>& defines ) const
67 {
68 size_t i;
69
70 fprintf (
71 fMakefile,
72 "PROJECT_CFLAGS %s",
73 assignmentOperation );
74 for ( i = 0; i < includes.size(); i++ )
75 {
76 fprintf (
77 fMakefile,
78 " -I%s",
79 includes[i]->directory.c_str() );
80 }
81
82 for ( i = 0; i < defines.size(); i++ )
83 {
84 Define& d = *defines[i];
85 fprintf (
86 fMakefile,
87 " -D%s",
88 d.name.c_str() );
89 if ( d.value.size() )
90 fprintf (
91 fMakefile,
92 "=%s",
93 d.value.c_str() );
94 }
95 fprintf ( fMakefile, "\n" );
96 }
97
98 void
99 MingwBackend::GenerateGlobalCFlagsAndProperties (
100 const char* assignmentOperation,
101 const vector<Property*>& properties,
102 const vector<Include*>& includes,
103 const vector<Define*>& defines,
104 const vector<If*>& ifs ) const
105 {
106 size_t i;
107
108 for ( i = 0; i < properties.size(); i++ )
109 {
110 Property& prop = *properties[i];
111 fprintf ( fMakefile, "%s := %s\n",
112 prop.name.c_str(),
113 prop.value.c_str() );
114 }
115
116 if ( includes.size() || defines.size() )
117 {
118 GenerateProjectCFlagsMacro ( assignmentOperation,
119 includes,
120 defines );
121 }
122
123 for ( i = 0; i < ifs.size(); i++ )
124 {
125 If& rIf = *ifs[i];
126 if ( rIf.defines.size() || rIf.includes.size() || rIf.ifs.size() )
127 {
128 fprintf (
129 fMakefile,
130 "ifeq (\"$(%s)\",\"%s\")\n",
131 rIf.property.c_str(),
132 rIf.value.c_str() );
133 GenerateGlobalCFlagsAndProperties (
134 "+=",
135 rIf.properties,
136 rIf.includes,
137 rIf.defines,
138 rIf.ifs );
139 fprintf (
140 fMakefile,
141 "endif\n\n" );
142 }
143 }
144 }
145
146 string
147 MingwBackend::GenerateProjectLFLAGS () const
148 {
149 string lflags;
150 for ( size_t i = 0; i < ProjectNode.linkerFlags.size (); i++ )
151 {
152 LinkerFlag& linkerFlag = *ProjectNode.linkerFlags[i];
153 if ( lflags.length () > 0 )
154 lflags += " ";
155 lflags += linkerFlag.flag;
156 }
157 return lflags;
158 }
159
160 void
161 MingwBackend::GenerateGlobalVariables () const
162 {
163 #ifdef WIN32
164 fprintf ( fMakefile, "host_gcc = gcc\n" );
165 fprintf ( fMakefile, "host_gpp = g++\n" );
166 fprintf ( fMakefile, "host_ld = ld\n" );
167 fprintf ( fMakefile, "host_ar = ar\n" );
168 fprintf ( fMakefile, "host_objcopy = objcopy\n" );
169 fprintf ( fMakefile, "rm = del /f /q\n" );
170 fprintf ( fMakefile, "gcc = gcc\n" );
171 fprintf ( fMakefile, "gpp = g++\n" );
172 fprintf ( fMakefile, "ld = ld\n" );
173 fprintf ( fMakefile, "ar = ar\n" );
174 fprintf ( fMakefile, "objcopy = objcopy\n" );
175 fprintf ( fMakefile, "dlltool = dlltool\n" );
176 fprintf ( fMakefile, "windres = windres\n" );
177 #else
178 fprintf ( fMakefile, "host_gcc = gcc\n" );
179 fprintf ( fMakefile, "host_gpp = g++\n" );
180 fprintf ( fMakefile, "host_ld = ld\n" );
181 fprintf ( fMakefile, "host_ar = ar\n" );
182 fprintf ( fMakefile, "host_objcopy = objcopy\n" );
183 fprintf ( fMakefile, "rm = rm -f\n" );
184 fprintf ( fMakefile, "gcc = mingw32-gcc\n" );
185 fprintf ( fMakefile, "gpp = mingw32-g++\n" );
186 fprintf ( fMakefile, "ld = mingw32-ld\n" );
187 fprintf ( fMakefile, "ar = mingw32-ar\n" );
188 fprintf ( fMakefile, "objcopy = mingw32-objcopy\n" );
189 fprintf ( fMakefile, "dlltool = mingw32-dlltool\n" );
190 fprintf ( fMakefile, "windres = mingw32-windres\n" );
191 #endif
192 fprintf ( fMakefile, "mkdir = tools%crmkdir\n", CSEP );
193 fprintf ( fMakefile, "NUL=NUL\n" );
194 fprintf ( fMakefile, "winebuild = tools" SSEP "winebuild" SSEP "winebuild\n" );
195 fprintf ( fMakefile, "bin2res = tools" SSEP "bin2res" SSEP "bin2res\n" );
196 fprintf ( fMakefile, "\n" );
197 GenerateGlobalCFlagsAndProperties (
198 "=",
199 ProjectNode.properties,
200 ProjectNode.includes,
201 ProjectNode.defines,
202 ProjectNode.ifs );
203 fprintf ( fMakefile, "PROJECT_RCFLAGS = $(PROJECT_CFLAGS)\n" );
204 fprintf ( fMakefile, "PROJECT_LFLAGS = %s\n",
205 GenerateProjectLFLAGS ().c_str () );
206 fprintf ( fMakefile, "\n" );
207
208 fprintf ( fMakefile, ".PHONY: clean\n\n" );
209 }
210
211 bool
212 MingwBackend::IncludeInAllTarget ( const Module& module ) const
213 {
214 if ( module.type == ObjectLibrary )
215 return false;
216 if ( module.type == Iso )
217 return false;
218 return true;
219 }
220
221 void
222 MingwBackend::GenerateAllTarget () const
223 {
224 fprintf ( fMakefile, "all:" );
225 for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
226 {
227 Module& module = *ProjectNode.modules[i];
228 if ( IncludeInAllTarget ( module ) )
229 {
230 fprintf ( fMakefile,
231 " %s",
232 FixupTargetFilename ( module.GetPath () ).c_str () );
233 }
234 }
235 fprintf ( fMakefile, "\n\t\n\n" );
236 }
237
238 void
239 MingwBackend::ProcessModule ( Module& module ) const
240 {
241 MingwModuleHandler* h = MingwModuleHandler::LookupHandler (
242 module.node.location,
243 module.type );
244 h->Process ( module );
245 h->GenerateDirectoryTargets ();
246 }
247
248 string
249 FixupTargetFilename ( const string& targetFilename )
250 {
251 return string("$(ROS_INTERMEDIATE)") + NormalizeFilename ( targetFilename );
252 }