1 #ifndef MAKEFILE_GENERATOR
7 enum DirExpressionType { unknown, targetDir, intermediateObjectsDir }; // "type" is not right
9 class DirExpression : struct
12 DirExpressionType type;
19 property const char * dir
23 return dir ? dir : "";
29 dir = CopyString(value);
35 void Evaluate(const char * expression, Project project, CompilerConfig compiler, ProjectConfig config, int bitDepth)
38 const char * expr = expression;
44 expr = ideSettings.projectDefaultTargetDir;
45 else if(type == intermediateObjectsDir)
46 expr = ideSettings.projectDefaultIntermediateObjDir;
49 expr = defaultObjDirExpression;
51 if((len = strlen(expr)))
54 const char * configName = config && config.name && config.name[0] ? config.name : "Common";
55 const char * moduleName = project && project.moduleName ? project.moduleName : "";
56 const char * compilerName = (compiler && compiler.name) ? compiler.name : defaultCompilerName;
57 const char * targetPlatformName = compiler && compiler.targetPlatform ? compiler.targetPlatform : "";
58 char buffer[MAX_LOCATION];
59 for(c = 0, d = 0; c < len; c++)
61 if(expr[c] == '$' && c < len - 1 && expr[c + 1] == '(')
65 for(i = c + 2; i < len; i++)
72 if(!strnicmp(&expr[c + 2], "Config", n) || !strnicmp(&expr[c + 2], "Config", n))
75 strcat(buffer, configName);
76 CamelCase(&buffer[d]);
77 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);
90 else if(!strnicmp(&expr[c + 2], "Platform", n))
93 strcat(buffer, targetPlatformName);
94 CamelCase(&buffer[d]);
95 d += strlen(targetPlatformName);
99 else if(!strnicmp(&expr[c + 2], "Compiler", n))
102 strcat(buffer, compilerName);
103 CamelCase(&buffer[d]);
104 d += strlen(compilerName);
108 else if(!strnicmp(&expr[c + 2], "Debug_Suffix", n))
110 // We don't support .debug from the IDE yet...
114 else if(!strnicmp(&expr[c + 2], "Compiler_Suffix", n))
116 if(bitDepth || (compilerName[0] && strcmpi(compilerName, "default")))
118 if(compilerName[0] && strcmpi(compilerName, "default"))
122 strcat(buffer, compilerName);
123 CamelCase(&buffer[d]);
124 d += strlen(compilerName);
128 strcat(buffer, ".x32");
131 else if(bitDepth == 64)
133 strcat(buffer, ".x64");
140 else if(compiler && compiler.environmentVars && compiler.environmentVars.count)
142 for(ev : compiler.environmentVars;
143 ev.name && ev.string && ev.name[0] && ev.string[0] && !strnicmp(&expr[c + 2], ev.name, n) && strlen(ev.name) == n)
146 ChangeCh(ev.string, '\\', '/');
147 strcat(buffer, ev.string);
148 ChangeCh(ev.string, '/', '\\');
149 d += strlen(ev.string);
156 buffer[d++] = expr[c];
160 buffer[d++] = expr[c];
165 else if(expr[i] == '\\' || expr[i] == '/')
168 strncat(buffer, &expr[i], i - c);
176 buffer[d++] = expr[c];
180 buffer[d++] = expr[c];
184 if(dir && strcmp(buffer, dir))
187 dir = CopyString(buffer);
192 dir = CopyString("");
197 public enum TargetTypes { unset, executable, sharedLibrary, staticLibrary };
198 public enum OptimizationStrategy { unset, none, speed, size };
199 public enum WarningsOption { unset, normal, none, all }; // TOCHECK: More options?
200 public enum BuildBitDepth { all, bits32, bits64 };
202 Array<String> CopyArrayString(Array<String> array)
204 Array<String> copy = null;
208 for(s : array) copy.Add(CopyString(s));
213 public class ProjectOptions
217 property SetBool allWarnings
225 WarningsOption warnings;
229 SetBool noLineNumbers;
230 OptimizationStrategy optimization;
231 Array<String> preprocessorDefinitions;
232 property Array<String> includeDirs
238 if(value && value.count)
243 includeDirs.Add(CopyValidateMakefilePath(s));
250 get { return includeDirs; }
251 isset { return includeDirs && includeDirs.count; }
253 String defaultNameSpace;
254 SetBool strictNameSpaces;
257 TargetTypes targetType;
258 // NOTE: The JSON Parser deletes strings after setting a String property, so we do a copy here.
259 // (This behavior is different from Objects (class instances) values which are not deleted)
260 // Code calling these properties should *NOT* use CopyString().
261 property char * targetFileName
263 set { delete targetFileName; if(value && value[0]) targetFileName = CopyValidateMakefilePath(value); }
264 get { return targetFileName; }
265 isset { return targetFileName && targetFileName[0]; }
267 property char * targetDirectory
269 set { delete targetDirectory; if(value /*&& value[0]*/) targetDirectory = CopyValidateMakefilePath(value); }
270 get { return targetDirectory; }
271 isset { return targetDirectory != null/*&& targetDirectory[0]*/; }
273 property char * objectsDirectory
275 set { delete objectsDirectory; if(value /*&& value[0]*/) objectsDirectory = CopyValidateMakefilePath(value); }
276 get { return objectsDirectory; }
277 isset { return objectsDirectory != null/*&& objectsDirectory[0]*/; }
279 Array<String> libraries;
280 Array<String> compilerOptions;
281 Array<String> linkerOptions;
282 property Array<String> libraryDirs
288 if(value && value.count)
293 libraryDirs.Add(CopyValidateMakefilePath(s));
294 value.Free(); // why do I have to do this here? it's a property, shouldn't json deal with this?
300 get { return libraryDirs; }
301 isset { return libraryDirs && libraryDirs.count; }
306 // todo; move those to compiler/linker sections
307 SetBool excludeFromBuild;
308 BuildBitDepth buildBitDepth;
311 property Array<String> prebuildCommands
316 prebuildCommands.Free();
317 if(value && value.count)
319 if(!prebuildCommands)
320 prebuildCommands = { };
322 prebuildCommands.Add(CopyValidateMakefilePath(s));
327 delete prebuildCommands;
329 get { return prebuildCommands; }
330 isset { return prebuildCommands && prebuildCommands.count; }
332 property Array<String> postbuildCommands
336 if(postbuildCommands)
337 postbuildCommands.Free();
338 if(value && value.count)
340 if(!postbuildCommands)
341 postbuildCommands = { };
343 postbuildCommands.Add(CopyValidateMakefilePath(s));
348 delete postbuildCommands;
350 get { return postbuildCommands; }
351 isset { return postbuildCommands && postbuildCommands.count; }
353 property Array<String> installCommands
358 installCommands.Free();
359 if(value && value.count)
362 installCommands = { };
364 installCommands.Add(CopyValidateMakefilePath(s));
369 delete installCommands;
371 get { return installCommands; }
372 isset { return installCommands && installCommands.count; }
375 ProjectOptions Copy()
377 // TODO: We'll want some solution so that we can use OnCopy for copying containers (Array<String>)
382 memoryGuard = memoryGuard,
384 noLineNumbers = noLineNumbers;
385 optimization = optimization,
386 defaultNameSpace = CopyString(defaultNameSpace),
387 strictNameSpaces = strictNameSpaces,
388 targetType = targetType,
389 targetFileName = /*CopyString(*/targetFileName/*)*/,
390 targetDirectory = /*CopyString(*/targetDirectory/*)*/,
391 objectsDirectory = /*CopyString(*/objectsDirectory/*)*/,
394 excludeFromBuild = excludeFromBuild,
396 preprocessorDefinitions = CopyArrayString(preprocessorDefinitions),
397 includeDirs = CopyArrayString(includeDirs),
398 libraries = CopyArrayString(libraries),
399 compilerOptions = CopyArrayString(compilerOptions),
400 linkerOptions = CopyArrayString(linkerOptions),
401 libraryDirs = CopyArrayString(libraryDirs),
402 prebuildCommands = CopyArrayString(prebuildCommands),
403 postbuildCommands = CopyArrayString(postbuildCommands),
404 installCommands = CopyArrayString(installCommands)
411 PrintLn("warnings:", warnings);
412 PrintLn("debug:", debug);
413 PrintLn("memoryGuard:", memoryGuard);
414 PrintLn("profile:", profile);
415 //PrintLn("noLineNumbers:", noLineNumbers);
416 PrintLn("optimization:", optimization);
419 //PrintLn("dddddddd:", dddddddd);
421 PrintLn("fastMath:", fastMath);
423 PrintLn("preprocessorDefinitions:", preprocessorDefinitions);
424 PrintLn("compilerOptions:", compilerOptions);
425 PrintLn("linkerOptions:", linkerOptions);
426 PrintLn("includeDirs:", includeDirs);
429 //PrintLn("dddddddd:", dddddddd);
437 if(preprocessorDefinitions) { preprocessorDefinitions.Free(); delete preprocessorDefinitions; }
438 if(includeDirs) { includeDirs.Free(); delete includeDirs; }
439 delete defaultNameSpace;
440 delete targetFileName;
441 delete targetDirectory;
442 delete objectsDirectory;
443 if(libraries) { libraries.Free(); delete libraries; }
444 if(compilerOptions) { compilerOptions.Free(); delete compilerOptions; }
445 if(linkerOptions) { linkerOptions.Free(); delete linkerOptions; }
446 if(libraryDirs) { libraryDirs.Free(); delete libraryDirs; }
447 if(prebuildCommands) { prebuildCommands.Free(); delete prebuildCommands; }
448 if(postbuildCommands) { postbuildCommands.Free(); delete postbuildCommands; }
449 if(installCommands) { installCommands.Free(); delete installCommands; }
452 Array<String> includeDirs;
453 String targetFileName;
454 String targetDirectory;
455 String objectsDirectory;
456 Array<String> libraryDirs;
457 Array<String> prebuildCommands;
458 Array<String> postbuildCommands;
459 Array<String> installCommands;
461 property bool isEmpty
465 if(warnings == unset &&
467 memoryGuard == unset &&
469 noLineNumbers == unset &&
470 optimization == unset &&
471 !preprocessorDefinitions &&
472 (!includeDirs || !includeDirs.count) &&
474 strictNameSpaces == unset &&
475 targetType == unset &&
482 (!libraryDirs || !libraryDirs.count) &&
485 excludeFromBuild == unset &&
487 (!prebuildCommands || !prebuildCommands.count) &&
488 (!postbuildCommands || !postbuildCommands.count) &&
489 (!installCommands || !installCommands.count))
496 public class PlatformOptions
500 property ProjectOptions options { get { return options; } set { options = value; } isset { return options && !options.isEmpty; } }
508 PlatformOptions Copy()
513 options ? options.Copy() : null
517 ProjectOptions options;
520 class ProjectConfig : struct
524 property ProjectOptions options { get { return options; } set { options = value; } isset { return options && !options.isEmpty; } }
525 property Array<PlatformOptions> platforms
527 get { return platforms; }
530 if(platforms) { platforms.Free(); delete platforms; }
533 List<PlatformOptions> empty { };
534 Iterator<PlatformOptions> it { value };
536 for(p : platforms; !p.options || p.options.isEmpty) empty.Add(p);
537 for(p : empty; it.Find(p)) platforms.Delete(it.pointer);
547 if(p.options && !p.options.isEmpty)
556 ProjectOptions options;
558 bool compilingModified, linkingModified, symbolGenModified;
559 Array<PlatformOptions> platforms;
566 if(platforms) { platforms.Free(); delete platforms; }
571 Array<PlatformOptions> platforms = null;
575 for(p : this.platforms)
577 platforms.Add(p.Copy());
583 options ? options.Copy() : null,