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, CompilerConfig compiler, ProjectConfig config, int bitDepth)
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 char * configName = config && config.name && config.name[0] ? config.name : "Common";
56 char * projectName = project.name ? project.name : "";
57 char * moduleName = project.moduleName ? project.moduleName : "";
58 char * compilerName = (compiler && compiler.name) ? compiler.name : defaultCompilerName;
59 char * targetPlatformName = compiler && compiler.targetPlatform ? compiler.targetPlatform : "";
60 char buffer[MAX_LOCATION];
61 for(c = 0, d = 0; c < len; c++)
63 if(expr[c] == '$' && c < len - 1 && expr[c + 1] == '(')
66 for(i = c + 2; i < len; i++)
73 if(!strnicmp(&expr[c + 2], "Config", n) || !strnicmp(&expr[c + 2], "Config", n))
76 strcat(buffer, configName);
77 CamelCase(&buffer[d]);
78 d += strlen(configName);
81 else if(!strnicmp(&expr[c + 2], "Module", n) || !strnicmp(&expr[c + 2], "Project", n))
84 strcat(buffer, moduleName);
85 //CamelCase(&buffer[d]);
86 d += strlen(moduleName);
89 else if(!strnicmp(&expr[c + 2], "Platform", n))
92 strcat(buffer, targetPlatformName);
93 CamelCase(&buffer[d]);
94 d += strlen(targetPlatformName);
97 else if(!strnicmp(&expr[c + 2], "Compiler", n))
100 strcat(buffer, compilerName);
101 CamelCase(&buffer[d]);
102 d += strlen(compilerName);
105 else if(!strnicmp(&expr[c + 2], "Debug_Suffix", n))
107 // We don't support .debug from the IDE yet...
110 else if(!strnicmp(&expr[c + 2], "Compiler_Suffix", n))
112 if(bitDepth || (compilerName[0] && strcmpi(compilerName, "default")))
114 if(compilerName[0] && strcmpi(compilerName, "default"))
118 strcat(buffer, compilerName);
119 CamelCase(&buffer[d]);
120 d += strlen(compilerName);
124 strcat(buffer, ".x32");
127 else if(bitDepth == 64)
129 strcat(buffer, ".x64");
137 buffer[d++] = expr[c];
142 buffer[d++] = expr[c];
147 else if(expr[i] == '\\' || expr[i] == '/')
150 strncat(buffer, &expr[i], i - c);
158 buffer[d++] = expr[c];
162 buffer[d++] = expr[c];
166 if(dir && strcmp(buffer, dir))
169 dir = CopyString(buffer);
174 dir = CopyString("");
179 public enum TargetTypes { unset, executable, sharedLibrary, staticLibrary };
180 public enum OptimizationStrategy { unset, none, speed, size };
181 public enum WarningsOption { unset, normal, none, all }; // TOCHECK: More options?
182 public enum BuildBitDepth { all, bits32, bits64 };
184 Array<String> CopyArrayString(Array<String> array)
186 Array<String> copy = null;
190 for(s : array) copy.Add(CopyString(s));
195 public class ProjectOptions
199 property SetBool allWarnings
207 WarningsOption warnings;
211 SetBool noLineNumbers;
212 OptimizationStrategy optimization;
213 Array<String> preprocessorDefinitions;
214 property Array<String> includeDirs
220 if(value && value.count)
225 includeDirs.Add(CopyValidateMakefilePath(s));
232 get { return includeDirs; }
233 isset { return includeDirs && includeDirs.count; }
235 String defaultNameSpace;
236 SetBool strictNameSpaces;
239 TargetTypes targetType;
240 // NOTE: The JSON Parser deletes strings after setting a String property, so we do a copy here.
241 // (This behavior is different from Objects (class instances) values which are not deleted)
242 // Code calling these properties should *NOT* use CopyString().
243 property char * targetFileName
245 set { delete targetFileName; if(value && value[0]) targetFileName = CopyValidateMakefilePath(value); }
246 get { return targetFileName; }
247 isset { return targetFileName && targetFileName[0]; }
249 property char * targetDirectory
251 set { delete targetDirectory; if(value /*&& value[0]*/) targetDirectory = CopyValidateMakefilePath(value); }
252 get { return targetDirectory; }
253 isset { return targetDirectory != null/*&& targetDirectory[0]*/; }
255 property char * objectsDirectory
257 set { delete objectsDirectory; if(value /*&& value[0]*/) objectsDirectory = CopyValidateMakefilePath(value); }
258 get { return objectsDirectory; }
259 isset { return objectsDirectory != null/*&& objectsDirectory[0]*/; }
261 Array<String> libraries;
262 Array<String> compilerOptions;
263 Array<String> linkerOptions;
264 property Array<String> libraryDirs
270 if(value && value.count)
275 libraryDirs.Add(CopyValidateMakefilePath(s));
276 value.Free(); // why do I have to do this here? it's a property, shouldn't json deal with this?
282 get { return libraryDirs; }
283 isset { return libraryDirs && libraryDirs.count; }
288 // todo; move those to compiler/linker sections
289 SetBool excludeFromBuild;
290 BuildBitDepth buildBitDepth;
293 property Array<String> prebuildCommands
298 prebuildCommands.Free();
299 if(value && value.count)
301 if(!prebuildCommands)
302 prebuildCommands = { };
304 prebuildCommands.Add(CopyValidateMakefilePath(s));
309 delete prebuildCommands;
311 get { return prebuildCommands; }
312 isset { return prebuildCommands && prebuildCommands.count; }
314 property Array<String> postbuildCommands
318 if(postbuildCommands)
319 postbuildCommands.Free();
320 if(value && value.count)
322 if(!postbuildCommands)
323 postbuildCommands = { };
325 postbuildCommands.Add(CopyValidateMakefilePath(s));
330 delete postbuildCommands;
332 get { return postbuildCommands; }
333 isset { return postbuildCommands && postbuildCommands.count; }
335 property Array<String> installCommands
340 installCommands.Free();
341 if(value && value.count)
344 installCommands = { };
346 installCommands.Add(CopyValidateMakefilePath(s));
351 delete installCommands;
353 get { return installCommands; }
354 isset { return installCommands && installCommands.count; }
357 ProjectOptions Copy()
359 // TODO: We'll want some solution so that we can use OnCopy for copying containers (Array<String>)
364 memoryGuard = memoryGuard,
366 noLineNumbers = noLineNumbers;
367 optimization = optimization,
368 defaultNameSpace = CopyString(defaultNameSpace),
369 strictNameSpaces = strictNameSpaces,
370 targetType = targetType,
371 targetFileName = /*CopyString(*/targetFileName/*)*/,
372 targetDirectory = /*CopyString(*/targetDirectory/*)*/,
373 objectsDirectory = /*CopyString(*/objectsDirectory/*)*/,
376 excludeFromBuild = excludeFromBuild,
378 preprocessorDefinitions = CopyArrayString(preprocessorDefinitions),
379 includeDirs = CopyArrayString(includeDirs),
380 libraries = CopyArrayString(libraries),
381 compilerOptions = CopyArrayString(compilerOptions),
382 linkerOptions = CopyArrayString(linkerOptions),
383 libraryDirs = CopyArrayString(libraryDirs),
384 prebuildCommands = CopyArrayString(prebuildCommands),
385 postbuildCommands = CopyArrayString(postbuildCommands),
386 installCommands = CopyArrayString(installCommands)
393 PrintLn("warnings:", warnings);
394 PrintLn("debug:", debug);
395 PrintLn("memoryGuard:", memoryGuard);
396 PrintLn("profile:", profile);
397 //PrintLn("noLineNumbers:", noLineNumbers);
398 PrintLn("optimization:", optimization);
401 //PrintLn("dddddddd:", dddddddd);
403 PrintLn("fastMath:", fastMath);
405 PrintLn("preprocessorDefinitions:", preprocessorDefinitions);
406 PrintLn("compilerOptions:", compilerOptions);
407 PrintLn("linkerOptions:", linkerOptions);
408 PrintLn("includeDirs:", includeDirs);
411 //PrintLn("dddddddd:", dddddddd);
419 if(preprocessorDefinitions) { preprocessorDefinitions.Free(); delete preprocessorDefinitions; }
420 if(includeDirs) { includeDirs.Free(); delete includeDirs; }
421 delete defaultNameSpace;
422 delete targetFileName;
423 delete targetDirectory;
424 delete objectsDirectory;
425 if(libraries) { libraries.Free(); delete libraries; }
426 if(compilerOptions) { compilerOptions.Free(); delete compilerOptions; }
427 if(linkerOptions) { linkerOptions.Free(); delete linkerOptions; }
428 if(libraryDirs) { libraryDirs.Free(); delete libraryDirs; }
429 if(prebuildCommands) { prebuildCommands.Free(); delete prebuildCommands; }
430 if(postbuildCommands) { postbuildCommands.Free(); delete postbuildCommands; }
431 if(installCommands) { installCommands.Free(); delete installCommands; }
434 Array<String> includeDirs;
435 String targetFileName;
436 String targetDirectory;
437 String objectsDirectory;
438 Array<String> libraryDirs;
439 Array<String> prebuildCommands;
440 Array<String> postbuildCommands;
441 Array<String> installCommands;
443 property bool isEmpty
447 if(warnings == unset &&
449 memoryGuard == unset &&
451 noLineNumbers == unset &&
452 optimization == unset &&
453 !preprocessorDefinitions &&
454 (!includeDirs || !includeDirs.count) &&
456 strictNameSpaces == unset &&
457 targetType == unset &&
464 (!libraryDirs || !libraryDirs.count) &&
467 excludeFromBuild == unset &&
469 (!prebuildCommands || !prebuildCommands.count) &&
470 (!postbuildCommands || !postbuildCommands.count) &&
471 (!installCommands || !installCommands.count))
478 public class PlatformOptions
482 property ProjectOptions options { get { return options; } set { options = value; } isset { return options && !options.isEmpty; } }
490 PlatformOptions Copy()
495 options ? options.Copy() : null
499 ProjectOptions options;
502 class ProjectConfig : struct
506 property ProjectOptions options { get { return options; } set { options = value; } isset { return options && !options.isEmpty; } }
507 property Array<PlatformOptions> platforms
509 get { return platforms; }
512 if(platforms) { platforms.Free(); delete platforms; }
515 List<PlatformOptions> empty { };
516 Iterator<PlatformOptions> it { value };
518 for(p : platforms; !p.options || p.options.isEmpty) empty.Add(p);
519 for(p : empty; it.Find(p)) platforms.Delete(it.pointer);
529 if(p.options && !p.options.isEmpty)
538 ProjectOptions options;
540 bool compilingModified, linkingModified, symbolGenModified;
541 Array<PlatformOptions> platforms;
548 if(platforms) { platforms.Free(); delete platforms; }
553 Array<PlatformOptions> platforms = null;
557 for(p : this.platforms)
559 platforms.Add(p.Copy());
565 options ? options.Copy() : null,