epj2make, ide: makefile generation, global settings dialog: add CXXFLAGS to compiler...
[sdk] / ide / src / project / ProjectNode.ec
index fa5bff7..d6c478d 100644 (file)
@@ -1,4 +1,4 @@
-#ifndef MAKEFILE_GENERATOR
+#if !defined(ECERE_DOCUMENTOR) && !defined(ECERE_EPJ2MAKE)
 import "ide"
 #else
 #ifdef ECERE_STATIC
@@ -12,18 +12,18 @@ import "Project"
 static define app = ((GuiApplication)__thisModule);
 #endif
 
-#define OPTION(x) ((uint)(&((ProjectOptions)0).x))
+#define OPTION(x) ((uint)(uintptr)(&((ProjectOptions)0).x))
 
-static void OutputLog(char * string)
+static void OutputLog(const char * string)
 {
-#ifdef MAKEFILE_GENERATOR
-   printf(string);
-#else
+#if !defined(ECERE_DOCUMENTOR) && !defined(ECERE_EPJ2MAKE)
    ide.outputView.buildBox.Log(string);
+#else
+   printf("%s", string);
 #endif
 }
 
-bool eString_PathInsideOfMore(char * path, char * of, char * pathRest)
+bool eString_PathInsideOfMore(const char * path, const char * of, char * pathRest)
 {
    if(!path[0] || !of[0])
       return false;  // What to do here? Ever used?
@@ -35,7 +35,7 @@ bool eString_PathInsideOfMore(char * path, char * of, char * pathRest)
       strcpy(pathRest, path);
       for(; ofRest[0] && pathRest[0];)
       {
-         SplitDirectory(ofRest, ofPart, ofRest);      
+         SplitDirectory(ofRest, ofPart, ofRest);
          SplitDirectory(pathRest, pathPart, pathRest);
          if(fstrcmp(pathPart, ofPart))
             return false;
@@ -55,7 +55,7 @@ enum NodeIcons
    sFile, cFile, hFile, cppFile, hppFile, textFile, webFile, pictureFile, soundFile,
    archiveFile, packageFile, opticalMediaImageFile, mFile, mmFile;
 
-   NodeIcons ::SelectFileIcon(char * filePath)
+   NodeIcons ::SelectFileIcon(const char * filePath)
    {
       NodeIcons icon;
       if(filePath && filePath[0])
@@ -180,7 +180,7 @@ class TwoStrings : struct
 class DotMain : bool
 {
    //property char * { set { } }
-   DotMain ::FromFileName(char * fileName)
+   DotMain ::FromFileName(const char * fileName)
    {
       DotMain dotMain = false;
       if(fileName && fileName[0])
@@ -274,7 +274,7 @@ public:
       }
       isset { return nodeType == folder; }
    };
-   property String fileName
+   property const String fileName
    {
       set
       {
@@ -436,14 +436,14 @@ private:
    // For folders, it includes the folder it refers to. If there is a name difference between the
    // file system folder and the grouping folder of the project view, it maps to that folder.
    char * path;
-   
+
    NodeTypes type;
    NodeIcons icon;
    int indent;
    DataRow row;
 
    bool modified;
-   
+
    // This is only set for Top Nodes
    Project project;
 
@@ -451,9 +451,9 @@ private:
    {
       if(!platforms.Find(unknown))  // unknown is "Common"
       {
-         // e.g. ifneq "$(or $(or $(OSX_TARGET),$(LINUX_TARGET)),$(WINDOWS_TARGET))"
+         // e.g. ifneq ($(or $(or $(OSX_TARGET),$(LINUX_TARGET)),$(WINDOWS_TARGET)),)
          int i = 0;
-         f.Puts("ifneq \"");
+         f.Puts("ifneq (");
          for(i = 0; platforms.count && i < platforms.count - 1; i++)
             f.Puts("$(or ");
          i = 0;
@@ -468,7 +468,7 @@ private:
                f.Puts(")");
             i++;
          }
-         f.Puts("\" \"\"\n");
+         f.Puts(",)\n");
          (*ifCount)++;
       }
       else
@@ -499,7 +499,7 @@ private:
    {
       get
       {
-         bool result;
+         bool result = false;
          if(files)
          {
             for(child : files)
@@ -518,24 +518,44 @@ private:
       }
    }
 
-   char * GetFullFilePath(char * buffer)
+   char * GetFullFilePath(char * buffer, bool resolveVars)
    {
       if(buffer)
       {
          strcpy(buffer, root.path);
-         PathCatSlash(buffer, path);
-         PathCatSlash(buffer, name);
+         if(resolveVars)
+         {
+            if(path && path[0])
+            {
+               DirExpression pathExp { };
+               Project project = property::project;
+               CompilerConfig compiler = GetCompilerConfig();
+               ProjectConfig config = project.config;
+               int bitDepth = GetBitDepth();
+               pathExp.Evaluate(path, project, compiler, config, bitDepth);
+               PathCatSlash(buffer, pathExp.dir);
+               delete compiler;
+               delete pathExp;
+            }
+            PathCatSlash(buffer, name);
+         }
+         else
+         {
+            PathCatSlash(buffer, path);
+            PathCatSlash(buffer, name);
+         }
       }
       return buffer;
    }
 
-   char * GetObjectFileName(char * buffer, Map<String, NameCollisionInfo> namesInfo, IntermediateFileType type, bool dotMain)
+   char * GetObjectFileName(char * buffer, Map<String, NameCollisionInfo> namesInfo, IntermediateFileType type, bool dotMain, const char * objectFileExt)
    {
       if(buffer && (this.type == file || (this.type == project && dotMain == true)))
       {
          bool collision;
          char extension[MAX_EXTENSION];
          char moduleName[MAX_FILENAME];
+         const char * objFileExt = objectFileExt ? objectFileExt : objectDefaultFileExt;
          NameCollisionInfo info;
 
          GetExtension(name, extension);
@@ -567,9 +587,12 @@ private:
          if(type == o)
          {
             if(collision)
-               strcat(buffer, ".o");
+            {
+               strcat(buffer, ".");
+               strcat(buffer, objFileExt);
+            }
             else
-               ChangeExtension(buffer, "o", buffer);
+               ChangeExtension(buffer, objFileExt, buffer);
          }
       }
       return buffer;
@@ -608,7 +631,6 @@ private:
       // TODO: Check how to fix duplication of following options when configuration is made per-config-per-file
       while((node = nodeStack.lastIterator.data))
       {
-         ProjectConfig config = GetMatchingNodeConfig(prjConfig);
          ProjectOptions nodeOptions = node.property::options;
          if(nodeOptions && nodeOptions.preprocessorDefinitions)
          {
@@ -644,9 +666,9 @@ private:
          while(n && n.type != project) n = n.parent;
          return n ? (*&n.project) : null;
       }
-   }   
+   }
 
-   void RenameConfig(char * oldName, char * newName)
+   void RenameConfig(const char * oldName, const char * newName)
    {
       if(files)
       {
@@ -675,7 +697,7 @@ private:
          {
             ProjectConfig config = c.data;
             if(!strcmp(configToDelete.name, config.name))
-            {               
+            {
                c.Remove();
                delete config;
                break;
@@ -794,7 +816,7 @@ private:
       }
    }
 
-   char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+   const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
    {
       if(!needClass)
       {
@@ -861,7 +883,8 @@ private:
       // note: unknown platform is for common
       Map<Platform, SetBool> exclusionInfo { };
       MapNode<Platform, SetBool> mn;
-      char * exp, * var;
+      char * exp;
+      const char * var;
       int len;
       SetBool common;
 
@@ -893,7 +916,7 @@ private:
             {
                if(mn.key != unknown)
                {
-                  char * comma = mn.next ? "," : "";
+                  const char * comma = mn.next ? "," : "";
 
                   var = PlatformToMakefileTargetVariable(mn.key);
 
@@ -942,7 +965,7 @@ private:
          result.b = exp;
       }
       delete exclusionInfo;
-      
+
       return result;
    }
 
@@ -974,6 +997,19 @@ private:
       return result;
    }
 
+   bool GetIsExcludedForCompiler(ProjectConfig prjConfig, CompilerConfig compiler)
+   {
+      bool result;
+      Map<Platform, SetBool> exclusionInfo { };
+      SetBool common, platform;
+      CollectExclusionInfo(exclusionInfo, prjConfig);
+      common = exclusionInfo[unknown];
+      platform = exclusionInfo[compiler.targetPlatform];
+      result = platform == true || (common == true && platform == unset);
+      delete exclusionInfo;
+      return result;
+   }
+
    void CollectExclusionInfo(Map<Platform, SetBool> output, ProjectConfig prjConfig)
    {
       // note: unknown platform is for common
@@ -981,7 +1017,6 @@ private:
       ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       ProjectOptions options = property::options;
       Array<PlatformOptions> platforms = property::platforms;
-      List<ProjectConfig> configurations = property::configurations;
 
       if(parent)
          parent.CollectExclusionInfo(output, prjConfig);
@@ -990,7 +1025,7 @@ private:
 
       if(options && options.excludeFromBuild)
          output[unknown] = options.excludeFromBuild;
-      
+
       if(config && config.options && config.options.excludeFromBuild)
          output[unknown] = config.options.excludeFromBuild;
 
@@ -1025,7 +1060,7 @@ private:
          parent.files.Delete(this);
    }
 
-   ProjectNode Find(char * name, bool includeResources)
+   ProjectNode Find(const char * name, bool includeResources)
    {
       ProjectNode result = null;
       if(files)
@@ -1048,7 +1083,7 @@ private:
       return result;
    }
 
-   ProjectNode FindWithPath(char * name, bool includeResources)
+   ProjectNode FindWithPath(const char * name, bool includeResources)
    {
       ProjectNode result = null;
       if(files)
@@ -1077,7 +1112,7 @@ private:
       return result;
    }
 
-   ProjectNode FindByFullPath(char * path, bool includeResources)
+   ProjectNode FindByFullPath(const char * path, bool includeResources)
    {
       if(files)
       {
@@ -1088,7 +1123,7 @@ private:
       return null;
    }
 
-   ProjectNode InternalFindByFullPath(char * path, bool includeResources, char * lastDirName)
+   ProjectNode InternalFindByFullPath(const char * path, bool includeResources, const char * lastDirName)
    {
       ProjectNode result = null;
       if(files)
@@ -1102,7 +1137,7 @@ private:
                else if(child.name && !fstrcmp(lastDirName, child.name))
                {
                   char p[MAX_LOCATION];
-                  child.GetFullFilePath(p);
+                  child.GetFullFilePath(p, true);
                   if(!fstrcmp(p, path))
                   {
                      result = child;
@@ -1117,13 +1152,13 @@ private:
       return result;
    }
 
-   ProjectNode FindByObjectFileName(char * fileName, IntermediateFileType type, bool dotMain, Map<String, NameCollisionInfo> namesInfo)
+   ProjectNode FindByObjectFileName(const char * fileName, IntermediateFileType type, bool dotMain, Map<String, NameCollisionInfo> namesInfo, const char * objectFileExt)
    {
       char p[MAX_LOCATION];
       ProjectNode result = null;
       if(dotMain == true && this.type == project)
       {
-         GetObjectFileName(p, namesInfo, type, dotMain);
+         GetObjectFileName(p, namesInfo, type, dotMain, objectFileExt);
          if(!fstrcmp(p, fileName))
             result = this;
       }
@@ -1131,11 +1166,11 @@ private:
       {
          for(child : files; child.type != resources)
          {
-            if(child.type != file && (result = child.FindByObjectFileName(fileName, type, dotMain, namesInfo)))
+            if(child.type != file && (result = child.FindByObjectFileName(fileName, type, dotMain, namesInfo, objectFileExt)))
                break;
             else if(child.type == file && child.name)
             {
-               child.GetObjectFileName(p, namesInfo, type, dotMain);
+               child.GetObjectFileName(p, namesInfo, type, dotMain, objectFileExt);
                if(!fstrcmp(p, fileName))
                {
                   result = child;
@@ -1147,7 +1182,7 @@ private:
       return result;
    }
 
-   ProjectNode FindSpecial(char * name, bool recursive, bool includeResources, bool includeFolders)
+   ProjectNode FindSpecial(const char * name, bool recursive, bool includeResources, bool includeFolders)
    {
       ProjectNode result = null;
       if(files)
@@ -1171,7 +1206,7 @@ private:
       return result;
    }
 
-   ProjectNode FindSameNameConflict(char * name, bool includeResources,
+   ProjectNode FindSameNameConflict(const char * name, bool includeResources,
       Map<Platform, SetBool> exclusionInfo, ProjectConfig prjConfig)
    {
       ProjectNode result = null;
@@ -1229,7 +1264,7 @@ private:
       return result;
    }
 
-   ProjectNode Add(Project project, char * filePath, ProjectNode after, NodeTypes type, NodeIcons icon, bool checkIfExists)
+   ProjectNode Add(Project project, const char * filePath, ProjectNode after, NodeTypes type, NodeIcons icon, bool checkIfExists)
    {
       ProjectNode node = null;
       if(!project.topNode.FindByFullPath(filePath, true))
@@ -1283,11 +1318,10 @@ private:
       return node;
    }
 
-#ifndef MAKEFILE_GENERATOR
+#if !defined(ECERE_DOCUMENTOR) && !defined(ECERE_EPJ2MAKE)
    void OnDisplay(Surface surface, int x, int y, int width, ProjectView projectView, Alignment alignment, DataDisplayFlags displayFlags)
    {
       char label[MAX_FILENAME];
-      int indent = 16;
       int xStart;
       int len;
       int w, h;
@@ -1298,10 +1332,10 @@ private:
       {
          showConfig = false;
          projectView = ide.projectView;
-      }         
-      
+      }
+
       bmp = projectView.icons[icon].bitmap;
-      xStart = /*indent * indent + */x + (bmp ? (bmp.width + 5) : 0);
+      xStart = x + (bmp ? (bmp.width + 5) : 0);
 
       GetLastDirectory(name, label);
       if(!showConfig || projectView.drawingInProjectSettingsDialogHeader)
@@ -1310,8 +1344,7 @@ private:
          {
             if(projectView.projectSettingsDialog && projectView.projectSettingsDialog.buildTab)
             {
-               char * addendum;
-               addendum = projectView.projectSettingsDialog.buildTab.selectedConfigName;
+               const char * addendum = projectView.projectSettingsDialog.buildTab.selectedConfigName;
                if(strlen(addendum))
                {
                   strcat(label, " (");
@@ -1342,7 +1375,7 @@ private:
          }
       }
       len = strlen(label);
-      
+
       if(!bmp)
       {
          if(type == folder || type == folderOpen)
@@ -1353,15 +1386,15 @@ private:
       surface.TextOpacity(false);
       surface.TextExtent(label, len, &w, &h);
       h = Max(h, 16);
-    
+
       // Draw the current row stipple
       if(displayFlags.selected)
          //surface.Area(xStart - 1, y, xStart - 1, y + h - 1);
          //surface.Area(xStart + w - 1, y, xStart + w + 1, y + h - 1);
          surface.Area(xStart - 3, y, xStart + w + 1, y + h - 1);
-      
+
       surface.WriteTextDots(alignment, xStart, y + 2, width, label, len);
-      
+
       if(!app.textMode)
       {
          if(displayFlags.current)
@@ -1393,7 +1426,7 @@ private:
 
    int OnCompare(ProjectNode b)
    {
-      int result;
+      int result = 0;
       if(type == b.type /*|| type >= TYPE_DRIVE*/)
          result = strcmpi(name, b.name);
       else
@@ -1404,9 +1437,9 @@ private:
       return result;
    }
 
-   bool ContainsFilesWithExtension(char * extension)
+   bool ContainsFilesWithExtension(const char * extension, ProjectConfig prjConfig)
    {
-      if(type == file)
+      if(type == file && name && name[0])
       {
          char ext[MAX_EXTENSION];
          GetExtension(name, ext);
@@ -1415,10 +1448,14 @@ private:
       }
       else if(files)
       {
-         bool needed = false;
          for(child : files)
-            if(child.ContainsFilesWithExtension(extension))
-               return true;
+         {
+            if(child.type != resources && (child.type == folder || !prjConfig || !child.GetIsExcluded(prjConfig)))
+            {
+               if(child.ContainsFilesWithExtension(extension, prjConfig))
+                  return true;
+            }
+         }
       }
       return false;
    }
@@ -1471,7 +1508,7 @@ private:
          }
       }
    }
-   
+
    int GenMakefilePrintNode(File f, Project project, GenMakefilePrintTypes printType,
       Map<String, NameCollisionInfo> namesInfo, Array<String> items,
       ProjectConfig prjConfig, bool * containsCXX)
@@ -1556,11 +1593,12 @@ private:
                StripExtension(moduleName);
                info = namesInfo[moduleName];
                collision = info ? info.IsExtensionColliding(extension) : false;
-               sprintf(s, "%s$(OBJ)%s%s%s.o%s", ts.a, moduleName, collision ? "." : "", collision ? extension : "", ts.b);
+               sprintf(s, "%s$(OBJ)%s%s%s$(O)%s", ts.a, moduleName, collision ? "." : "", collision ? extension : "", ts.b);
                items.Add(CopyString(s));
-               if(containsCXX && (!strcmpi(extension, "cpp") || !strcmpi(extension, "cc") || !strcmpi(extension, "cxx")))
-                  *containsCXX = true;
             }
+            else if(printType == noPrint && containsCXX &&
+                  (!strcmpi(extension, "cpp") || !strcmpi(extension, "cc") || !strcmpi(extension, "cxx")))
+               *containsCXX = true;
          }
          delete ts;
       }
@@ -1595,8 +1633,8 @@ private:
          GetExtension(name, extension);
          if(!strcmpi(extension, "ec"))
          {
-            DualPipe dep;
-            char command[2048];
+            //DualPipe dep;
+            //char command[2048];
 
             ReplaceSpaces(moduleName, name);
             StripExtension(moduleName);
@@ -1686,7 +1724,7 @@ private:
                   GenMakePrintNodeFlagsVariable(this, nodeECFlagsMapping, "ECFLAGS", f);
                   GenMakePrintNodeFlagsVariable(this, nodeCFlagsMapping, "PRJ_CFLAGS", f);
 
-                  f.Printf(" -c %s%s.%s -o $(call escspace,$@)\n",
+                  f.Printf(" -c $(call quote_path,%s%s.%s) -o $(call quote_path,$@)\n",
                      modulePath, moduleName, extension);
                   if(ifCount) f.Puts("endif\n");
                   f.Puts("\n");
@@ -1698,19 +1736,7 @@ private:
       }
       if(files)
       {
-         bool needed = false;
-         if(ContainsFilesWithExtension("ec"))
-         {
-            for(child : files)
-            {
-               if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
-               {
-                  needed = true;
-                  break;
-               }
-            }
-         }
-         if(needed)
+         if(ContainsFilesWithExtension("ec", prjConfig))
          {
             for(child : files)
             {
@@ -1728,7 +1754,6 @@ private:
          Map<intptr, int> nodeCFlagsMapping, Map<intptr, int> nodeECFlagsMapping)
    {
       int ifCount = 0;
-      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       Array<Platform> platforms = GetPlatformsArrayFromExclusionInfo(prjConfig);
       //ProjectNode child;
       //char objDir[MAX_LOCATION];
@@ -1744,9 +1769,6 @@ private:
          GetExtension(name, extension);
          if(!strcmpi(extension, "ec"))
          {
-            DualPipe dep;
-            char command[2048];
-
             ReplaceSpaces(moduleName, name);
             StripExtension(moduleName);
 
@@ -1774,19 +1796,7 @@ private:
       }
       if(files)
       {
-         bool needed = false;
-         if(ContainsFilesWithExtension("ec"))
-         {
-            for(child : files)
-            {
-               if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
-               {
-                  needed = true;
-                  break;
-               }
-            }
-         }
-         if(needed)
+         if(ContainsFilesWithExtension("ec", prjConfig))
          {
             for(child : files)
             {
@@ -1804,7 +1814,6 @@ private:
       Map<intptr, int> nodeCFlagsMapping, Map<intptr, int> nodeECFlagsMapping)
    {
       int ifCount = 0;
-      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       Array<Platform> platforms = GetPlatformsArrayFromExclusionInfo(prjConfig);
       //ProjectNode child;
       //char objDir[MAX_LOCATION];
@@ -1819,8 +1828,8 @@ private:
          GetExtension(name, extension);
          if(!strcmpi(extension, "ec"))
          {
-            DualPipe dep;
-            char command[2048];
+            //DualPipe dep;
+            //char command[2048];
 
             ReplaceSpaces(moduleName, name);
             StripExtension(moduleName);
@@ -1922,7 +1931,7 @@ private:
             GenMakePrintNodeFlagsVariable(this, nodeCFlagsMapping, "PRJ_CFLAGS", f);
             f.Puts(" $(FVISIBILITY)");
 
-            f.Printf(" -c %s%s.%s -o $(call escspace,$@) -symbols $(OBJ)\n",
+            f.Printf(" -c $(call quote_path,%s%s.%s) -o $(call quote_path,$@) -symbols $(OBJ)\n",
                modulePath, moduleName, extension);
             if(ifCount) f.Puts("endif\n");
             f.Puts("\n");
@@ -1930,19 +1939,7 @@ private:
       }
       if(files)
       {
-         bool needed = false;
-         if(ContainsFilesWithExtension("ec"))
-         {
-            for(child : files)
-            {
-               if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
-               {
-                  needed = true;
-                  break;
-               }
-            }
-         }
-         if(needed)
+         if(ContainsFilesWithExtension("ec", prjConfig))
          {
             for(child : files)
             {
@@ -1962,7 +1959,6 @@ private:
       Map<intptr, int> nodeCFlagsMapping, Map<intptr, int> nodeECFlagsMapping)
    {
       int ifCount = 0;
-      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       Array<Platform> platforms = GetPlatformsArrayFromExclusionInfo(prjConfig);
       //ProjectNode child;
       //char objDir[MAX_LOCATION];
@@ -1980,8 +1976,8 @@ private:
                !strcmpi(extension, "cpp") || !strcmpi(extension, "cc") || !strcmpi(extension, "cxx") ||
                !strcmpi(extension, "m") || !strcmpi(extension, "mm") || !strcmpi(extension, "ec"))
          {
-            DualPipe dep;
-            char command[2048];
+            //DualPipe dep;
+            //char command[2048];
             NameCollisionInfo info;
 
             ReplaceSpaces(moduleName, name);
@@ -1989,7 +1985,7 @@ private:
 
             info = namesInfo[moduleName];
             collision = info ? info.IsExtensionColliding(extension) : false;
-            
+
             ReplaceSpaces(modulePath, path);
             if(modulePath[0]) strcat(modulePath, SEPS);
 
@@ -2088,26 +2084,27 @@ private:
                OpenRulesPlatformExclusionIfs(f, &ifCount, platforms);
 
             if(!strcmpi(extension, "ec"))
-               f.Printf("$(OBJ)%s.o: $(OBJ)%s.c\n", moduleName, moduleName);
+               f.Printf("$(OBJ)%s$(O): $(OBJ)%s.c\n", moduleName, moduleName);
             else
-               f.Printf("$(OBJ)%s%s%s.o: %s%s.%s\n", moduleName, 
-                     collision ? "." : "", collision ? extension : "", modulePath, moduleName, extension);
+               f.Printf("$(OBJ)%s%s%s$(O): %s%s.%s\n",
+                     moduleName, collision ? "." : "", collision ? extension : "",
+                     modulePath, moduleName, extension);
             if(!strcmpi(extension, "cc") || !strcmpi(extension, "cpp") || !strcmpi(extension, "cxx"))
-               f.Printf("\t$(CXX)");
+               f.Printf("\t$(CXX) $(CXXFLAGS)");
             else if(!strcmpi(extension, "rc"))
-               f.Printf("\t$(WINDRES) $(WINDRES_FLAGS) $< $(call escspace,$@)\n");
+               f.Printf("\t$(WINDRES) $(WINDRES_FLAGS) $< \"$(call escspace,$(call quote_path,$@))\"\n");
             else
-               f.Printf("\t$(CC)");
+               f.Printf("\t$(CC) $(CFLAGS)");
 
             if(strcmpi(extension, "rc") != 0)
             {
-               f.Puts(" $(CFLAGS)");
                GenMakePrintNodeFlagsVariable(this, nodeCFlagsMapping, "PRJ_CFLAGS", f);
 
                if(!strcmpi(extension, "ec"))
-                  f.Printf(" $(FVISIBILITY) -c $(OBJ)%s.c -o $(call escspace,$@)\n", moduleName);
+                  f.Printf(" $(FVISIBILITY) -c $(call quote_path,$(OBJ)%s.c) -o $(call quote_path,$@)\n",
+                        moduleName);
                else
-                  f.Printf(" -c %s%s.%s -o $(call escspace,$@)\n",
+                  f.Printf(" -c $(call quote_path,%s%s.%s) -o $(call quote_path,$@)\n",
                         modulePath, moduleName, !strcmpi(extension, "ec") ? "c" : extension);
             }
             if(ifCount) f.Puts("endif\n");
@@ -2138,7 +2135,7 @@ private:
       delete platforms;
    }
 
-   void GenMakefileAddResources(File f, String resourcesPath, ProjectConfig prjConfig)
+   void GenMakefileAddResources(File f, String resourcesPath, ProjectConfig prjConfig, const char * resourcesTarget)
    {
       int count = 0;
       if(files)
@@ -2163,7 +2160,7 @@ private:
 
                // $(EAR) aw%s --- /*quiet ? "q" : */""
                if(count == 0)
-                  f.Printf("\t%s$(EAR) aw$(EARFLAGS) $(TARGET)", ts.a);
+                  f.Printf("\t%s$(EAR) aw$(EARFLAGS) $(%s)", ts.a, resourcesTarget);
 
                tempPath[0] = '\0';
                if(eString_PathInsideOfMore(child.path, resourcesPath, tempPath))
@@ -2209,7 +2206,7 @@ private:
          for(child : files)
          {
             if(child.type == folder)
-               child.GenMakefileAddResources(f, resourcesPath, prjConfig);
+               child.GenMakefileAddResources(f, resourcesPath, prjConfig, resourcesTarget);
          }
       }
    }
@@ -2379,7 +2376,6 @@ private:
                nodeECFlagsMapping[(intptr)this] = nodeECFlagsMapping[(intptr)parent];
             }
          }
-
       }
       if(files)
       {
@@ -2434,7 +2430,7 @@ private:
       return platforms;
    }
 
-   void GetTargets(ProjectConfig prjConfig, Map<String, NameCollisionInfo> namesInfo, char * objDir, DynamicString output)
+   void GetTargets(ProjectConfig prjConfig, Map<String, NameCollisionInfo> namesInfo, char * objDir, const char * objectFileExt, DynamicString output)
    {
       char moduleName[MAX_FILENAME];
       if(type == file)
@@ -2444,10 +2440,10 @@ private:
          char extension[MAX_EXTENSION];
          NameCollisionInfo info;
          Project prj = property::project;
-         Map<String, String> headerToSource { [ { "eh", "ec" }, { "h", "c" }, { "hh", "cc" }, { "hpp", "cpp" }, { "hxx", "cxx" } ] };
+         Map<String, const String> headerToSource { [ { "eh", "ec" }, { "h", "c" }, { "hh", "cc" }, { "hpp", "cpp" }, { "hxx", "cxx" } ] };
 
          GetExtension(name, extension);
-         ReplaceSpaces(moduleName, name);
+         strcpy(moduleName, name);
          StripExtension(moduleName);
          info = namesInfo[moduleName];
          collision = info ? info.IsExtensionColliding(extension) : false;
@@ -2457,7 +2453,7 @@ private:
             if(!strcmpi(extension, &h2s))
             {
                char filePath[MAX_LOCATION];
-               GetFullFilePath(filePath);
+               GetFullFilePath(filePath, true);
                OutputLog($"No compilation required for header file "); OutputLog(filePath); OutputLog("\n");
                ChangeExtension(moduleName, h2s, moduleName);
                if(prj.topNode.Find(moduleName, false))
@@ -2489,12 +2485,13 @@ private:
                strcat(moduleName, ".");
                strcat(moduleName, extension);
             }
-            strcat(moduleName, ".o");
+            strcat(moduleName, ".");
+            strcat(moduleName, objectFileExt);
             output.concat(moduleName);
             output.concat("\"");
          }
       }
-      else if(type == project && ContainsFilesWithExtension("ec"))
+      else if(type == project && ContainsFilesWithExtension("ec", prjConfig))
       {
          Project prj = property::project;
 
@@ -2525,7 +2522,7 @@ private:
          for(child : files)
          {
             if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
-               child.GetTargets(prjConfig, namesInfo, objDir, output);
+               child.GetTargets(prjConfig, namesInfo, objDir, objectFileExt, output);
          }
       }
    }
@@ -2535,6 +2532,7 @@ private:
       if(type == file)
       {
          bool collision;
+         const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt;
          char extension[MAX_EXTENSION];
          char fileName[MAX_FILENAME];
          char moduleName[MAX_FILENAME];
@@ -2566,9 +2564,12 @@ private:
          }
 
          if(collision)
-            strcat(fileName, ".o");
+         {
+            strcat(fileName, ".");
+            strcat(fileName, objectFileExt);
+         }
          else
-            ChangeExtension(fileName, "o", fileName);
+            ChangeExtension(fileName, objectFileExt, fileName);
          if(FileExists(fileName)) DeleteFile(fileName);
 
          delete objDir;
@@ -2613,12 +2614,11 @@ static ProjectOptions BlendFileConfigPlatformProjectOptions(ProjectNode node, Pr
    //         p Platform
    //         u Utility (GenericOptionTools)
 
-   int e;
    int o;
    int priority = 0;
    int includeDirsOption = OPTION(includeDirs);
    ProjectNode n;
-   char * platformName = platform ? platform.OnGetString(0,0,0) : null;
+   const char * platformName = platform ? platform.OnGetString(0,0,0) : null;
 
    // OPTION(ProjectOptions' last member) for size
    Array<bool> optionConfigXplatformSet   { size = OPTION(installCommands) };
@@ -2659,7 +2659,7 @@ static ProjectOptions BlendFileConfigPlatformProjectOptions(ProjectNode node, Pr
       void LoadOption(ProjectOptions options, int option, int priority, Array<Array<String>> optionTempStrings, ProjectOptions output) {
          if(mergeValues)
          {
-            Array<String> strings = options ? *((Array<String>*)((byte *)options + option) : null;
+            Array<String> strings = options ? *(Array<String>*)((byte *)options + option) : null;
             if(strings)
             {
                int order = 0;
@@ -2838,9 +2838,7 @@ static ProjectOptions BlendFileConfigPlatformProjectOptions(ProjectNode node, Pr
 
 static void CollectPlatformsCommonOptions(Map<Platform, ProjectOptions> byPlatformOptions, ProjectOptions * platformsCommonOptions)
 {
-   char * s;
-   int i;
-   ProjectOptions first;
+   ProjectOptions first = null;
    ProjectOptions commonOptions;
 
    Map<String, int> countIncludeDirs { };
@@ -2850,7 +2848,7 @@ static void CollectPlatformsCommonOptions(Map<Platform, ProjectOptions> byPlatfo
 
    for(options : byPlatformOptions) { first = options; break; }
 
-   *platformsCommonOptions = commonOptions = first.Copy();
+   *platformsCommonOptions = commonOptions = first ? first.Copy() : { };
 
    if(commonOptions.includeDirs)
       commonOptions.includeDirs.Free();
@@ -3009,7 +3007,8 @@ static bool StringsAreSameOrMore(Array<String> strings, Array<String> originals,
             break;
          }
          else
-            map[s] = null;
+            mit.Remove();
+            // TOFIX: Templates map[s] = null;
       }
       if(result)
       {
@@ -3046,7 +3045,7 @@ static void GetPlatformsCommonStrings(Map<String, int> counts, int goodCount, Ma
       int i = it;
       if(i == goodCount)
       {
-         char * s = &it;
+         const char * s = &it;
          strings.Add(CopyString(s));
          common[s] = true;
       }
@@ -3076,7 +3075,7 @@ static void RemovePlatformsCommonStrings(Map<String, bool> common, Array<String>
    }
 }
 
-static void GenMakePrintNodeFlagsVariable(ProjectNode node, Map<intptr, int> nodeFlagsMapping, String variableName, File f)
+static void GenMakePrintNodeFlagsVariable(ProjectNode node, Map<intptr, int> nodeFlagsMapping, const String variableName, File f)
 {
    int customFlags;
    customFlags = nodeFlagsMapping[(intptr)node];
@@ -3086,7 +3085,7 @@ static void GenMakePrintNodeFlagsVariable(ProjectNode node, Map<intptr, int> nod
       f.Printf(" $(%s)", variableName);
 }
 
-static void DynStringPrintNodeFlagsVariable(ProjectNode node, Map<intptr, int> nodeFlagsMapping, String variableName, DynamicString s)
+static void DynStringPrintNodeFlagsVariable(ProjectNode node, Map<intptr, int> nodeFlagsMapping, const String variableName, DynamicString s)
 {
    int customFlags;
    customFlags = nodeFlagsMapping[(intptr)node];
@@ -3135,6 +3134,8 @@ static void GenCFlagsFromProjectOptions(ProjectOptions options, bool prjWithEcFi
       }
       if(options.profile)
          s.concat(" -pg");
+      if(commonOptions)
+         s.concat(" -DREPOSITORY_VERSION=\"\\\"$(REPOSITORY_VER)\\\"\"");
    }
 
    if(options && options.preprocessorDefinitions)
@@ -3156,7 +3157,7 @@ static void GenECFlagsFromProjectOptions(ProjectOptions options, bool prjWithEcF
 }
 
 static void ListOptionToDynamicString(DynamicString output, ToolchainFlag flag, Array<String> list, bool prioritize,
-      LineOutputMethod lineMethod, String newLineStart)
+      LineOutputMethod lineMethod, const String newLineStart)
 {
    if(list.count)
    {