buildsystem, epj2make, ide: support Emscripten compiler.
authorJerome St-Louis <jerome@ecere.com>
Sun, 15 Feb 2015 19:58:29 +0000 (14:58 -0500)
committerJerome St-Louis <jerome@ecere.com>
Thu, 15 Oct 2015 00:19:24 +0000 (20:19 -0400)
 - add ld and ar toolchain command options to compiler configuration.
 - add object and output file extension options to compiler config.
 - change windows style path seperator to linux style when exporting compiler config's environment variables.
 - add support for resolving compiler environment variables in compiler config's executable dirs.

13 files changed:
crossplatform.mk
default.cf
epj2make/epj2make.ec
ide/src/IDESettings.ec
ide/src/OldIDESettings.ec
ide/src/debugger/Debugger.ec
ide/src/dialogs/GlobalSettingsDialog.ec [changed mode: 0644->0755]
ide/src/ide.ec [changed mode: 0644->0755]
ide/src/project/Project.ec
ide/src/project/ProjectConfig.ec
ide/src/project/ProjectNode.ec
ide/src/project/ProjectView.ec
ide/src/project/Workspace.ec

index 375040c..0e507a8 100644 (file)
@@ -195,13 +195,14 @@ else
 endif
 
 # PREFIXES AND EXTENSIONS
-.SUFFIXES: .c .ec .sym .imp .bowl .o .a
 EC := .ec
 S := .sym
 I := .imp
 B := .bowl
 C := .c
+ifndef O
 O := .o
+endif
 A := .a
 E := $(if $(WINDOWS_TARGET),.exe,)
 SO := $(if $(WINDOWS_TARGET),.dll,$(if $(OSX_TARGET),.dylib,.so))
@@ -209,6 +210,7 @@ LP := $(if $(WINDOWS_TARGET),$(if $(STATIC_LIBRARY_TARGET),lib,),lib)
 HOST_E := $(if $(WINDOWS_HOST),.exe,)
 HOST_SO := $(if $(WINDOWS_HOST),.dll,$(if $(OSX_HOST),.dylib,.so))
 HOST_LP := $(if $(WINDOWS_HOST),$(if $(STATIC_LIBRARY_TARGET),lib,),lib)
+.SUFFIXES: .c .ec .sym .imp .bowl $(O) $(A)
 
 # TARGET VERSION
 VER := $(if $(LINUX_TARGET),$(if $(LINUX_HOST),$(if $(VERSION),.$(VERSION),),),)
index b5653a6..0e4121d 100644 (file)
@@ -7,6 +7,9 @@ ifdef WINDOWS_HOST
  endif
 endif
 
+# EXTENSIONS
+OUT := $(if $(STATIC_LIBRARY_TARGET),$(A),$(if $(SHARED_LIBRARY_TARGET),$(SO)$(VER),$(if $(EXECUTABLE_TARGET),$(E),.x)))
+
 # TOOLCHAIN
 export CC      = $(CCACHE_COMPILE)$(DISTCC_COMPILE)$(GCC_PREFIX)gcc$(_SYSROOT)$(if $(GCC_CC_FLAGS),$(space)$(GCC_CC_FLAGS),)
 export CPP     = $(CCACHE_COMPILE)$(DISTCC_COMPILE)$(GCC_PREFIX)gcc$(_SYSROOT)
index be0caf7..88faa87 100644 (file)
@@ -359,7 +359,7 @@ class epj2makeApp : GuiApplication
                   {
                      project.GenerateCompilerCf(defaultCompiler, project.topNode.ContainsFilesWithExtension("ec", project.config));
                      project.GenerateCrossPlatformMk(null);
-                     if(project.GenerateMakefile(makePath, noResources, includemkPath, project.config))
+                     if(project.GenerateMakefile(makePath, noResources, includemkPath, project.config, defaultCompiler.ldCommand))
                      {
                         if(makePath)
                            printf("%s\n", makePath);
index 067716c..d37ede5 100644 (file)
@@ -11,6 +11,18 @@ public import static "ecere"
 public import "ecere"
 #endif
 
+define ecpDefaultCommand = "ecp";
+define eccDefaultCommand = "ecc";
+define ecsDefaultCommand = "ecs";
+define earDefaultCommand = "ear";
+define cppDefaultCommand = "gcc"; // As per #624 we decided to default to "gcc"...
+define ccDefaultCommand = "gcc";
+define cxxDefaultCommand = "g++";
+//define ldDefaultCommand = "gcc";
+define arDefaultCommand = "ar";
+define objectDefaultFileExt = "o";
+define outputDefaultFileExt = "";
+
 import "StringsBox"
 
 import "OldIDESettings"
@@ -217,7 +229,9 @@ CompilerConfig MakeDefaultCompiler(const char * name, bool readOnly)
       earDefaultCommand,
       cppDefaultCommand,
       ccDefaultCommand,
-      cxxDefaultCommand
+      cxxDefaultCommand,
+      arDefaultCommand
+      //ldDefaultCommand
    };
    incref defaultCompiler;
    return defaultCompiler;
@@ -376,13 +390,31 @@ private:
       FileGetSize(settingsFilePath, &settingsFileSize);
       if(data.compilerConfigs)
       {
-         for(c : data.compilerConfigs)
+         for(ccfg : data.compilerConfigs)
          {
-            CompilerConfig compiler = c;
-            char * cxxCommand = compiler.cxxCommand;
-            if(!cxxCommand || !cxxCommand[0])
-               compiler.cxxCommand = cxxDefaultCommand;
-            incref compiler;
+            if(!ccfg.ecpCommand || !ccfg.ecpCommand[0])
+               ccfg.ecpCommand = ecpDefaultCommand;
+            if(!ccfg.eccCommand || !ccfg.eccCommand[0])
+               ccfg.eccCommand = eccDefaultCommand;
+            if(!ccfg.ecsCommand || !ccfg.ecsCommand[0])
+               ccfg.ecsCommand = ecsDefaultCommand;
+            if(!ccfg.earCommand || !ccfg.earCommand[0])
+               ccfg.earCommand = earDefaultCommand;
+            if(!ccfg.cppCommand || !ccfg.cppCommand[0])
+               ccfg.cppCommand = cppDefaultCommand;
+            if(!ccfg.ccCommand || !ccfg.ccCommand[0])
+               ccfg.ccCommand = ccDefaultCommand;
+            if(!ccfg.cxxCommand || !ccfg.cxxCommand[0])
+               ccfg.cxxCommand = cxxDefaultCommand;
+            /*if(!ccfg.ldCommand || !ccfg.ldCommand[0])
+               ccfg.ldCommand = ldDefaultCommand;*/
+            if(!ccfg.arCommand || !ccfg.arCommand[0])
+               ccfg.arCommand = arDefaultCommand;
+            if(!ccfg.objectFileExt || !ccfg.objectFileExt[0])
+               ccfg.objectFileExt = objectDefaultFileExt;
+            /*if(!ccfg.outputFileExt || !ccfg.outputFileExt[0])
+               ccfg.outputFileExt = outputDefaultFileExt;*/
+            incref ccfg;
          }
       }
       if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
@@ -867,6 +899,30 @@ public:
       get { return cxxCommand; }
       isset { return cxxCommand && cxxCommand[0]; }
    }
