1 #ifndef MAKEFILE_GENERATOR
12 static define app = ((GuiApplication)__thisModule);
15 bool eString_PathInsideOfMore(char * path, char * of, char * pathRest)
17 if(!path[0] || !of[0])
18 return false; // What to do here? Ever used?
21 char ofPart[MAX_FILENAME], ofRest[MAX_LOCATION];
22 char pathPart[MAX_FILENAME]; //, pathRest[MAX_LOCATION];
24 strcpy(pathRest, path);
25 for(; ofRest[0] && pathRest[0];)
27 SplitDirectory(ofRest, ofPart, ofRest);
28 SplitDirectory(pathRest, pathPart, pathRest);
29 if(fstrcmp(pathPart, ofPart))
32 if(!ofRest[0] && !pathRest[0])
34 else if(!pathRest[0]) // not inside of, it's the other way around
40 enum NodeTypes { project, file, folder, resources, folderOpen };
43 genFile, ewsFile, epjFile, folder, openFolder, ecFile, ehFile,
44 cFile, hFile, cppFile, hppFile, textFile, webFile, pictureFile, soundFile,
45 archiveFile, packageFile, opticalMediaImageFile, mFile;
47 NodeIcons ::SelectFileIcon(char * filePath)
50 if(filePath && filePath[0])
52 char extension[MAX_EXTENSION];
53 GetExtension(filePath, extension);
56 if(!strcmpi(extension, WorkspaceExtension))
58 else if(!strcmpi(extension, ProjectExtension))
60 else if(!strcmpi(extension, "ec"))
62 else if(!strcmpi(extension, "eh"))
64 else if(!strcmpi(extension, "cpp") || !strcmpi(extension, "cc") ||
65 !strcmpi(extension, "cxx"))
67 else if(!strcmpi(extension, "hpp") || !strcmpi(extension, "hh") ||
68 !strcmpi(extension, "hxx"))
70 else if(!strcmpi(extension, "c"))
72 else if(!strcmpi(extension, "h"))
74 else if(!strcmpi(extension, "m"))
76 else if(!strcmpi(extension, "txt") || !strcmpi(extension, "text") ||
77 !strcmpi(extension, "nfo") || !strcmpi(extension, "info"))
79 else if(!strcmpi(extension, "htm") || !strcmpi(extension, "html") ||
80 !strcmpi(extension, "css") || !strcmpi(extension, "php") ||
81 !strcmpi(extension, "js"))
83 else if(!strcmpi(extension, "bmp") || !strcmpi(extension, "pcx") ||
84 !strcmpi(extension, "jpg") || !strcmpi(extension, "jpeg") ||
85 !strcmpi(extension, "gif") || !strcmpi(extension, "png") ||
86 !strcmpi(extension, "ico"))
88 else if(!strcmpi(extension, "wav") || !strcmpi(extension, "mp3") ||
89 !strcmpi(extension, "ogg") || !strcmpi(extension, "snd"))
91 else if(!strcmpi(extension, "ear") || !strcmpi(extension, "7z") ||
92 !strcmpi(extension, "rar") || !strcmpi(extension, "zip") ||
93 !strcmpi(extension, "gz") || !strcmpi(extension, "bz2") ||
94 !strcmpi(extension, "tar") || !strcmpi(extension, "arj") ||
95 !strcmpi(extension, "lza") || !strcmpi(extension, "lzh") ||
96 !strcmpi(extension, "cpio") || !strcmpi(extension, "z"))
98 else if(!strcmpi(extension, "cab") || !strcmpi(extension, "deb") ||
99 !strcmpi(extension, "rpm"))
101 else if(!strcmpi(extension, "iso") || !strcmpi(extension, "mds") ||
102 !strcmpi(extension, "cue") || !strcmpi(extension, "bin") ||
103 !strcmpi(extension, "ccd") || !strcmpi(extension, "bwt") ||
104 !strcmpi(extension, "cdi") || !strcmpi(extension, "nrg"))
105 icon = opticalMediaImageFile;
113 icon = genFile; // tocheck: error icon?
117 NodeIcons ::SelectNodeIcon(NodeTypes type)
136 #define SELECTION_COLOR Color { 10, 36, 106 }
142 // this is so not working, why!
144 // return result was not even executed (did not step on while debugging)
145 class TwoStrings : struct
165 class ProjectNode : ListItem
170 set { return { fileName = value }; }
171 // TOCHECK: Is this isset necessary at all?
172 isset { return nodeType == file && !options && !configurations && !platforms && !files; }
174 property String folder
179 if(strchr(value, '/'))
181 char p[MAX_LOCATION];
182 char n[MAX_FILENAME];
183 GetLastDirectory(value, n);
184 StripLastDirectory(value, p);
185 name = CopyString(n);
186 path = CopyString(p);
189 name = CopyString(value);
193 // TOCHECK: Non Reentrant
194 static char insidePath[MAX_LOCATION];
196 strcpy(insidePath, (parent.type == project) ? "" : parent.path);
197 PathCatSlash(insidePath, name);
199 if(!fstrcmp(path, insidePath))
203 strcpy(insidePath, path);
204 if(!insidePath[0]) strcpy(insidePath, ".");
205 PathCatSlash(insidePath, name);
209 isset { return nodeType == folder; }
211 property String fileName
216 if(strchr(value, '/'))
218 char p[MAX_LOCATION];
219 char n[MAX_FILENAME];
220 GetLastDirectory(value, n);
221 StripLastDirectory(value, p);
222 name = CopyValidateMakefilePath(n);
223 path = CopyValidateMakefilePath(p);
226 name = CopyValidateMakefilePath(value);
230 // TOCHECK: Non Reentrant
231 static char insidePath[MAX_LOCATION];
233 strcpy(insidePath, (parent.type == project) ? "" : parent.path);
234 if(!fstrcmp(path, insidePath))
238 strcpy(insidePath, path);
239 if(!insidePath[0]) strcpy(insidePath, ".");
240 PathCatSlash(insidePath, name);
244 isset { return nodeType == file && (options || configurations || platforms); }
247 LinkList<ProjectNode> files;
248 property ProjectOptions options
250 get { return project ? project.options : options; }
251 set { if(project) { delete project.options; project.options = value; } else { delete options; options = value; } }
252 isset { ProjectOptions options = project ? project.options : this.options; return options && !options.isEmpty; }
254 property Array<PlatformOptions> platforms
256 get { return project ? project.platforms : platforms; }
259 if(project) { project.platforms = value; }
262 if(platforms) { platforms.Free(); delete platforms; }
265 List<PlatformOptions> empty { };
266 Iterator<PlatformOptions> it { value };
268 for(p : platforms; !p.options || p.options.isEmpty) empty.Add(p);
269 for(p : empty; it.Find(p)) platforms.Delete(it.pointer);
276 Array<PlatformOptions> platforms = project ? project.platforms : this.platforms;
281 if(p.options && !p.options.isEmpty)
288 property List<ProjectConfig> configurations
290 get { return project ? project.configurations : configurations; }
295 if(project.configurations)
297 project.configurations.Free();
298 delete project.configurations;
300 project.configurations = value;
304 if(configurations) { configurations.Free(); delete configurations; }
307 List<ProjectConfig> empty { };
308 Iterator<ProjectConfig> it { value };
309 configurations = value;
310 for(c : configurations)
312 bool somethingSet = c.options && !c.options.isEmpty;
313 // TODO: Implement isset keyword
314 if(!somethingSet && c.platforms && c.platforms.count)
318 if(p.options && !p.options.isEmpty)
328 for(c : empty; it.Find(c)) configurations.Delete(it.pointer);
335 if(!parent) return true;
338 for(c : configurations)
340 bool somethingSet = c.options && !c.options.isEmpty;
341 if(!somethingSet && c.platforms && c.platforms.count)
345 if(p.options && !p.options.isEmpty)
360 ProjectOptions options;
361 Array<PlatformOptions> platforms;
362 List<ProjectConfig> configurations;
363 ProjectNodeType nodeType;
368 // This holds the absolute path of the .epj for the project topnode (without the filename)
369 // It holds a relative path to the topNode (project) for other nodes (folders and files)
370 // For folders, it includes the folder it refers to. If there is a name difference between the
371 // file system folder and the grouping folder of the project view, it maps to that folder.
381 // This is only set for Top Nodes
384 ProjectConfig GetMatchingNodeConfig(ProjectConfig prjConfig)
386 ProjectConfig nodeConfig = null;
387 if(property::configurations && prjConfig)
389 const char * configName = prjConfig.name;
390 for(cfg : property::configurations)
392 if(!strcmpi(cfg.name, configName))
402 // For makefile generation:
403 bool GetECFLAGS(ProjectConfig prjConfig)
405 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
406 ProjectOptions options = property::options;
407 SetBool memoryGuard = localMemoryGuard;
408 String defaultNameSpace = localDefaultNameSpace;
409 SetBool strictNameSpaces = localStrictNameSpaces;
410 SetBool noLineNumbers = localNoLineNumbers;
412 if(memoryGuard || defaultNameSpace || strictNameSpaces || noLineNumbers)
414 else if(parent.parent)
415 return parent.GetECFLAGS(prjConfig);
420 bool GetMemoryGuard(ProjectConfig prjConfig)
422 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
423 ProjectOptions options = property::options;
424 SetBool memoryGuard = localMemoryGuard;
428 return parent.GetMemoryGuard(prjConfig);
430 return memoryGuard == true;
433 String GetDefaultNameSpace(ProjectConfig prjConfig)
435 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
436 ProjectOptions options = property::options;
437 String defaultNameSpace = localDefaultNameSpace;
438 if(!defaultNameSpace)
441 return parent.GetDefaultNameSpace(prjConfig);
443 return defaultNameSpace;
446 bool GetStrictNameSpaces(ProjectConfig prjConfig)
448 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
449 ProjectOptions options = property::options;
450 SetBool strictNameSpaces = localStrictNameSpaces;
451 if(!strictNameSpaces)
454 return parent.GetStrictNameSpaces(prjConfig);
456 return strictNameSpaces == true;
459 bool GetNoLineNumbers(ProjectConfig prjConfig)
461 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
462 ProjectOptions options = property::options;
463 SetBool noLineNumbers = localNoLineNumbers;
467 return parent.GetNoLineNumbers(prjConfig);
469 return noLineNumbers == true;
472 property ProjectNode root { get { ProjectNode n; for(n = this; n.parent; n = n.parent); return n; } }
474 property bool containsFile
483 if(child.type == file ||
484 ((child.type == folder || child.type == folderOpen) && child.containsFile))
497 char * GetFullFilePath(char * buffer)
501 strcpy(buffer, root.path);
502 PathCatSlash(buffer, path);
503 PathCatSlash(buffer, name);
508 char * GetFileSysMatchingPath(char * buffer)
512 ProjectNode n, root = this.root;
513 for(n = this; n && (n.type == folder || n.type == project); n = n.parent)
515 strcpy(buffer, root.path);
517 PathCatSlash(buffer, n.path);
518 if(FileExists(buffer).isDirectory)
521 if(!(n && (n.type == folder || n.type == project)))
527 void CollectPerFileAndDirOptions(ProjectConfig prjConfig, Array<String> perFilePreprocessorDefs, Array<DirPath> perFileIncludeDirs)
529 ProjectNode node = null;
530 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
531 List<ProjectNode> nodeStack { };
533 for(node = this; node && node.parent; node = node.parent)
536 // Should we reverse this stack to give priority to the per-file includes? Does the following technique already reverse?
538 // TODO: Check how to fix duplication of following options when configuration is made per-config-per-file
539 while((node = nodeStack.lastIterator.data))
541 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
542 ProjectOptions nodeOptions = node.property::options;
543 if(nodeOptions && nodeOptions.preprocessorDefinitions)
545 for(def : nodeOptions.preprocessorDefinitions)
546 perFilePreprocessorDefs.Add(CopyString(def));
548 if(config && config.options && config.options.preprocessorDefinitions)
550 for(def : config.options.preprocessorDefinitions)
551 perFilePreprocessorDefs.Add(CopyString(def));
553 if(nodeOptions && nodeOptions.includeDirs)
555 for(dir : nodeOptions.includeDirs)
556 perFileIncludeDirs.Add(CopySystemPath(dir));
558 if(config && config.options && config.options.includeDirs)
560 for(dir : config.options.includeDirs)
561 perFileIncludeDirs.Add(CopySystemPath(dir));
563 nodeStack.lastIterator.Remove();
569 property Project project
573 ProjectNode n = this;
574 while(n && n.type != project) n = n.parent;
575 return n ? (*&n.project) : null;
579 void RenameConfig(char * oldName, char * newName)
583 for(f : files; (f.configurations || f.files)) { f.RenameConfig(oldName, newName); }
585 if(property::configurations)
587 for(c : property::configurations; !strcmp(c.name, oldName))
590 c.name = CopyString(newName);
595 void DeleteConfig(ProjectConfig configToDelete)
599 for(f : files; (f.configurations || f.files)) { f.DeleteConfig(configToDelete); }
601 if(property::configurations)
603 Iterator<ProjectConfig> c { property::configurations };
606 ProjectConfig config = c.data;
607 if(!strcmp(configToDelete.name, config.name))
614 if(!property::configurations.count)
615 property::configurations = null;
621 ProjectNode backupNode { };
625 backupNode.files = { };
626 for(f : files) backupNode.files.Add(f.Backup());
628 if(property::options)
629 backupNode.options = property::options.Copy();
631 if(property::platforms)
633 backupNode.platforms = { };
634 for(p : property::platforms)
635 backupNode.platforms.Add(p.Copy());
638 if(property::configurations)
640 backupNode.configurations = { };
641 for(c : property::configurations)
642 backupNode.configurations.Add(c.Copy());
647 void Revert(ProjectNode backupNode)
651 Iterator<ProjectNode> it { backupNode.files };
659 property::options = backupNode.options ? backupNode.options.Copy() : null;
660 if(backupNode.platforms)
662 Array<PlatformOptions> platforms { };
663 property::platforms = platforms;
665 for(p : backupNode.platforms)
666 platforms.Add(p.Copy());
668 if(backupNode.configurations)
670 List<ProjectConfig> configurations { };
671 property::configurations = configurations;
672 for(c : backupNode.configurations)
673 configurations.Add(c.Copy());
677 void FixupNode(char * parentPath)
683 else if(nodeType == file)
688 path = CopyString((parent.type == folder || parent.type == resources) ? parentPath : "");
691 else if(nodeType == folder)
697 char temp[MAX_LOCATION];
698 strcpy(temp, (parent.type == folder || parent.type == resources) ? parentPath : "");
699 PathCatSlash(temp, name);
700 path = CopyString(temp);
704 indent = parent ? parent.indent + 1 : 0;
707 icon = NodeIcons::SelectFileIcon(name);
709 icon = NodeIcons::SelectNodeIcon(type);
718 parentPath[0] = '\0';
719 else if(type == resources || type == folder)
720 strcpy(parentPath, path);
722 f.FixupNode(parentPath);
727 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
731 // TOCHECK: Called from JSON writer
732 if(nodeType == file && !property::options && !property::configurations && !property::platforms && name)
734 strcpy(tempString, "\"");
735 strcat(tempString, property::fileName);
736 strcat(tempString, "\"");
743 // TOCHECK: Called from ProjectView rendering
744 return name ? name : "";
757 if(!project && platforms)
762 if(!project && configurations)
764 configurations.Free();
765 delete configurations;
768 /////////////////////////////
774 property bool isInResources
779 for(node = this; node; node = node.parent)
781 if(node.type == resources)
788 TwoStrings GetPlatformSpecificFu(ProjectConfig prjConfig)
790 TwoStrings result { a = CopyString(""), b = CopyString("") };
791 // note: unknown platform is for common
792 Map<Platform, SetBool> exclusionInfo { };
793 MapNode<Platform, SetBool> mn;
798 CollectExclusionInfo(exclusionInfo, prjConfig);
799 common = exclusionInfo[unknown];
801 Map<Platform, SetBool> cleaned { };
802 SetBool opposite = common == true ? false : true;
803 for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
805 if(mn.key == unknown || mn.value == opposite)
806 cleaned[mn.key] = mn.value;
808 delete exclusionInfo;
809 exclusionInfo = cleaned;
812 if(exclusionInfo.count > 1)
814 if(exclusionInfo.count > 2)
817 len = strlen(exp) + strlen("$(if $(or ");
818 exp = renew exp char[len+1];
819 strcat(exp, "$(if $(or ");
822 for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
824 if(mn.key != unknown)
826 char * comma = mn.next ? "," : "";
828 var = PlatformToMakefileVariable(mn.key);
831 len = strlen(exp) + strlen("$(") + strlen(var) + strlen(")") + strlen(comma);
832 exp = renew exp char[len+1];
842 len = strlen(exp) + strlen("),");
843 exp = renew exp char[len+1];
847 if(exclusionInfo.root.minimum.key != unknown)
848 var = PlatformToMakefileVariable(exclusionInfo.root.minimum.key);
850 var = PlatformToMakefileVariable(exclusionInfo.root.minimum.next.key);
853 len = strlen(exp) + strlen("$(if $(") + strlen(var) + strlen("),");
854 exp = renew exp char[len+1];
855 strcat(exp, "$(if $(");
862 exp = common == true ? result.b : result.a;
863 len = strlen(exp) + strlen(",");
864 exp = renew exp char[len+1];
866 if(common == true) result.b = exp; else result.a = exp;
869 len = strlen(exp) + strlen(")");
870 exp = renew exp char[len+1];
874 delete exclusionInfo;
879 bool GetIsExcluded(ProjectConfig prjConfig)
882 // note: unknown platform is for common
883 Map<Platform, SetBool> exclusionInfo { };
884 CollectExclusionInfo(exclusionInfo, prjConfig);
885 if(exclusionInfo.count == 0)
887 else if(exclusionInfo.count == 1)
888 result = exclusionInfo.root.minimum.value == true;
891 SetBool check = exclusionInfo.root.minimum.value;
892 MapNode<Platform, SetBool> mn;
893 for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
895 if(check != mn.value)
898 if(!mn) // all are same
899 result = check == true;
903 delete exclusionInfo;
907 void CollectExclusionInfo(Map<Platform, SetBool> output, ProjectConfig prjConfig)
909 // note: unknown platform is for common
911 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
912 ProjectOptions options = property::options;
913 Array<PlatformOptions> platforms = property::platforms;
914 List<ProjectConfig> configurations = property::configurations;
917 parent.CollectExclusionInfo(output, prjConfig);
919 output[unknown] = unset;
921 if(options && options.excludeFromBuild)
922 output[unknown] = options.excludeFromBuild;
924 if(config && config.options && config.options.excludeFromBuild)
925 output[unknown] = config.options.excludeFromBuild;
931 if(p.options.excludeFromBuild && (platform = p.name))
932 output[platform] = p.options.excludeFromBuild;
935 if(config && config.platforms)
937 for(p : config.platforms)
939 if(p.options.excludeFromBuild && (platform = p.name))
940 output[platform] = p.options.excludeFromBuild;
948 parent.EnsureVisible();
949 row.collapsed = false;
955 parent.files.Delete(this);
958 ProjectNode Find(char * name, bool includeResources)
960 ProjectNode result = null;
965 if(includeResources || child.type != resources)
967 if(child.type != folder && child.name && !strcmpi(child.name, name))
972 result = child.Find(name, includeResources);
981 ProjectNode FindWithPath(char * name, bool includeResources)
983 ProjectNode result = null;
988 if(includeResources || child.type != resources)
990 char path[MAX_LOCATION];
991 strcpy(path, child.path);
992 if(child.type != folder && child.name)
994 PathCatSlash(path, child.name);
995 if(!strcmpi(path, name))
1001 result = child.FindWithPath(name, includeResources);
1010 ProjectNode FindByFullPath(char * path, bool includeResources)
1012 ProjectNode result = null;
1017 if(includeResources || child.type != resources)
1019 if(child.type != folder && child.name)
1021 char p[MAX_LOCATION];
1022 child.GetFullFilePath(p);
1023 if(!strcmpi(p, path))
1029 result = child.FindByFullPath(path, includeResources);
1038 ProjectNode FindSpecial(char * name, bool recursive, bool includeResources, bool includeFolders)
1040 ProjectNode result = null;
1045 if(includeResources || child.type != resources)
1047 if((includeFolders || child.type != folder) && child.name && !strcmpi(child.name, name))
1053 result = child.FindSpecial(name, recursive, includeResources, includeFolders);
1062 ProjectNode FindSameNameConflict(char * name, bool includeResources,
1063 Map<Platform, SetBool> exclusionInfo, ProjectConfig prjConfig)
1065 ProjectNode result = null;
1066 Map<Platform, SetBool> compareExclusion { };
1067 SetBool common, commonComp;
1068 SetBool actual, actualComp;
1073 if(includeResources || child.type != resources)
1075 if(child.type != folder && child.name && !strcmpi(child.name, name))
1077 child.CollectExclusionInfo(compareExclusion, prjConfig);
1078 common = exclusionInfo[unknown];
1079 commonComp = compareExclusion[unknown];
1080 if(exclusionInfo.count == 1 && compareExclusion.count == 1)
1082 if(!(common == true || commonComp == true))
1091 for(platform = (Platform)1; platform < Platform::enumSize; platform++)
1094 actualComp = commonComp;
1095 if(exclusionInfo[platform] != unset)
1096 actual = exclusionInfo[platform];
1097 if(compareExclusion[platform] != unset)
1098 actualComp = compareExclusion[platform];
1099 if(!(actual == true || actualComp == true))
1107 compareExclusion.Free();
1110 result = child.FindSameNameConflict(name, includeResources, exclusionInfo, prjConfig);
1114 compareExclusion.Free();
1116 delete compareExclusion;
1120 ProjectNode Add(Project project, char * filePath, ProjectNode after, NodeTypes type, NodeIcons icon, bool checkIfExists)
1122 ProjectNode node = null;
1123 char temp[MAX_LOCATION];
1124 Map<Platform, SetBool> exclusionInfo { };
1126 GetLastDirectory(filePath, temp);
1127 //if(!checkIfExists || !project.topNode.Find(temp, false))
1129 // TOCHECK: Shouldn't this apply either for all configs or none?
1130 CollectExclusionInfo(exclusionInfo, project.config);
1131 if(!checkIfExists || !project.topNode.FindSameNameConflict(temp, false, exclusionInfo, project.config))
1133 // Do the check for folder in the same parent or resource files only here
1134 if(type == folder || !checkIfExists)
1138 if(node.name && !strcmpi(node.name, temp))
1143 node = ProjectNode { parent = this, indent = indent + 1, type = type, icon = icon, name = CopyString(temp) };
1147 node.nodeType = folder;
1153 StripLastDirectory(filePath, temp);
1154 MakePathRelative(temp, project.topNode.path, temp);
1155 node.path = CopyUnixPath(temp);
1157 node.nodeType = file;
1161 strcpy(temp, (type == NodeTypes::project) ? "" : path);
1162 PathCatSlash(temp, node.name);
1163 node.path = CopyString(temp);
1165 files.Insert(after, node);
1167 delete exclusionInfo;
1171 #ifndef MAKEFILE_GENERATOR
1172 void OnDisplay(Surface surface, int x, int y, int width, ProjectView projectView, Alignment alignment, DataDisplayFlags displayFlags)
1174 char label[MAX_FILENAME];
1180 bool showConfig = true;
1185 projectView = ide.projectView;
1188 bmp = projectView.icons[icon].bitmap;
1189 xStart = /*indent * indent + */x + (bmp ? (bmp.width + 5) : 0);
1191 GetLastDirectory(name, label);
1192 if(!showConfig || projectView.drawingInProjectSettingsDialogHeader)
1194 if(projectView.drawingInProjectSettingsDialogHeader || (type == project && info))
1196 if(projectView.projectSettingsDialog && projectView.projectSettingsDialog.buildTab)
1199 addendum = projectView.projectSettingsDialog.buildTab.selectedConfigName;
1200 if(strlen(addendum))
1202 strcat(label, " (");
1203 strcat(label, addendum);
1206 addendum = projectView.projectSettingsDialog.buildTab.selectedPlatformName;
1207 if(strlen(addendum))
1209 strcat(label, " (");
1210 strcat(label, addendum);
1216 else if(!projectView.drawingInProjectSettingsDialog)
1219 strcat(label, " *");
1220 if(type == project && info)
1222 int len = strlen(info) + 4;
1223 char * more = new char[len];
1224 sprintf(more, " (%s)", info);
1225 strcat(label, more);
1229 len = strlen(label);
1233 if(type == folder || type == folderOpen)
1234 surface.SetForeground(yellow);
1238 surface.TextOpacity(false);
1239 surface.TextExtent(label, len, &w, &h);
1242 // Draw the current row stipple
1243 if(displayFlags.selected)
1244 //surface.Area(xStart - 1, y, xStart - 1, y + h - 1);
1245 //surface.Area(xStart + w - 1, y, xStart + w + 1, y + h - 1);
1246 surface.Area(xStart - 3, y, xStart + w + 1, y + h - 1);
1248 surface.WriteTextDots(alignment, xStart, y + 2, width, label, len);
1252 if(displayFlags.current)
1254 if(displayFlags.active)
1256 surface.LineStipple(0x5555);
1257 if(displayFlags.selected)
1258 surface.SetForeground(projectView.fileList.stippleColor);
1260 surface.SetForeground(projectView.fileList.foreground);
1264 surface.SetForeground(SELECTION_COLOR);
1266 surface.Rectangle(xStart - 3, y, xStart + w + 1, y + h - 1);
1267 surface.LineStipple(0);
1272 surface.SetForeground(white);
1273 surface.Blit(bmp, x /*+ indent * indent*/,y,0,0, bmp.width, bmp.height);
1279 int OnCompare(ProjectNode b)
1282 if(type == b.type /*|| type >= TYPE_DRIVE*/)
1283 result = strcmpi(name, b.name);
1286 if(type == folder && b.type == file) result = -1;
1287 else if(type == file && b.type == folder) result = 1;
1292 bool ContainsFilesWithExtension(char * extension)
1296 char ext[MAX_EXTENSION];
1297 GetExtension(name, ext);
1298 if(!fstrcmp(ext, extension))
1303 bool needed = false;
1305 if(child.ContainsFilesWithExtension(extension))
1311 void GenFileFlags(File f, Project project, ProjectConfig prjConfig)
1313 ProjectNode node = null;
1314 List<ProjectNode> nodeStack { };
1316 for(node = this; node && node.parent; node = node.parent)
1317 nodeStack.Add(node);
1319 // Should we reverse this stack to give priority to the per-file includes?
1321 while((node = nodeStack.lastIterator.data))
1323 ProjectOptions nodeOptions = node.property::options;
1324 ProjectConfig config = node.GetMatchingNodeConfig(prjConfig);
1325 if(nodeOptions && nodeOptions.preprocessorDefinitions)
1326 OutputListOption(f, "D", nodeOptions.preprocessorDefinitions, inPlace, false);
1327 if(config && config.options && config.options.preprocessorDefinitions)
1328 OutputListOption(f, "D", config.options.preprocessorDefinitions, inPlace, false);
1329 if(nodeOptions && nodeOptions.includeDirs)
1330 OutputListOption(f, "I", nodeOptions.includeDirs, inPlace, true);
1331 if(config && config.options && config.options.includeDirs)
1332 OutputListOption(f, "I", config.options.includeDirs, inPlace, true);
1334 nodeStack.lastIterator.Remove();
1339 void GenMakefileGetNameCollisionInfo(Map<String, NameCollisionInfo> namesInfo, ProjectConfig prjConfig)
1343 char extension[MAX_EXTENSION];
1344 GetExtension(name, extension);
1345 if(!strcmpi(extension, "ec") || !strcmpi(extension, "c") ||
1346 !strcmpi(extension, "cpp") || !strcmpi(extension, "cc") ||
1347 !strcmpi(extension, "cxx") || !strcmpi(extension, "m"))
1349 char moduleName[MAX_FILENAME];
1350 NameCollisionInfo info;
1351 ReplaceSpaces(moduleName, name);
1352 StripExtension(moduleName);
1353 info = namesInfo[moduleName];
1355 info = NameCollisionInfo { };
1356 info.count++; // += 1; unless this is for a bug?
1357 if(!strcmpi(extension, "ec"))
1359 else if(!strcmpi(extension, "c"))
1361 else if(!strcmpi(extension, "cpp"))
1363 else if(!strcmpi(extension, "cc"))
1365 else if(!strcmpi(extension, "cxx"))
1367 else if(!strcmpi(extension, "m"))
1369 namesInfo[moduleName] = info;
1376 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1377 child.GenMakefileGetNameCollisionInfo(namesInfo, prjConfig);
1382 int GenMakefilePrintNode(File f, Project project, GenMakefilePrintTypes printType,
1383 Map<String, NameCollisionInfo> namesInfo, Array<String> items,
1384 ProjectConfig prjConfig, bool * containsCXX)
1390 TwoStrings ts = GetPlatformSpecificFu(prjConfig);
1391 char moduleName[MAX_FILENAME];
1392 char extension[MAX_EXTENSION];
1393 GetExtension(name, extension);
1394 if(printType == resources)
1397 char tempPath[MAX_LOCATION];
1398 char modulePath[MAX_LOCATION];
1401 if(eString_PathInsideOfMore(path, project.resNode.path, tempPath))
1404 PathCatSlash(tempPath, name);
1409 strcpy(tempPath, path);
1410 PathCatSlash(tempPath, name);
1412 ReplaceSpaces(modulePath, tempPath);
1413 sprintf(s, "%s%s%s%s", ts.a, useRes ? "$(RES)" : "", modulePath, ts.b);
1414 items.Add(CopyString(s));
1416 else if(printType == sources)
1418 if(!strcmpi(extension, "c") || !strcmpi(extension, "cpp") ||
1419 !strcmpi(extension, "cc") || !strcmpi(extension, "cxx") ||
1420 !strcmpi(extension, "m"))
1422 char modulePath[MAX_LOCATION];
1424 ReplaceSpaces(modulePath, path);
1425 ReplaceSpaces(moduleName, name);
1426 sprintf(s, "%s%s%s%s%s", ts.a, modulePath, path[0] ? SEPS : "", moduleName, ts.b);
1427 items.Add(CopyString(s));
1430 else if(printType == eCsources)
1432 if(!strcmpi(extension, "ec"))
1434 char modulePath[MAX_LOCATION];
1436 ReplaceUnwantedMakeChars(modulePath, path);
1437 ReplaceUnwantedMakeChars(moduleName, name);
1438 sprintf(s, "%s%s%s%s%s", ts.a, modulePath, path[0] ? SEPS : "", moduleName, ts.b);
1439 items.Add(CopyString(s));
1442 else if(!strcmpi(extension, "c") || !strcmpi(extension, "cpp") ||
1443 !strcmpi(extension, "cc") || !strcmpi(extension, "cxx") ||
1444 !strcmpi(extension, "m"))
1446 if(printType == objects)
1449 NameCollisionInfo info;
1450 ReplaceSpaces(moduleName, name);
1451 StripExtension(moduleName);
1452 info = namesInfo[moduleName];
1453 collision = info ? info.IsExtensionColliding(extension) : false;
1454 sprintf(s, "%s$(OBJ)%s%s%s.o%s", ts.a, moduleName, collision ? "." : "", collision ? extension : "", ts.b);
1455 items.Add(CopyString(s));
1456 if(containsCXX && (!strcmpi(extension, "cpp") || !strcmpi(extension, "cc") || !strcmpi(extension, "cxx")))
1457 *containsCXX = true;
1460 else if(!strcmpi(extension, "ec"))
1462 ReplaceSpaces(moduleName, name);
1463 StripExtension(moduleName);
1464 if(printType == objects)
1467 if(printType == objects)
1468 sprintf(s, "%s$(OBJ)%s.o%s", ts.a, moduleName, ts.b);
1469 else if(printType == cObjects)
1470 sprintf(s, "%s$(OBJ)%s.c%s", ts.a, moduleName, ts.b);
1471 else if(printType == symbols)
1472 sprintf(s, "%s$(OBJ)%s.sym%s", ts.a, moduleName, ts.b);
1473 else if(printType == imports)
1474 sprintf(s, "%s$(OBJ)%s.imp%s", ts.a, moduleName, ts.b);
1476 items.Add(CopyString(s));
1484 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1485 count += child.GenMakefilePrintNode(f, project, printType, namesInfo, items, prjConfig, containsCXX);
1491 void GenMakefilePrintSymbolRules(File f, Project project, CompilerConfig compiler,
1492 ProjectConfig prjConfig, Map<Platform, bool> parentExcludedPlatforms)
1495 Array<Platform> platforms = GetPlatformsArrayFromExcluisionInfo(prjConfig);
1496 //ProjectNode child;
1497 //char objDir[MAX_LOCATION];
1498 //ReplaceSpaces(objDir, config.objDir.dir);
1500 //eSystem_Log("Printing Symbol Rules\n");
1503 char extension[MAX_EXTENSION];
1504 char modulePath[MAX_LOCATION];
1505 char moduleName[MAX_FILENAME];
1507 GetExtension(name, extension);
1508 if(!strcmpi(extension, "ec"))
1513 ReplaceSpaces(moduleName, name);
1514 StripExtension(moduleName);
1516 ReplaceSpaces(modulePath, path);
1517 if(modulePath[0]) strcat(modulePath, SEPS);
1520 // *** Dependency command ***
1521 sprintf(command, "gcc -MT $(OBJ)%s.o -MM %s%s.%s", moduleName,
1522 modulePath, moduleName, extension);
1524 // System Includes (from global settings)
1525 for(item : compiler.dirs[Includes])
1527 strcat(command, " -isystem ");
1528 if(strchr(item, ' '))
1530 strcat(command, "\"");
1531 strcat(command, item);
1532 strcat(command, "\"");
1535 strcat(command, item);
1538 for(item : project.includeDirs)
1540 strcat(command, " -I");
1541 if(strchr(item, ' '))
1543 strcat(command, "\"");
1544 strcat(command, item);
1545 strcat(command, "\"");
1548 strcat(command, item);
1550 for(item : project.preprocessorDefs)
1552 strcat(command, " -D");
1553 strcat(command, item);
1557 if((dep = DualPipeOpen(PipeOpenMode { output = 1, error = 1, input = 2 }, command)))
1560 bool firstLine = true;
1563 // To do some time: auto save external dependencies?
1566 if(dep.GetLine(line, sizeof(line)-1))
1570 char * colon = strstr(line, ":");
1571 if(strstr(line, "No such file") || strstr(line, ",") || (colon && strstr(colon+1, ":")))
1585 // If we failed to generate dependencies...
1589 OpenRulesPlatformExclusionIfs(f, &ifCount, platforms[0], parentExcludedPlatforms, null);
1590 f.Printf("$(OBJ)%s.sym: %s%s.%s\n",
1591 moduleName, modulePath, moduleName, extension);
1597 f.Printf("\t$(ECP) %s%s.%s %s.sym\n\n",
1598 modulePath, moduleName, extension, moduleName);
1601 f.Printf("\t$(ECP)");
1602 // Give priority to file flags
1603 GenFileFlags(f, project, prjConfig);
1605 f.Printf(" $(CECFLAGS)");
1606 if(GetECFLAGS(prjConfig))
1608 if(GetMemoryGuard(prjConfig))
1609 f.Printf(" -memguard");
1610 if(GetStrictNameSpaces(prjConfig))
1611 f.Printf(" -strictns");
1613 char * s = GetDefaultNameSpace(prjConfig);
1615 f.Printf(" -defaultns %s", s);
1619 f.Printf(" $(ECFLAGS)");
1620 f.Printf(" $(CFLAGS)");
1622 f.Printf(" -c %s%s.%s -o $(OBJ)%s.sym\n\n",
1623 modulePath, moduleName, extension, moduleName);
1624 CloseRulesPlatformExclusionIfs(f, ifCount);
1629 bool needed = false;
1630 if(ContainsFilesWithExtension("ec"))
1634 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1643 Map<Platform, bool> excludedPlatforms { };
1644 for(mn : parentExcludedPlatforms) if(mn) excludedPlatforms[&mn] = true;
1645 for(platform : platforms)
1647 OpenRulesPlatformExclusionIfs(f, &ifCount, platform, parentExcludedPlatforms, excludedPlatforms);
1650 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1651 child.GenMakefilePrintSymbolRules(f, project, compiler, prjConfig, excludedPlatforms);
1654 CloseRulesPlatformExclusionIfs(f, ifCount);
1655 delete excludedPlatforms;
1661 void GenMakefilePrintPrepecsRules(File f, Project project, CompilerConfig compiler,
1662 ProjectConfig prjConfig, Map<Platform, bool> parentExcludedPlatforms)
1665 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
1666 Array<Platform> platforms = GetPlatformsArrayFromExcluisionInfo(prjConfig);
1667 //ProjectNode child;
1668 //char objDir[MAX_LOCATION];
1669 //ReplaceSpaces(objDir, config.objDir.dir);
1671 //eSystem_Log("Printing Symbol Rules\n");
1674 char extension[MAX_EXTENSION];
1675 char modulePath[MAX_LOCATION];
1676 char moduleName[MAX_FILENAME];
1678 GetExtension(name, extension);
1679 if(!strcmpi(extension, "ec"))
1684 ReplaceSpaces(moduleName, name);
1685 StripExtension(moduleName);
1687 ReplaceSpaces(modulePath, path);
1688 if(modulePath[0]) strcat(modulePath, SEPS);
1690 OpenRulesPlatformExclusionIfs(f, &ifCount, platforms[0], parentExcludedPlatforms, null);
1691 f.Printf("$(OBJ)%s$(EC): %s%s.%s\n",
1692 moduleName, modulePath, moduleName, extension);
1693 //$(CPP) -x c -E ../extras/gui/controls/DirectoriesBox.ec -o $(OBJ)DirectoriesBox$(EC)
1694 /*f.Printf("\t$(CPP) %s%s.%s %s$(S)\n\n",
1695 modulePath, moduleName, extension, moduleName);*/
1697 f.Printf("\t$(CPP)");
1698 // Give priority to file flags
1699 GenFileFlags(f, project, prjConfig);
1701 /*f.Printf(" $(CECFLAGS)");
1702 if(GetECFLAGS(prjConfig))
1704 if(GetMemoryGuard(prjConfig))
1705 f.Printf(" -memguard");
1706 if(GetStrictNameSpaces(prjConfig))
1707 f.Printf(" -strictns");
1709 char * s = GetDefaultNameSpace(prjConfig);
1711 f.Printf(" -defaultns %s", s);
1715 f.Printf(" $(ECFLAGS)");*/
1716 f.Printf(" $(CFLAGS)");
1718 f.Printf(" -x c -E %s%s.%s -o $(OBJ)%s$(EC)\n\n",
1719 modulePath, moduleName, extension, moduleName);
1720 CloseRulesPlatformExclusionIfs(f, ifCount);
1725 bool needed = false;
1726 if(ContainsFilesWithExtension("ec"))
1730 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1739 Map<Platform, bool> excludedPlatforms { };
1740 for(mn : parentExcludedPlatforms) if(mn) excludedPlatforms[&mn] = true;
1741 for(platform : platforms)
1743 OpenRulesPlatformExclusionIfs(f, &ifCount, platform, parentExcludedPlatforms, excludedPlatforms);
1746 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1747 child.GenMakefilePrintPrepecsRules(f, project, compiler, prjConfig, excludedPlatforms);
1750 CloseRulesPlatformExclusionIfs(f, ifCount);
1751 delete excludedPlatforms;
1757 void GenMakefilePrintCObjectRules(File f, Project project, CompilerConfig compiler,
1758 ProjectConfig prjConfig, Map<Platform, bool> parentExcludedPlatforms)
1761 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
1762 Array<Platform> platforms = GetPlatformsArrayFromExcluisionInfo(prjConfig);
1763 //ProjectNode child;
1764 //char objDir[MAX_LOCATION];
1765 //ReplaceSpaces(objDir, config.objDir.dir);
1766 //eSystem_Log("Printing C Object Rules\n");
1769 char extension[MAX_EXTENSION];
1770 char modulePath[MAX_LOCATION];
1771 char moduleName[MAX_FILENAME];
1773 GetExtension(name, extension);
1774 if(!strcmpi(extension, "ec"))
1779 ReplaceSpaces(moduleName, name);
1780 StripExtension(moduleName);
1782 ReplaceSpaces(modulePath, path);
1783 if(modulePath[0]) strcat(modulePath, SEPS);
1786 // *** Dependency command ***
1787 sprintf(command, "gcc -MT $(OBJ)%s.o -MM %s%s.%s",
1788 moduleName, modulePath, moduleName, extension);
1790 // System Includes (from global settings)
1791 for(item : compiler.dirs[Includes])
1793 strcat(command, " -isystem ");
1794 if(strchr(item, ' '))
1796 strcat(command, "\"");
1797 strcat(command, item);
1798 strcat(command, "\"");
1801 strcat(command, item);
1804 for(item : config.includeDirs)
1806 strcat(command, " -I");
1807 if(strchr(item, ' '))
1809 strcat(command, "\"");
1810 strcat(command, item);
1811 strcat(command, "\"");
1814 strcat(command, item);
1816 for(item : config.preprocessorDefs)
1818 strcat(command, " -D");
1819 strcat(command, item);
1823 if((dep = DualPipeOpen(PipeOpenMode { output = 1, error = 1, input = 2 }, command)))
1827 bool firstLine = true;
1829 // To do some time: auto save external dependencies?
1832 if(dep.GetLine(line, sizeof(line)-1))
1836 char * colon = strstr(line, ":");
1837 if(strstr(line, "No such file") || strstr(line, ",") || (colon && strstr(colon+1, ":")))
1851 // If we failed to generate dependencies...
1854 /* COMMENTED OUT FOR NOW
1855 f.Printf("$(OBJ)%s.c: %s%s.%s $(Symbols)\n",
1856 moduleName, modulePath, moduleName, extension);
1859 OpenRulesPlatformExclusionIfs(f, &ifCount, platforms[0], parentExcludedPlatforms, null);
1860 f.Printf("$(OBJ)%s.c: %s%s.%s $(OBJ)%s.sym | $(SYMBOLS)\n",
1861 moduleName, modulePath, moduleName, extension, moduleName);
1867 f.Printf("\t$(ECC) %s%s.%s $(OBJ)%s.c\n\n",
1868 modulePath, moduleName, extension, moduleName);
1871 f.Printf("\t$(ECC)");
1872 // Give priority to file flags
1873 GenFileFlags(f, project, prjConfig);
1874 if(GetECFLAGS(prjConfig))
1876 f.Printf("%s $(CECFLAGS)", GetNoLineNumbers(prjConfig) ? " -nolinenumbers" : "");
1877 if(GetMemoryGuard(prjConfig))
1878 f.Printf(" -memguard");
1879 if(GetStrictNameSpaces(prjConfig))
1880 f.Printf(" -strictns");
1882 char * s = GetDefaultNameSpace(prjConfig);
1884 f.Printf(" -defaultns %s", s);
1888 f.Printf(" $(CECFLAGS) $(ECFLAGS)");
1889 f.Printf(" $(CFLAGS) $(FVISIBILITY)");
1891 f.Printf(" -c %s%s.%s -o $(OBJ)%s.c -symbols $(OBJ)\n\n",
1892 modulePath, moduleName, extension, moduleName);
1893 CloseRulesPlatformExclusionIfs(f, ifCount);
1898 bool needed = false;
1899 if(ContainsFilesWithExtension("ec"))
1903 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1912 Map<Platform, bool> excludedPlatforms { };
1913 for(mn : parentExcludedPlatforms) if(mn) excludedPlatforms[&mn] = true;
1914 for(platform : platforms)
1916 OpenRulesPlatformExclusionIfs(f, &ifCount, platform, parentExcludedPlatforms, excludedPlatforms);
1919 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
1920 child.GenMakefilePrintCObjectRules(f, project, compiler, prjConfig, excludedPlatforms);
1923 CloseRulesPlatformExclusionIfs(f, ifCount);
1924 delete excludedPlatforms;
1930 void GenMakefilePrintObjectRules(File f, Project project,
1931 Map<String, NameCollisionInfo> namesInfo,
1932 CompilerConfig compiler, ProjectConfig prjConfig,
1933 Map<Platform, bool> parentExcludedPlatforms)
1936 ProjectConfig config = GetMatchingNodeConfig(prjConfig);
1937 Array<Platform> platforms = GetPlatformsArrayFromExcluisionInfo(prjConfig);
1938 //ProjectNode child;
1939 //char objDir[MAX_LOCATION];
1940 //ReplaceSpaces(objDir, config.objDir.dir);
1941 //eSystem_Log("Printing Object Rules\n");
1945 char extension[MAX_EXTENSION];
1946 char modulePath[MAX_LOCATION];
1947 char moduleName[MAX_FILENAME];
1949 GetExtension(name, extension);
1950 /*if(!strcmpi(extension, "c") || !strcmpi(extension, "cpp") ||
1951 !strcmpi(extension, "ec") || !strcmpi(extension, "cc") ||
1952 !strcmpi(extension, "cxx"))*/
1953 if(!strcmpi(extension, "c") || !strcmpi(extension, "cpp") ||
1954 !strcmpi(extension, "cc") || !strcmpi(extension, "cxx") ||
1955 !strcmpi(extension, "m") || !strcmpi(extension, "ec"))
1959 NameCollisionInfo info;
1961 ReplaceSpaces(moduleName, name);
1962 StripExtension(moduleName);
1964 info = namesInfo[moduleName];
1965 collision = info ? info.IsExtensionColliding(extension) : false;
1967 ReplaceSpaces(modulePath, path);
1968 if(modulePath[0]) strcat(modulePath, SEPS);
1970 // *** Dependency command ***
1971 if(!strcmpi(extension, "ec"))
1972 sprintf(command, "%s -MT $(OBJ)%s.o -MM $(OBJ)%s.c", compiler.ccCommand, moduleName, moduleName);
1974 sprintf(command, "%s -MT $(OBJ)%s.o -MM %s%s.%s", (!strcmpi(extension, "cc") || !strcmpi(extension, "cxx") || !strcmpi(extension, "cpp")) ? compiler.cxxCommand : compiler.ccCommand,
1975 moduleName, modulePath, moduleName, extension);
1977 if(!strcmpi(extension, "ec"))
1978 f.Printf("$(OBJ)%s.o: $(OBJ)%s.c\n", moduleName, moduleName);
1982 // System Includes (from global settings)
1983 for(item : compiler.dirs[includes])
1985 strcat(command, " -isystem ");
1986 if(strchr(item, ' '))
1988 strcat(command, "\"");
1989 strcat(command, item);
1990 strcat(command, "\"");
1993 strcat(command, item);
1996 for(item : config.includeDirs)
1998 strcat(command, " -I");
1999 if(strchr(item, ' '))
2001 strcat(command, "\"");
2002 strcat(command, item);
2003 strcat(command, "\"");
2006 strcat(command, item);
2008 for(item : config.preprocessorDefs)
2010 strcat(command, " -D");
2011 strcat(command, item);
2015 if((dep = DualPipeOpen(PipeOpenMode { output = 1, error = 1, input = 2 }, command)))
2018 bool firstLine = true;
2021 // To do some time: auto save external dependencies?
2025 if(dep.GetLine(line, sizeof(line)-1))
2029 char * colon = strstr(line, ":");
2030 if(strstr(line, "No such file") || strstr(line, ",") || (colon && strstr(colon+1, ":")))
2044 // If we failed to generate dependencies...
2048 OpenRulesPlatformExclusionIfs(f, &ifCount, platforms[0], parentExcludedPlatforms, null);
2050 /*if(!strcmpi(extension, "ec"))
2051 f.Printf("$(OBJ)%s.o: $(OBJ)%s.c\n", moduleName, moduleName);
2053 f.Printf("$(OBJ)%s%s%s.o: %s%s.%s\n", moduleName,
2054 collision ? "." : "", collision ? extension : "", modulePath, moduleName, extension);
2060 f.Printf("\t$(%s)", (!strcmpi(extension, "cc") || !strcmpi(extension, "cpp") || !strcmpi(extension, "cxx")) ? "CXX" : "CC");
2061 // Give priority to file flags
2062 GenFileFlags(f, project, prjConfig);
2064 f.Printf(" $(CFLAGS)");
2066 if(!strcmpi(extension, "ec"))
2067 f.Printf(" $(FVISIBILITY) -c $(OBJ)%s.c -o $(OBJ)%s.o\n\n", moduleName, moduleName);
2069 f.Printf(" -c %s%s.%s -o $(OBJ)%s%s%s.o\n\n",
2070 modulePath, moduleName, !strcmpi(extension, "ec") ? "c" : extension, moduleName,
2071 collision ? "." : "", collision ? extension : "");
2072 CloseRulesPlatformExclusionIfs(f, ifCount);
2077 bool needed = false;
2080 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
2088 Map<Platform, bool> excludedPlatforms { };
2089 for(mn : parentExcludedPlatforms) if(mn) excludedPlatforms[&mn] = true;
2090 for(platform : platforms)
2092 OpenRulesPlatformExclusionIfs(f, &ifCount, platform, parentExcludedPlatforms, excludedPlatforms);
2095 if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
2096 child.GenMakefilePrintObjectRules(f, project, namesInfo, compiler, prjConfig, excludedPlatforms);
2099 CloseRulesPlatformExclusionIfs(f, ifCount);
2100 delete excludedPlatforms;
2106 void GenMakefileAddResources(File f, String resourcesPath, ProjectConfig prjConfig)
2113 //Iterator<ProjectNode> i { files };
2114 //Iterator<ProjectNode> prev { files };
2115 //for(child : files)
2117 for(c = 0; c < files.count; c++)
2119 ProjectNode child = files[c];
2120 TwoStrings ts = child.GetPlatformSpecificFu(prjConfig);
2123 if(child.type == file && !child.GetIsExcluded(prjConfig) && !(count > 0 && ts))
2126 char tempPath[MAX_LOCATION];
2127 char resPath[MAX_LOCATION];
2131 // $(EAR) aw%s --- /*quiet ? "q" : */""
2133 f.Printf("\t%s$(EAR) aw $(TARGET)", ts.a);
2136 if(eString_PathInsideOfMore(child.path, resourcesPath, tempPath))
2139 PathCatSlash(tempPath, child.name);
2144 strcpy(tempPath, child.path);
2145 PathCatSlash(tempPath, child.name);
2147 ReplaceSpaces(resPath, tempPath);
2148 if(strchr(tempPath, ' '))
2152 f.Printf(" %s%s%s%s", quotes, useRes ? "$(RES)" : "", tempPath, quotes);
2155 if(count == 10 || (count > 0 && (ts || !child.next)))
2157 char path[MAX_LOCATION] = "", temp[MAX_LOCATION];
2160 for(parent = this; parent.type == folder; parent = parent.parent)
2163 strcpy(path, parent.name);
2170 f.Printf(" \"%s\"%s\n", path, ts.b);
2182 if(child.type == folder)
2183 child.GenMakefileAddResources(f, resourcesPath, prjConfig);
2188 Array<Platform> GetPlatformsArrayFromExcluisionInfo(ProjectConfig prjConfig)
2190 Array<Platform> platforms { };
2191 Map<Platform, SetBool> exclusionInfo { };
2192 CollectExclusionInfo(exclusionInfo, prjConfig);
2193 if(exclusionInfo[unknown] == true && exclusionInfo.count > 1)
2194 for(mn : exclusionInfo; mn == false)
2197 platforms.Add(unknown);
2198 delete exclusionInfo;
2203 class NameCollisionInfo
2213 bool IsExtensionColliding(char * extension)
2216 if(count > 1 && ((!strcmpi(extension, "c") && ec) ||
2217 (!strcmpi(extension, "cpp") && (ec || c)) ||
2218 (!strcmpi(extension, "cc") && (ec || c || cpp)) ||
2219 (!strcmpi(extension, "cxx") && (ec || c || cpp || cc)) ||
2220 !strcmpi(extension, "m")))
2228 static inline void OpenRulesPlatformExclusionIfs(File f, int * ifCount, Platform platform,
2229 Map<Platform, bool> parentExcludedPlatforms, Map<Platform, bool> excludedPlatforms)
2231 if(platform != unknown && !parentExcludedPlatforms[platform])
2233 if(*ifCount) // we really need a if defined(a) || defined(b) here
2234 f.Printf("else\n"); // instead of repeating the rules for each platform
2236 f.Printf("ifdef %s\n\n", PlatformToMakefileVariable(platform)); //
2237 if(excludedPlatforms)
2238 excludedPlatforms[platform] = true;
2242 static inline void CloseRulesPlatformExclusionIfs(File f, int ifCount)
2247 for(c = 0; c < ifCount; c++)
2248 f.Printf("endif\n");