Fix copy/paste error.
[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 ()
52 {
53 if (fMakefile)
54 fclose ( fMakefile );
55 }
56
57 void
58 MingwBackend::GenerateHeader ()
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 )
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 ()
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 ()
162 {
163 #ifdef WIN32
164 fprintf ( fMakefile, "host_gcc = gcc\n" );
165 fprintf ( fMakefile, "host_ar = ar\n" );
166 fprintf ( fMakefile, "host_ld = ld\n" );
167 fprintf ( fMakefile, "rm = del /f /q\n" );
168 fprintf ( fMakefile, "gcc = gcc\n" );
169 fprintf ( fMakefile, "ld = ld\n" );
170 fprintf ( fMakefile, "ar = ar\n" );
171 fprintf ( fMakefile, "dlltool = dlltool\n" );
172 fprintf ( fMakefile, "windres = windres\n" );
173 #else
174 fprintf ( fMakefile, "host_gcc = gcc\n" );
175 fprintf ( fMakefile, "host_ar = ar\n" );
176 fprintf ( fMakefile, "host_ld = ld\n" );
177 fprintf ( fMakefile, "rm = rm -f\n" );
178 fprintf ( fMakefile, "gcc = mingw32-gcc\n" );
179 fprintf ( fMakefile, "ld = mingw32-ld\n" );
180 fprintf ( fMakefile, "ar = mingw32-ar\n" );
181 fprintf ( fMakefile, "dlltool = mingw32-dlltool\n" );
182 fprintf ( fMakefile, "windres = mingw32-windres\n" );
183 #endif
184 fprintf ( fMakefile, "mkdir = tools%crmkdir\n", CSEP );
185 fprintf ( fMakefile, "NUL=NUL\n" );
186 fprintf ( fMakefile, "winebuild = tools" SSEP "winebuild" SSEP "winebuild\n" );
187 fprintf ( fMakefile, "bin2res = tools" SSEP "bin2res" SSEP "bin2res\n" );
188 fprintf ( fMakefile, "\n" );
189 GenerateGlobalCFlagsAndProperties (
190 "=",
191 ProjectNode.properties,
192 ProjectNode.includes,
193 ProjectNode.defines,
194 ProjectNode.ifs );
195 fprintf ( fMakefile, "PROJECT_RCFLAGS = $(PROJECT_CFLAGS)\n" );
196 fprintf ( fMakefile, "PROJECT_LFLAGS = %s\n",
197 GenerateProjectLFLAGS ().c_str () );
198 fprintf ( fMakefile, "\n" );
199
200 fprintf ( fMakefile, ".PHONY: clean\n\n" );
201 }
202
203 void
204 MingwBackend::GenerateAllTarget ()
205 {
206 fprintf ( fMakefile, "all:" );
207 for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
208 {
209 Module& module = *ProjectNode.modules[i];
210 fprintf ( fMakefile,
211 " %s",
212 FixupTargetFilename ( module.GetPath () ).c_str () );
213 }
214 fprintf ( fMakefile, "\n\t\n\n" );
215 }
216
217 void
218 MingwBackend::ProcessModule ( Module& module )
219 {
220 MingwModuleHandler* h = MingwModuleHandler::LookupHandler (
221 module.node.location,
222 module.type );
223 h->Process ( module );
224 h->GenerateDirectoryTargets ();
225 }
226
227 string
228 FixupTargetFilename ( const string& targetFilename )
229 {
230 return string("$(ROS_INTERMEDIATE)") + NormalizeFilename ( targetFilename );
231 }