+   property const char * arCommand
+   {
+      set { delete arCommand; if(value && value[0]) arCommand = CopyString(value); }
+      get { return arCommand; }
+      isset { return arCommand && arCommand[0]; }
+   }
+   property const char * ldCommand
+   {
+      set { delete ldCommand; if(value && value[0]) ldCommand = CopyString(value); }
+      get { return ldCommand; }
+      isset { return ldCommand && ldCommand[0]; }
+   }
+   property const char * objectFileExt
+   {
+      set { delete objectFileExt; if(value && value[0]) objectFileExt = CopyString(value); }
+      get { return objectFileExt && objectFileExt[0] ? objectFileExt : objectDefaultFileExt ; }
+      isset { return objectFileExt && objectFileExt[0] && strcmp(objectFileExt, objectDefaultFileExt); }
+   }
+   property const char * outputFileExt
+   {
+      set { delete outputFileExt; if(value && value[0]) outputFileExt = CopyString(value); }
+      get { return outputFileExt; }
+      isset { return outputFileExt && outputFileExt[0]; }
+   }
    property const char * executableLauncher
    {
       set { delete executableLauncher; if(value && value[0]) executableLauncher = CopyString(value); }
@@ -1057,6 +1113,10 @@ private:
    char * cppCommand;
    char * ccCommand;
    char * cxxCommand;
+   char * ldCommand;
+   char * arCommand;
+   char * objectFileExt;
+   char * outputFileExt;
    char * executableLauncher;
    char * distccHosts;
    char * gnuToolchainPrefix;
@@ -1077,6 +1137,10 @@ private:
       delete cppCommand;
       delete ccCommand;
       delete cxxCommand;
+      delete ldCommand;
+      delete arCommand;
+      delete objectFileExt;
+      delete outputFileExt;
       delete makeCommand;
       delete executableLauncher;
       delete distccHosts;
@@ -1111,6 +1175,10 @@ public:
          cppCommand,
          ccCommand,
          cxxCommand,
+         arCommand,
+         ldCommand,
+         objectFileExt,
+         outputFileExt,
          executableLauncher,
          ccacheEnabled,
          distccEnabled,
index 8359f01..ea261a8 100644 (file)
@@ -25,13 +25,6 @@ define makeDefaultCommand = (__runtimePlatform == win32) ? "mingw32-make" :
 #else
    "make";
 #endif
-define ecpDefaultCommand = "ecp";
-define eccDefaultCommand = "ecc";
-define ecsDefaultCommand = "ecs";
-define earDefaultCommand = "ear";
-define cppDefaultCommand = "gcc"; // As per #624 we decided to default to "gcc"...
-define ccDefaultCommand = "gcc";
-define cxxDefaultCommand = "g++";
 
 class OldIDESettings : GlobalAppSettings
 {
index ccdc5f4..d8f352e 100644 (file)
@@ -1061,9 +1061,10 @@ class Debugger
    void RunToCursor(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, const char * absoluteFilePath, int lineNumber, bool ignoreBreakpoints, bool atSameLevel, bool oldImplementation)
    {
       char relativeFilePath[MAX_LOCATION];
+      const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt;
       _dpcl(_dpct, dplchan::debuggerCall, 0, "Debugger::RunToCursor()");
       _ChangeUserAction(runToCursor);
-      ide.workspace.GetRelativePath(absoluteFilePath, relativeFilePath, null);
+      ide.workspace.GetRelativePath(absoluteFilePath, relativeFilePath, null, objectFileExt);
 
       if(bpRunToCursor && bpRunToCursor.inserted && symbols)
       {
@@ -1339,8 +1340,9 @@ class Debugger
       {
          Project owner;
          char relativePath[MAX_LOCATION];
+         const char * objectFileExt = currentCompiler ? currentCompiler.objectFileExt : objectDefaultFileExt;
 
-         ide.workspace.GetRelativePath(absolutePath, relativePath, &owner);
+         ide.workspace.GetRelativePath(absolutePath, relativePath, &owner, objectFileExt);
 
          if(!owner && !FileExists(absolutePath))
          {
@@ -2100,7 +2102,8 @@ class Debugger
       GdbExecCommon();
       if(absoluteFilePath)
       {
-         ide.workspace.GetRelativePath(absoluteFilePath, relativeFilePath, null);
+         const char * objectFileExt = currentCompiler ? currentCompiler.objectFileExt : objectDefaultFileExt;
+         ide.workspace.GetRelativePath(absoluteFilePath, relativeFilePath, null, objectFileExt);
          if(!GdbCommand(0.1, true, "-exec-until %s:%d", relativeFilePath, lineNumber))
          {
             GetLastDirectory(relativeFilePath, relativeFilePath);
@@ -2126,7 +2129,8 @@ class Debugger
       GdbExecCommon();
       if(lineNumber)
       {
-         ide.workspace.GetRelativePath(absoluteFilePathOrLocation, relativeFilePath, null);
+         const char * objectFileExt = currentCompiler ? currentCompiler.objectFileExt : objectDefaultFileExt;
+         ide.workspace.GetRelativePath(absoluteFilePathOrLocation, relativeFilePath, null, objectFileExt);
          if(!GdbCommand(0.1, true, "advance %s:%d", relativeFilePath, lineNumber)) // should use -exec-advance -- GDB/MI implementation missing
          {
             GetLastDirectory(relativeFilePath, relativeFilePath);
@@ -4822,7 +4826,7 @@ class Breakpoint : struct
          {
             if(!strcmp(prjName, prj.name))
             {
-               if(prj.GetAbsoluteFromRelativePath(filePath, fullPath))
+               if(prj.GetAbsoluteFromRelativePath(filePath, fullPath, null))
                {
                   property::absoluteFilePath = fullPath;
                   project = prj;
@@ -4836,7 +4840,7 @@ class Breakpoint : struct
       else
       {
          Project prj = ide.project;
-         if(prj.GetAbsoluteFromRelativePath(filePath, fullPath))
+         if(prj.GetAbsoluteFromRelativePath(filePath, fullPath, null))
          {
             property::absoluteFilePath = fullPath;
             project = prj;
old mode 100644 (file)
new mode 100755 (executable)
index 7471a81..620bb2c
@@ -16,7 +16,7 @@ class GlobalSettingsDialog : Window
    hasClose = true;
    borderStyle = sizable;
    text = $"Global Settings";
-   minClientSize = { 560, 506 };
+   minClientSize = { 560, 542 };
    nativeDecorations = true;
 
    IDESettings ideSettings;
@@ -718,10 +718,22 @@ class CompilerToolchainTab : CompilersSubTab
       text = $"Ecere Archiver", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
    };
    Label cppLabel { this, position = { 8, 116 }, labeledWindow = cpp, tabCycle = false, inactive = true };
-   PathBox cpp
+   EditBox cpp
    {
       this, anchor = { left = margin, top = 112, right = 8 };
-      text = $"C Preprocessor", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
+      //text = $"C Preprocessor", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
+      text = $"C Preprocessor";//, NotifyModified = NotifyModifiedDocument;
+      bool NotifyModified(EditBox editBox)
+      {
+         CompilerConfig compiler = loadedCompiler;
+         if(compiler)
+         {
+            compiler.cppCommand = editBox.contents;
+            modifiedDocument = true;
+            compilersTab.modifiedDocument = true;
+         }
+         return true;
+      }
    };
    Label ccLabel { this, position = { 8, 142 }, labeledWindow = cc, tabCycle = false, inactive = true };
    PathBox cc
@@ -735,28 +747,40 @@ class CompilerToolchainTab : CompilersSubTab
       this, anchor = { left = margin, top = 164, right = 8 };
       text = $"C++ Compiler", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
    };
-   Label makeLabel { this, position = { 8, 194 }, labeledWindow = make, tabCycle = false, inactive = true };
-   PathBox make
+   Label arLabel { this, position = { 8, 194 }, labeledWindow = ar, tabCycle = false, inactive = true };
+   PathBox ar
    {
       this, anchor = { left = margin, top = 190, right = 8 };
+      text = $"AR", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
+   };
+   Label ldLabel { this, position = { 8, 220 }, labeledWindow = ld, tabCycle = false, inactive = true };
+   PathBox ld
+   {
+      this, anchor = { left = margin, top = 216, right = 8 };
+      text = $"Linker", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
+   };
+   Label makeLabel { this, position = { 8, 246 }, labeledWindow = make, tabCycle = false, inactive = true };
+   PathBox make
+   {
+      this, anchor = { left = margin, top = 242, right = 8 };
       text = $"GNU Make", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
    };
-   Label gnuToolchainPrefixLabel { this, position = { 8, 220 }, labeledWindow = gnuToolchainPrefix, tabCycle = false, inactive = true };
+   Label gnuToolchainPrefixLabel { this, position = { 8, 272 }, labeledWindow = gnuToolchainPrefix, tabCycle = false, inactive = true };
    PathBox gnuToolchainPrefix
    {
-      this, anchor = { left = margin, top = 216, right = 8 };
-      text = $"GNU Toolchain Prefix", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
+      this, anchor = { left = margin, top = 268, right = 8 };
+      text = $"GNU Toolchain Prefix", typeExpected = directory, browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
    };
-   Label sysrootLabel { this, position = { 8, 246 }, labeledWindow = sysroot, tabCycle = false, inactive = true };
+   Label sysrootLabel { this, position = { 8, 298 }, labeledWindow = sysroot, tabCycle = false, inactive = true };
    PathBox sysroot
    {
-      this, anchor = { left = margin, top = 242, right = 8 };
-      text = $"SYSROOT", typeExpected = directory, browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
+      this, anchor = { left = margin, top = 294, right = 8 };
+      text = $"SYSROOT", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
    };
-   Label executableLauncherLabel { this, position = { 8, 272 }, labeledWindow = executableLauncher, tabCycle = false, inactive = true };
+   Label executableLauncherLabel { this, position = { 8, 324 }, labeledWindow = executableLauncher, tabCycle = false, inactive = true };
    PathBox executableLauncher
    {
-      this, anchor = { left = margin, top = 268, right = 8 };
+      this, anchor = { left = margin, top = 320, right = 8 };
       text = $"Executable Launcher", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument;
    };
 
@@ -774,16 +798,20 @@ class CompilerToolchainTab : CompilersSubTab
             compiler.ecsCommand = pathBox.slashPath;
          else if(pathBox == ear)
             compiler.earCommand = pathBox.slashPath;
-         else if(pathBox == cpp)
-            compiler.cppCommand = pathBox.slashPath;
+         /*else if(pathBox == cpp)
+            compiler.cppCommand = pathBox.slashPath;*/
          else if(pathBox == cc)
             compiler.ccCommand = pathBox.slashPath;
          else if(pathBox == cxx)
             compiler.cxxCommand = pathBox.slashPath;
+         else if(pathBox == ld)
+            compiler.ldCommand = pathBox.slashPath;
+         else if(pathBox == ar)
+            compiler.arCommand = pathBox.slashPath;
          else if(pathBox == make)
             compiler.makeCommand = pathBox.slashPath;
          else if(pathBox == executableLauncher)
-            compiler.execPrefixCommand = pathBox.slashPath;
+            compiler.executableLauncher = pathBox.slashPath;
          else if(pathBox == gnuToolchainPrefix)
             compiler.gccPrefix = pathBox.slashPath;
          else if(pathBox == sysroot)
@@ -805,9 +833,12 @@ class CompilerToolchainTab : CompilersSubTab
          ecc.path = compiler.eccCommand;
          ecs.path = compiler.ecsCommand;
          ear.path = compiler.earCommand;
-         cpp.path = compiler.cppCommand;
+         //cpp.path = compiler.cppCommand;
+         cpp.contents = compiler.cppCommand;
          cc.path = compiler.ccCommand;
          cxx.path = compiler.cxxCommand;
+         ld.path = compiler.ldCommand;
+         ar.path = compiler.arCommand;
          make.path = compiler.makeCommand;
          executableLauncher.path = compiler.executableLauncher;
          gnuToolchainPrefix.path = compiler.gnuToolchainPrefix;
@@ -820,6 +851,7 @@ class CompilerToolchainTab : CompilersSubTab
          cppLabel.disabled = cpp.disabled = isVC || disabled;
          cxxLabel.disabled = cxx.disabled = isVC || disabled;
          ccLabel.disabled = cc.disabled = isVC || disabled;
+         ldLabel.disabled = cxx.disabled = isVC || disabled;
          makeLabel.disabled = make.disabled = disabled;
          executableLauncherLabel.disabled = executableLauncher.disabled = disabled;
          gnuToolchainPrefixLabel.disabled = gnuToolchainPrefix.disabled = disabled;
@@ -1084,6 +1116,44 @@ class CompilerOptionsTab : CompilersSubTab
       }
    };
 
+   Label objectFileExtLabel { this, position = { 8, 276 }, labeledWindow = objectFileExt };
+   EditBox objectFileExt
+   {
+      this, text = $"Object file extension";//, hotKey = altH;
+      position = { 168, 274 }, size = { 80, 22 };
+
+      bool NotifyModified(EditBox editBox)
+      {
+         CompilerConfig compiler = loadedCompiler;
+         if(compiler)
+         {
+            compiler.objectFileExt = editBox.contents;
+            modifiedDocument = true;
+            compilersTab.modifiedDocument = true;
+         }
+         return true;
+      }
+   };
+
+   Label outputFileExtLabel { this, position = { 8, 306 }, labeledWindow = outputFileExt };
+   EditBox outputFileExt
+   {
+      this, text = $"Output file extension";//, hotKey = altH;
+      position = { 168, 304 }, size = { 80, 22 };
+
+      bool NotifyModified(EditBox editBox)
+      {
+         CompilerConfig compiler = loadedCompiler;
+         if(compiler)
+         {
+            compiler.outputFileExt = editBox.contents;
+            modifiedDocument = true;
+            compilersTab.modifiedDocument = true;
+         }
+         return true;
+      }
+   };
+
    CompilerOptionsTab()
    {
       Platform p;
@@ -1114,6 +1184,8 @@ class CompilerOptionsTab : CompilersSubTab
          eCcompilerFlags.strings = compiler.eCcompilerFlags;
          compilerFlags.strings = compiler.compilerFlags;
          linkerFlags.strings = compiler.linkerFlags;
+         objectFileExt.contents = compiler.objectFileExt;
+         outputFileExt.contents = compiler.outputFileExt;
 
          labelTargetPlatform.disabled = disabled;
          targetPlatform.disabled = disabled;
old mode 100644 (file)
new mode 100755 (executable)
index c9aa31d..74cd35e
@@ -439,12 +439,16 @@ class IDEWorkSpace : Window
 
       void OnGotoError(const char * line, bool noParsing)
       {
-         ide.GoToError(line, noParsing);
+         CompilerConfig compiler = ide.workspace ? ideSettings.GetCompilerConfig(ide.workspace.compiler) : null;
+         const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt;
+         ide.GoToError(line, noParsing, objectFileExt);
       }
 
       void OnCodeLocationParseAndGoTo(const char * line)
       {
-         ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
+         CompilerConfig compiler = ide.workspace ? ideSettings.GetCompilerConfig(ide.workspace.compiler) : null;
+         const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt;
+         ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir, objectFileExt);
       }
 
       bool OnKeyDown(Key key, unichar ch)
@@ -2662,13 +2666,13 @@ class IDEWorkSpace : Window
       return true;
    }
 
-   void GoToError(const char * line, bool noParsing)
+   void GoToError(const char * line, bool noParsing, const char * objectFileExt)
    {
       if(projectView)
-         projectView.GoToError(line, noParsing);
+         projectView.GoToError(line, noParsing, objectFileExt);
    }
 
-   FileAttribs GoToCodeSelectFile(const char * filePath, const char * dir, Project prj, ProjectNode * node, char * selectedPath)
+   FileAttribs GoToCodeSelectFile(const char * filePath, const char * dir, Project prj, ProjectNode * node, char * selectedPath, const char * objectFileExt)
    {
       FileAttribs result { };
       FileAttribs fileAttribs;
@@ -2715,7 +2719,7 @@ class IDEWorkSpace : Window
                      }
                   }
                }
-               if(!n && (n = workspace.GetObjectFileNode(filePath, &project, selectedPath)) && project &&
+               if(!n && (n = workspace.GetObjectFileNode(filePath, &project, selectedPath, objectFileExt)) && project &&
                      (fileAttribs = FileExists(selectedPath)).isFile)
                {
                   if(node) *node = n;
@@ -2727,7 +2731,7 @@ class IDEWorkSpace : Window
       return result;
    }
 
-   void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
+   void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir, const char * objectFileExt)
    {
       char *s = null;
       const char *path = text;
@@ -2822,7 +2826,7 @@ class IDEWorkSpace : Window
          strcpy(filePath, path);
       }
 
-      if((fileAttribs = GoToCodeSelectFile(filePath, dir, prj, null, completePath)))
+      if((fileAttribs = GoToCodeSelectFile(filePath, dir, prj, null, completePath, objectFileExt)))
          CodeLocationGoTo(completePath, fileAttribs, line, col);
    }
 
@@ -2835,7 +2839,8 @@ class IDEWorkSpace : Window
          strlwr(ext);
          if(binaryDocExt.Find(ext))
             ShellOpen(path);
-         else if(!strcmp(ext, "a") || !strcmp(ext, "o") || !strcmp(ext, "lib") || !strcmp(ext, "dll") || !strcmp(ext, "exe"))
+         else if(!strcmp(ext, "a") || !strcmp(ext, "o") || !strcmp(ext, "bc") ||
+               !strcmp(ext, "lib") || !strcmp(ext, "dll") || !strcmp(ext, "exe"))
          {
             char dirPath[MAX_LOCATION];
             StripLastDirectory(path, dirPath);
@@ -3303,17 +3308,21 @@ class IDEWorkSpace : Window
 
       for(item : compiler.executableDirs)
       {
+         DirExpression dirExpr { };
+         dirExpr.Evaluate(item, null, compiler, null, 0);
          found = false;
+
          for(p : newExePaths)
          {
-            if(!fstrcmp(p, item))
+            if(!fstrcmp(p, dirExpr.dir))
             {
                found = true;
                break;
             }
          }
          if(!found)
-            newExePaths.Add(CopySystemPath(item));
+            newExePaths.Add(CopySystemPath(dirExpr.dir));
+         delete dirExpr;
       }
 
       GetEnvironment("PATH", oldList, maxPathLen);
index 013772f..5a8c93a 100644 (file)
@@ -1038,7 +1038,7 @@ private:
       return result;
    }
 
-   ProjectNode FindNodeByObjectFileName(const char * fileName, IntermediateFileType type, bool dotMain, ProjectConfig config)
+   ProjectNode FindNodeByObjectFileName(const char * fileName, IntermediateFileType type, bool dotMain, ProjectConfig config, const char * objectFileExt)
    {
       ProjectNode result;
       const char * cfgName;
@@ -1047,7 +1047,7 @@ private:
       cfgName = config ? config.name : "";
       if(!configsNameCollisions[cfgName])
          ProjectLoadLastBuildNamesInfo(this, config);
-      result = topNode.FindByObjectFileName(fileName, type, dotMain, configsNameCollisions[cfgName]);
+      result = topNode.FindByObjectFileName(fileName, type, dotMain, configsNameCollisions[cfgName], objectFileExt);
       return result;
    }
 
@@ -1349,7 +1349,7 @@ private:
    }
 
 #ifndef MAKEFILE_GENERATOR
-   ProjectNode GetObjectFileNode(const char * filePath)
+   ProjectNode GetObjectFileNode(const char * filePath, const char * objectFileExt)
    {
       ProjectNode node = null;
       char ext[MAX_EXTENSION];
@@ -1364,18 +1364,18 @@ private:
             if(fileName[0])
             {
                DotMain dotMain = DotMain::FromFileName(fileName);
-               node = FindNodeByObjectFileName(fileName, type, dotMain, null);
+               node = FindNodeByObjectFileName(fileName, type, dotMain, null, objectFileExt);
             }
          }
       }
       return node;
    }
 
-   bool GetAbsoluteFromRelativePath(const char * relativePath, char * absolutePath)
+   bool GetAbsoluteFromRelativePath(const char * relativePath, char * absolutePath, const char * objectFileExt)
    {
       ProjectNode node = topNode.FindWithPath(relativePath, false);
       if(!node)
-         node = GetObjectFileNode(relativePath);
+         node = GetObjectFileNode(relativePath, objectFileExt);
       if(node)
       {
          strcpy(absolutePath, node.project.topNode.path);
@@ -2101,6 +2101,7 @@ private:
       char command[MAX_F_STRING*4];
       char * compilerName = CopyString(compiler.name);
       Map<String, NameCollisionInfo> cfgNameCollisions;
+      const char * objFileExt = strcmp(compiler.objectFileExt, objectDefaultFileExt) != 0 ? compiler.objectFileExt : null;
 
       delete lastBuildConfigName;
       lastBuildConfigName = CopyString(config ? config.name : "Common");
@@ -2139,14 +2140,15 @@ private:
             // Create object dir if it does not exist already
             if(!FileExists(objDirExp.dir).isDirectory)
             {
-               sprintf(command, "%s CF_DIR=\"%s\"%s%s%s%s%s COMPILER=%s objdir -C \"%s\"%s -f \"%s\"",
+               sprintf(command, "%s CF_DIR=\"%s\"%s%s%s%s%s COMPILER=%s%s%s objdir -C \"%s\"%s -f \"%s\"",
                      compiler.makeCommand, cfDir,
                      crossCompiling ? " TARGET_PLATFORM=" : "",
                      targetPlatform,
                      bitDepth ? " ARCH=" : "", bitDepth == 32 ? "32" : bitDepth == 64 ? "64" : "",
                      /*(bitDepth == 64 && compiler.targetPlatform == win32) ? " GCC_PREFIX=x86_64-w64-mingw32-" : (bitDepth == 32 && compiler.targetPlatform == win32) ? " GCC_PREFIX=i686-w64-mingw32-" : */"",
-
-                     compilerName, topNode.path, justPrint ? " -n" : "", makeFilePath);
+                     compilerName,
+                     objFileExt ? " O=." : "", objFileExt ? objFileExt : "",
+                     topNode.path, justPrint ? " -n" : "", makeFilePath);
                if(justPrint)
                   ide.outputView.buildBox.Logf("%s\n", command);
                Execute(command);
@@ -2162,7 +2164,7 @@ private:
                {
                   if(!eC_Debug)
                      node.DeleteIntermediateFiles(compiler, config, bitDepth, cfgNameCollisions, mode == cObject ? true : false);
-                  node.GetTargets(config, cfgNameCollisions, objDirExp.dir, makeTargets);
+                  node.GetTargets(config, cfgNameCollisions, objDirExp.dir, compiler.objectFileExt, makeTargets);
                }
             }
          }
@@ -2197,7 +2199,7 @@ private:
          GccVersionInfo cxxVersion = GetGccVersionInfo(compiler, compiler.cxxCommand);
          char cfDir[MAX_LOCATION];
          GetIDECompilerConfigsDir(cfDir, true, true);
-         sprintf(command, "%s%s %sCF_DIR=\"%s\"%s%s%s%s%s%s COMPILER=%s %s%s%s-j%d %s%s%s -C \"%s\"%s -f \"%s\"",
+         sprintf(command, "%s%s %sCF_DIR=\"%s\"%s%s%s%s%s%s COMPILER=%s%s%s %s%s%s-j%d %s%s%s -C \"%s\"%s -f \"%s\"",
 #if defined(__WIN32__)
                "",
 #else
@@ -2212,7 +2214,9 @@ private:
                bitDepth == 32 ? "32" : bitDepth == 64 ? "64" : "",
                ide.workspace.useValgrind ? " DISABLED_POOLING=1" : "",
                /*(bitDepth == 64 && compiler.targetPlatform == win32) ? " GCC_PREFIX=x86_64-w64-mingw32-" : (bitDepth == 32 && compiler.targetPlatform == win32) ? " GCC_PREFIX=i686-w64-mingw32-" :*/ "",
-               compilerName, eC_Debug ? "--always-make " : "",
+               compilerName,
+               objFileExt ? " O=." : "", objFileExt ? objFileExt : "",
+               eC_Debug ? "--always-make " : "",
                ccVersion == post4_8 ? "GCC_CC_FLAGS=-fno-diagnostics-show-caret " : "",
                cxxVersion == post4_8 ? "GCC_CXX_FLAGS=-fno-diagnostics-show-caret " : "",
                numJobs,
@@ -2289,6 +2293,7 @@ private:
       PathBackup pathBackup { };
       bool crossCompiling = (compiler.targetPlatform != __runtimePlatform);
       const char * targetPlatform = crossCompiling ? (char *)compiler.targetPlatform : "";
+      const char * objFileExt = strcmp(compiler.objectFileExt, objectDefaultFileExt) ? compiler.objectFileExt : null;
 
       compilerName = CopyString(compiler.name);
       CamelCase(compilerName);
@@ -2323,11 +2328,12 @@ private:
       {
          char cfDir[MAX_LOCATION];
          GetIDECompilerConfigsDir(cfDir, true, true);
-         sprintf(command, "%s CF_DIR=\"%s\"%s%s%s%s COMPILER=%s %sclean%s -C \"%s\"%s -f \"%s\"",
+         sprintf(command, "%s CF_DIR=\"%s\"%s%s%s%s COMPILER=%s%s%s %sclean%s -C \"%s\"%s -f \"%s\"",
                compiler.makeCommand, cfDir,
                crossCompiling ? " TARGET_PLATFORM=" : "", targetPlatform,
                bitDepth ? " ARCH=" : "", bitDepth == 32 ? "32" : bitDepth == 64 ? "64" : "",
                compilerName,
+               objFileExt ? " O=." : "", objFileExt ? objFileExt : "",
                cleanType == realClean ? "real" : "", cleanType == cleanTarget ? "target" : "",
                topNode.path, justPrint ? " -n": "", makeFilePath);
          if(justPrint)
@@ -2410,18 +2416,7 @@ private:
       if(targetType == staticLibrary || targetType == sharedLibrary)
          strcat(fileName, "$(LP)");
       strcat(fileName, GetTargetFileName(config));
-      switch(targetType)
-      {
-         case executable:
-            strcat(fileName, "$(E)");
-            break;
-         case sharedLibrary:
-            strcat(fileName, "$(SO)$(VER)");
-            break;
-         case staticLibrary:
-            strcat(fileName, "$(A)");
-            break;
-      }
+      strcat(fileName, "$(OUT)");
    }
 
    bool GenerateCrossPlatformMk(File altCrossPlatformMk)
@@ -2512,7 +2507,9 @@ private:
                f.Puts("\n");
                for(e : compiler.environmentVars)
                {
+                  ChangeCh(e.string, '\\', '/');
                   f.Printf("export %s := %s\n", e.name, e.string);
+                  ChangeCh(e.string, '/', '\\');
                }
                f.Puts("\n");
             }
@@ -2520,6 +2517,12 @@ private:
             f.Puts("# TOOLCHAIN\n");
             f.Puts("\n");
 
+            f.Puts("# EXTENSIONS\n");
+            if(compiler.outputFileExt)
+               f.Printf("OUT := %s\n", compiler.outputFileExt);
+            else
+               f.Puts("OUT := $(if $(STATIC_LIBRARY_TARGET),$(A),$(if $(SHARED_LIBRARY_TARGET),$(SO)$(VER),$(if $(EXECUTABLE_TARGET),$(E),.x)))\n");
+
             if(gnuToolchainPrefix && gnuToolchainPrefix[0])
             {
                f.Printf("GCC_PREFIX := %s\n", gnuToolchainPrefix);
@@ -2552,8 +2555,8 @@ private:
             f.Printf("EAR := %s\n", compiler.earCommand);
 
             f.Puts("AS := $(GCC_PREFIX)as\n");
-            f.Puts("LD := $(GCC_PREFIX)ld\n");
-            f.Puts("AR := $(GCC_PREFIX)ar\n");
+            f.Printf("LD := $(GCC_PREFIX)%s$(_SYSROOT)$(if $(GCC_LD_FLAGS),$(space)$(GCC_LD_FLAGS),)\n", compiler.ldCommand);
+            f.Printf("AR := $(GCC_PREFIX)%s\n", compiler.arCommand);
             f.Puts("STRIP := $(GCC_PREFIX)strip\n");
             f.Puts("ifdef WINDOWS_TARGET\n");
             f.Puts("WINDRES := $(GCC_PREFIX)windres\n");
@@ -2664,7 +2667,7 @@ private:
       return result;
    }
 
-   bool GenerateMakefile(const char * altMakefilePath, bool noResources, const char * includemkPath, ProjectConfig config)
+   bool GenerateMakefile(const char * altMakefilePath, bool noResources, const char * includemkPath, ProjectConfig config, const char * ldCommand)
    {
       bool result = false;
       char filePath[MAX_LOCATION];
@@ -3366,7 +3369,7 @@ private:
 
          f.Puts("ifndef STATIC_LIBRARY_TARGET\n");
 
-         f.Printf("\t$(%s) $(OFLAGS) @$(OBJ)objects.lst $(LIBS) -o $(TARGET) $(INSTALLNAME)\n", containsCXX ? "CXX" : "CC");
+         f.Printf("\t$(%s) $(OFLAGS) @$(OBJ)objects.lst $(LIBS) -o $(TARGET) $(INSTALLNAME)\n", ldCommand && ldCommand[0] ? "LD" : containsCXX ? "CXX" : "CC");
          if(!GetDebug(config))
          {
             f.Puts("ifndef NOSTRIP\n");
@@ -3544,7 +3547,7 @@ private:
          f.Printf("cleantarget: objdir%s\n", sameOrRelObjTargetDirs ? "" : " targetdir");
          if(numCObjects)
          {
-            f.Printf("\t$(call rmq,%s)\n", "$(OBJ)$(MODULE).main.o $(OBJ)$(MODULE).main.c $(OBJ)$(MODULE).main.ec $(OBJ)$(MODULE).main$(I) $(OBJ)$(MODULE).main$(S)");
+            f.Printf("\t$(call rmq,%s)\n", "$(OBJ)$(MODULE).main$(O) $(OBJ)$(MODULE).main.c $(OBJ)$(MODULE).main.ec $(OBJ)$(MODULE).main$(I) $(OBJ)$(MODULE).main$(S)");
             f.Printf("\t$(call rmq,$(OBJ)symbols.lst)\n");
          }
          f.Printf("\t$(call rmq,$(OBJ)objects.lst)\n");
index 3d9b8b8..362b542 100644 (file)
@@ -52,7 +52,7 @@ class DirExpression : struct
       {
          int c, d;
          const char * configName = config && config.name && config.name[0] ? config.name : "Common";
-         const char * moduleName = project.moduleName ? project.moduleName : "";
+         const char * moduleName = project && project.moduleName ? project.moduleName : "";
          const char * compilerName = (compiler && compiler.name) ? compiler.name : defaultCompilerName;
          const char * targetPlatformName = compiler && compiler.targetPlatform ? compiler.targetPlatform : "";
          char buffer[MAX_LOCATION];
@@ -61,6 +61,7 @@ class DirExpression : struct
             if(expr[c] == '$' && c < len - 1 && expr[c + 1] == '(')
             {
                int i;
+               bool matched = false;
                for(i = c + 2; i < len; i++)
                {
                   if(expr[i] == ')')
@@ -75,6 +76,7 @@ class DirExpression : struct
                            CamelCase(&buffer[d]);
                            d += strlen(configName);
                            c = i;
+                           matched = true;
                         }
                         else if(!strnicmp(&expr[c + 2], "Module", n) || !strnicmp(&expr[c + 2], "Project", n))
                         {
@@ -83,6 +85,7 @@ class DirExpression : struct
                            //CamelCase(&buffer[d]);
                            d += strlen(moduleName);
                            c = i;
+                           matched = true;
                         }
                         else if(!strnicmp(&expr[c + 2], "Platform", n))
                         {
@@ -91,6 +94,7 @@ class DirExpression : struct
                            CamelCase(&buffer[d]);
                            d += strlen(targetPlatformName);
                            c = i;
+                           matched = true;
                         }
                         else if(!strnicmp(&expr[c + 2], "Compiler", n))
                         {
@@ -99,11 +103,13 @@ class DirExpression : struct
                            CamelCase(&buffer[d]);
                            d += strlen(compilerName);
                            c = i;
+                           matched = true;
                         }
                         else if(!strnicmp(&expr[c + 2], "Debug_Suffix", n))
                         {
                            // We don't support .debug from the IDE yet...
                            c = i;
+                           matched = true;
                         }
                         else if(!strnicmp(&expr[c + 2], "Compiler_Suffix", n))
                         {
@@ -129,11 +135,25 @@ class DirExpression : struct
                               }
                            }
                            c = i;
+                           matched = true;
                         }
-                        else
+                        else if(compiler && compiler.environmentVars && compiler.environmentVars.count)
                         {
-                           buffer[d++] = expr[c];
+                           for(ev : compiler.environmentVars;
+                                 ev.name && ev.string && ev.name[0] && ev.string[0] && !strnicmp(&expr[c + 2], ev.name, n) && strlen(ev.name) == n)
+                           {
+                              buffer[d] = '\0';
+                              ChangeCh(ev.string, '\\', '/');
+                              strcat(buffer, ev.string);
+                              ChangeCh(ev.string, '/', '\\');
+                              d += strlen(ev.string);
+                              c = i;
+                              matched = true;
+                              break;
+                           }
                         }
+                        if(!matched)
+                           buffer[d++] = expr[c];
                      }
                      else
                      {
index 9495d5e..c92c695 100644 (file)
@@ -529,13 +529,14 @@ private:
       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 +568,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;
@@ -1129,13 +1133,13 @@ private:
       return result;
    }
 
-   ProjectNode FindByObjectFileName(const 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;
       }
@@ -1143,11 +1147,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;
@@ -1570,7 +1574,7 @@ 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;
@@ -2060,10 +2064,11 @@ 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)");
             else if(!strcmpi(extension, "rc"))
@@ -2077,7 +2082,8 @@ private:
                GenMakePrintNodeFlagsVariable(this, nodeCFlagsMapping, "PRJ_CFLAGS", f);
 
                if(!strcmpi(extension, "ec"))
-                  f.Printf(" $(FVISIBILITY) -c $(call quote_path,$(OBJ)%s.c) -o $(call quote_path,$@)\n", moduleName);
+                  f.Printf(" $(FVISIBILITY) -c $(call quote_path,$(OBJ)%s.c) -o $(call quote_path,$@)\n",
+                        moduleName);
                else
                   f.Printf(" -c $(call quote_path,%s%s.%s) -o $(call quote_path,$@)\n",
                         modulePath, moduleName, !strcmpi(extension, "ec") ? "c" : extension);
@@ -2351,7 +2357,6 @@ private:
                nodeECFlagsMapping[(intptr)this] = nodeECFlagsMapping[(intptr)parent];
             }
          }
-
       }
       if(files)
       {
@@ -2406,7 +2411,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)
@@ -2461,7 +2466,8 @@ private:
                strcat(moduleName, ".");
                strcat(moduleName, extension);
             }
-            strcat(moduleName, ".o");
+            strcat(moduleName, ".");
+            strcat(moduleName, objectFileExt);
             output.concat(moduleName);
             output.concat("\"");
          }
@@ -2497,7 +2503,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);
          }
       }
    }
