1 #ifndef MAKEFILE_GENERATOR
7 enum DirExpressionType { unknown, targetDir, intermediateObjectsDir }; // "type" is not right
9 class DirExpression : struct
12 DirExpressionType type;
23 return dir ? dir : "";
29 dir = CopyString(value);
35 void Evaluate(char * expression, Project project)
38 char * expr = expression;
41 char buffer[MAX_LOCATION];
45 expr = ideSettings.projectDefaultTargetDir;
46 else if(type == intermediateObjectsDir)
47 expr = ideSettings.projectDefaultIntermediateObjDir;
50 expr = defaultObjDirExpression;
52 if((len = strlen(expr)))
55 CompilerConfig compiler = GetCompilerConfig();
56 ProjectConfig config = project.config;
57 char * configName = config && config.name && config.name[0] ? config.name : "Common";
58 char * projectName = project.name ? project.name : "";
59 char * moduleName = project.moduleName ? project.moduleName : "";
60 char * compilingPlatformName = GetRuntimePlatform();
61 char * compilerName = (compiler && compiler.name) ? compiler.name : defaultCompilerName;
62 char * targetPlatformName = compiler && compiler.targetPlatform ? compiler.targetPlatform : "";
63 char buffer[MAX_LOCATION];
64 for(c = 0, d = 0; c < len; c++)
66 if(expr[c] == '$' && c < len - 1 && expr[c + 1] == '(')
69 for(i = c + 2; i < len; i++)
76 if(!strnicmp(&expr[c + 2], "Config", n) || !strnicmp(&expr[c + 2], "Config", n))
79 strcat(buffer, configName);
80 CamelCase(&buffer[d]);
81 d += strlen(configName);
84 else if(!strnicmp(&expr[c + 2], "Module", n) || !strnicmp(&expr[c + 2], "Project", n))
87 strcat(buffer, moduleName);
88 //CamelCase(&buffer[d]);
89 d += strlen(moduleName);
92 else if(!strnicmp(&expr[c + 2], "Platform", n))
95 strcat(buffer, targetPlatformName);
96 CamelCase(&buffer[d]);
97 d += strlen(targetPlatformName);
98 /*if(strcmpi(targetPlatformName, compilingPlatformName))
102 strcat(buffer, compilingPlatformName);
103 d += strlen(compilingPlatformName);
107 else if(!strnicmp(&expr[c + 2], "Compiler", n))
110 strcat(buffer, compilerName);
111 CamelCase(&buffer[d]);
112 d += strlen(compilerName);
117 buffer[d++] = expr[c];
122 buffer[d++] = expr[c];
127 else if(expr[i] == '\\' || expr[i] == '/')
130 strncat(buffer, &expr[i], i - c);
138 buffer[d++] = expr[c];
142 buffer[d++] = expr[c];
146 if(dir && strcmp(buffer, dir))
149 dir = CopyString(buffer);
155 dir = CopyString("");
160 public enum TargetTypes { unset, executable, sharedLibrary, staticLibrary };
161 public enum OptimizationStrategy { unset, none, speed, size };
162 public enum WarningsOption { unset, normal, none, all }; // TOCHECK: More options?
164 Array<String> CopyArrayString(Array<String> array)
166 Array<String> copy = null;
170 for(s : array) copy.Add(CopyString(s));
175 public class ProjectOptions
179 property SetBool allWarnings
187 WarningsOption warnings;
191 SetBool noLineNumbers;
192 OptimizationStrategy optimization;
193 Array<String> preprocessorDefinitions;
194 property Array<String> includeDirs
200 if(value && value.count)
205 includeDirs.Add(CopyValidateMakefilePath(s));
212 get { return includeDirs; }
213 isset { return includeDirs && includeDirs.count; }
215 String defaultNameSpace;
216 SetBool strictNameSpaces;
219 TargetTypes targetType;
220 // NOTE: The JSON Parser deletes strings after setting a String property, so we do a copy here.
221 // (This behavior is different from Objects (class instances) values which are not deleted)
222 // Code calling these properties should *NOT* use CopyString().
223 property char * targetFileName
225 set { delete targetFileName; if(value && value[0]) targetFileName = CopyValidateMakefilePath(value); }
226 get { return targetFileName; }
227 isset { return targetFileName && targetFileName[0]; }
229 property char * targetDirectory
231 set { delete targetDirectory; if(value /*&& value[0]*/) targetDirectory = CopyValidateMakefilePath(value); }
232 get { return targetDirectory; }
233 isset { return targetDirectory != null/*&& targetDirectory[0]*/; }
235 property char * objectsDirectory
237 set { delete objectsDirectory; if(value /*&& value[0]*/) objectsDirectory = CopyValidateMakefilePath(value); }
238 get { return objectsDirectory; }
239 isset { return objectsDirectory != null/*&& objectsDirectory[0]*/; }
241 Array<String> libraries;
242 Array<String> linkerOptions;
243 property Array<String> libraryDirs
249 if(value && value.count)
254 libraryDirs.Add(CopyValidateMakefilePath(s));
255 value.Free(); // why do I have to do this here? it's a property, shouldn't json deal with this?
261 get { return libraryDirs; }
262 isset { return libraryDirs && libraryDirs.count; }
267 SetBool excludeFromBuild;
269 property Array<String> prebuildCommands
274 prebuildCommands.Free();
275 if(value && value.count)
277 if(!prebuildCommands)
278 prebuildCommands = { };
280 prebuildCommands.Add(CopyValidateMakefilePath(s));
285 delete prebuildCommands;
287 get { return prebuildCommands; }
288 isset { return prebuildCommands && prebuildCommands.count; }
290 property Array<String> postbuildCommands
294 if(postbuildCommands)
295 postbuildCommands.Free();
296 if(value && value.count)
298 if(!postbuildCommands)
299 postbuildCommands = { };
301 postbuildCommands.Add(CopyValidateMakefilePath(s));
306 delete postbuildCommands;
308 get { return postbuildCommands; }
309 isset { return postbuildCommands && postbuildCommands.count; }
312 ProjectOptions Copy()
314 // TODO: We'll want some solution so that we can use OnCopy for copying containers (Array<String>)
319 memoryGuard = memoryGuard,
321 noLineNumbers = noLineNumbers;
322 optimization = optimization,
323 defaultNameSpace = CopyString(defaultNameSpace),
324 strictNameSpaces = strictNameSpaces,
325 targetType = targetType,
326 targetFileName = /*CopyString(*/targetFileName/*)*/,
327 targetDirectory = /*CopyString(*/targetDirectory/*)*/,
328 objectsDirectory = /*CopyString(*/objectsDirectory/*)*/,
331 excludeFromBuild = excludeFromBuild,
332 preprocessorDefinitions = CopyArrayString(preprocessorDefinitions),
333 includeDirs = CopyArrayString(includeDirs),
334 libraries = CopyArrayString(libraries),
335 linkerOptions = CopyArrayString(linkerOptions),
336 libraryDirs = CopyArrayString(libraryDirs),
337 prebuildCommands = CopyArrayString(prebuildCommands),
338 postbuildCommands = CopyArrayString(postbuildCommands)
344 if(preprocessorDefinitions) { preprocessorDefinitions.Free(); delete preprocessorDefinitions; }
345 if(includeDirs) { includeDirs.Free(); delete includeDirs; }
346 delete defaultNameSpace;
347 delete targetFileName;
348 delete targetDirectory;
349 delete objectsDirectory;
350 if(libraries) { libraries.Free(); delete libraries; }
351 if(linkerOptions) { linkerOptions.Free(); delete linkerOptions; }
352 if(libraryDirs) { libraryDirs.Free(); delete libraryDirs; }
353 if(prebuildCommands) { prebuildCommands.Free(); delete prebuildCommands; }
354 if(postbuildCommands) { postbuildCommands.Free(); delete postbuildCommands; }
357 Array<String> includeDirs;
358 String targetFileName;
359 String targetDirectory;
360 String objectsDirectory;
361 Array<String> libraryDirs;
362 Array<String> prebuildCommands;
363 Array<String> postbuildCommands;
365 property bool isEmpty
369 if(warnings == unset &&
371 memoryGuard == unset &&
373 noLineNumbers == unset &&
374 optimization == unset &&
375 !preprocessorDefinitions &&
376 (!includeDirs || !includeDirs.count) &&
378 strictNameSpaces == unset &&
379 targetType == unset &&
385 (!libraryDirs || !libraryDirs.count) &&
388 excludeFromBuild == unset &&
389 (!prebuildCommands || !prebuildCommands.count) &&
390 (!postbuildCommands || !postbuildCommands.count) )
397 public class PlatformOptions
401 property ProjectOptions options { get { return options; } set { options = value; } isset { return options && !options.isEmpty; } }
409 PlatformOptions Copy()
414 options ? options.Copy() : null
418 ProjectOptions options;
421 class ProjectConfig : struct
425 property ProjectOptions options { get { return options; } set { options = value; } isset { return options && !options.isEmpty; } }
426 property Array<PlatformOptions> platforms
428 get { return platforms; }
431 if(platforms) { platforms.Free(); delete platforms; }
434 List<PlatformOptions> empty { };
435 Iterator<PlatformOptions> it { value };
437 for(p : platforms; !p.options || p.options.isEmpty) empty.Add(p);
438 for(p : empty; it.Find(p)) platforms.Delete(it.pointer);
448 if(p.options && !p.options.isEmpty)
457 ProjectOptions options;
459 bool compilingModified, linkingModified, symbolGenModified;
460 Array<PlatformOptions> platforms;
467 if(platforms) { platforms.Free(); delete platforms; }
472 Array<PlatformOptions> platforms = null;
476 for(p : this.platforms)
478 platforms.Add(p.Copy());
484 options ? options.Copy() : null,