@@ -2507,6 +2513,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];
@@ -2538,9 +2545,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;
index 9d758f0..626654d 100644 (file)
@@ -737,7 +737,7 @@ class ProjectView : Window
             //logBox.Logf("%s\n", makefileName);
             logBox.Logf($"%s - %s%smakefile for %s config...\n", makefileName, reason, action, GetConfigName(config));
 
-            if(!project.GenerateMakefile(null, false, null, config))
+            if(!project.GenerateMakefile(null, false, null, config, compiler.ldCommand))
                ide.outputView.buildBox.Logf($"Error generating makefile (Is the project directory writable?)\n");
 
             ide.statusBar.text = null;
@@ -1611,7 +1611,7 @@ class ProjectView : Window
       return result;
    }
 
-   void GoToError(const char * line, const bool noParsing)
+   void GoToError(const char * line, const bool noParsing, const char * objectFileExt)
    {
       char * colon;
 
@@ -1764,7 +1764,7 @@ class ProjectView : Window
                         for(prj : ide.workspace.projects; prj.lastBuildConfigName)
                         {
                            if((config = prj.GetConfig(prj.lastBuildConfigName)))
-                              node = prj.FindNodeByObjectFileName(moduleName, type, dotMain, config);
+                              node = prj.FindNodeByObjectFileName(moduleName, type, dotMain, config, objectFileExt);
                            if(node)
                               break;
                         }
@@ -1777,10 +1777,11 @@ class ProjectView : Window
                         if(compiler)
                         {
                            int bitDepth = ide.workspace.bitDepth;
+                           const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt;
                            DirExpression objDir = project.GetObjDir(compiler, config, bitDepth);
                            strcpy(filePath, project.topNode.path);
                            PathCatSlash(filePath, objDir.dir);
-                           node.GetObjectFileName(name, project.configsNameCollisions[config ? config.name : ""], type, dotMain);
+                           node.GetObjectFileName(name, project.configsNameCollisions[config ? config.name : ""], type, dotMain, objectFileExt);
                            PathCatSlash(filePath, name);
                            delete objDir;
                         }
@@ -1798,7 +1799,7 @@ class ProjectView : Window
             {
                CodeEditor codeEditor = null;
 
-               if(ide.GoToCodeSelectFile(moduleName, null, project, null, filePath))
+               if(ide.GoToCodeSelectFile(moduleName, null, project, null, filePath, objectFileExt))
                {
                   codeEditor = (CodeEditor)ide.OpenFile(filePath, false, true, null, no, normal, noParsing);
                }
index 41bf369..6f126a0 100644 (file)
@@ -467,7 +467,7 @@ public:
       return nodes;
    }
 
-   Project GetFileOwner(const char * absolutePath)
+   Project GetFileOwner(const char * absolutePath, const char * objectFileExt)
    {
       Project owner = null;
       for(prj : projects)
@@ -479,13 +479,13 @@ public:
          }
       }
       if(!owner)
-         GetObjectFileNode(absolutePath, &owner, null);
+         GetObjectFileNode(absolutePath, &owner, null, objectFileExt);
       return owner;
    }
 
-   void GetRelativePath(const char * absolutePath, char * relativePath, Project * owner)
+   void GetRelativePath(const char * absolutePath, char * relativePath, Project * owner, const char * objectFileExt)
    {
-      Project prj = GetFileOwner(absolutePath);
+      Project prj = GetFileOwner(absolutePath, objectFileExt);
       if(owner)
          *owner = prj;
       if(!prj)
@@ -499,7 +499,7 @@ public:
          relativePath[0] = '\0';
    }
 
-   ProjectNode GetObjectFileNode(const char * filePath, Project * project, char * fullPath)
+   ProjectNode GetObjectFileNode(const char * filePath, Project * project, char * fullPath, const char * objectFileExt)
    {
       ProjectNode node = null;
       char ext[MAX_EXTENSION];
@@ -516,7 +516,7 @@ public:
                DotMain dotMain = DotMain::FromFileName(fileName);
                for(prj : ide.workspace.projects)
                {
-                  if((node = prj.FindNodeByObjectFileName(fileName, type, dotMain, null)))
+                  if((node = prj.FindNodeByObjectFileName(fileName, type, dotMain, null, objectFileExt)))
                   {
                      if(project)
                         *project = prj;
@@ -528,7 +528,7 @@ public:
                         DirExpression objDir = prj.GetObjDir(compiler, prj.config, bitDepth);
                         strcpy(fullPath, prj.topNode.path);
                         PathCatSlash(fullPath, objDir.dir);
-                        node.GetObjectFileName(name, prj.configsNameCollisions[cfgName], type, dotMain);
+                        node.GetObjectFileName(name, prj.configsNameCollisions[cfgName], type, dotMain, objectFileExt);
                         PathCatSlash(fullPath, name);
                         delete objDir;
                         delete compiler;