buildsystem, ide; added install feature. aka install library or executable from ide...
authorRejean Loyer <rejean.loyer@gmail.com>
Tue, 2 Apr 2013 14:10:08 +0000 (10:10 -0400)
committerJerome St-Louis <jerome@ecere.com>
Fri, 9 Aug 2013 07:45:51 +0000 (03:45 -0400)
ide/Makefile
ide/ide.epj
ide/res/status/software-update-available.png [new file with mode: 0755]
ide/src/ProjectSettings.ec
ide/src/ide.ec
ide/src/project/Project.ec
ide/src/project/ProjectConfig.ec
ide/src/project/ProjectNode.ec
ide/src/project/ProjectView.ec

index a11f05f..78de81a 100644 (file)
@@ -159,6 +159,7 @@ RESOURCES1 = \
        $(RES)codeMarks/topFrameHalf.png \
        $(RES)codeMarks/topFrameHalfError.png \
        $(RES)others/mousePointer.png \
+       $(RES)status/software-update-available.png \
        locale/zh_CN/LC_MESSAGES/ide.mo \
        locale/es_ES/LC_MESSAGES/ide.mo \
        ../LICENSE \
@@ -261,6 +262,7 @@ endif
        $(EAR) aw$(EARFLAGS) $(TARGET) $(RES)actions/restart.png $(RES)actions/run.png $(RES)actions/skipBreaks.png $(RES)actions/stepInto.png $(RES)actions/stepOut.png $(RES)actions/stepOver.png $(RES)actions/stopDebug.png "actions"
        $(EAR) aw$(EARFLAGS) $(TARGET) $(RES)codeMarks/breakpoint.png $(RES)codeMarks/breakpointDisabled.png $(RES)codeMarks/breakpointHalf.png $(RES)codeMarks/breakpointHalfDisabled.png $(RES)codeMarks/cursor.png $(RES)codeMarks/cursorError.png $(RES)codeMarks/topFrame.png $(RES)codeMarks/topFrameError.png $(RES)codeMarks/topFrameHalf.png $(RES)codeMarks/topFrameHalfError.png "codeMarks"
        $(EAR) aw$(EARFLAGS) $(TARGET) $(RES)others/mousePointer.png "others"
+       $(EAR) aw$(EARFLAGS) $(TARGET) $(RES)status/software-update-available.png "status"
        $(EAR) aw$(EARFLAGS) $(TARGET) locale/zh_CN/LC_MESSAGES/ide.mo "locale/zh_CN/LC_MESSAGES"
        $(EAR) aw$(EARFLAGS) $(TARGET) locale/es_ES/LC_MESSAGES/ide.mo "locale/es_ES/LC_MESSAGES"
        $(EAR) aw$(EARFLAGS) $(TARGET) ../LICENSE ../extras/res/licenses/png.LICENSE ../extras/res/licenses/tango.COPYING ../extras/res/licenses/zlib.README ../extras/res/licenses/sqlite.LICENSE ../extras/res/licenses/jpg.LICENSE ../extras/res/licenses/ungif.LICENSE ../extras/res/licenses/freetype.LICENSE ../extras/res/licenses/harfbuzz.LICENSE ../extras/res/licenses/upx.LICENSE "licenses"
index 8da7be0..52058bd 100644 (file)
          ]
       },
       {
+         "Folder" : "status",
+         "Files" : [
+            "software-update-available.png"
+         ]
+      },
+      {
          "Folder" : "locale",
          "Files" : [
             {
diff --git a/ide/res/status/software-update-available.png b/ide/res/status/software-update-available.png
new file mode 100755 (executable)
index 0000000..ab8d494
Binary files /dev/null and b/ide/res/status/software-update-available.png differ
index 5c8560c..223f53f 100644 (file)
@@ -2227,17 +2227,24 @@ class BuilderTab : Tab
    Label labelPrebuildCommands { prebuildCommands.editor, labeledWindow = prebuildCommands, position = { 0, 6 }; };
    StringsArrayOptionBox prebuildCommands
    {
-      this, size = { 290, 100 }, anchor = { left = 8, top = 8, right = 8, bottom = 0.5 };
+      this, size = { 290, 100 }, anchor = { left = 8, top = 8, right = 8, bottom = 0.66 };
       text = $"Pre-build Commands", hotKey = altE, option = OPTION(prebuildCommands);
    };
 
    Label labelPostbuildCommands { postbuildCommands.editor, labeledWindow = postbuildCommands, position = { 0, 6 }; };
    StringsArrayOptionBox postbuildCommands
    {
-      this, size = { 290 }, anchor = { left = 8, top = 0.5, right = 8, bottom = 8 };
+      this, size = { 290 }, anchor = { left = 8, top = 0.33, right = 8, bottom = 0.33 };
       text = $"Post-build Commands", hotKey = altT, option = OPTION(postbuildCommands);
    };
 
+   Label labelInstallCommands { installCommands.editor, labeledWindow = installCommands, position = { 0, 6 }; };
+   StringsArrayOptionBox installCommands
+   {
+      this, size = { 290 }, anchor = { left = 8, top = 0.66, right = 8, bottom = 8 };
+      text = $"Install Commands", hotKey = altT, option = OPTION(installCommands);
+   };
+
    void LoadSettings()
    {
       bool disabled = strlen(((BuildTab)master).selectedPlatformName) > 0;
index 2e9cc4b..d0a46c6 100644 (file)
@@ -246,6 +246,9 @@ class IDEToolbar : ToolBar
    // Compile actual file
    // Execute
    ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem), disabled = true; };
+#ifdef IDE_SHOW_INSTALL_MENU_BUTTON
+   ToolButton buttonInstall { this, toolTip = $"Install", menuItemPtr = IDEItem(projectInstallItem), disabled = true; };
+#endif
 
    ToolSeparator separator4 { this };
 
@@ -1043,6 +1046,19 @@ class IDEWorkSpace : Window
             return true;
          }
       }
+      MenuItem projectInstallItem
+      {
+#ifdef IDE_SHOW_INSTALL_MENU_BUTTON
+         projectMenu, $"Install", t, disabled = true;
+#endif
+         bitmap = { ":status/software-update-available.png" };
+         bool NotifySelect(MenuItem selection, Modifiers mods)
+         {
+            if(projectView)
+               projectView.ProjectInstall(projectView.active ? selection : null, mods);
+            return true;
+         }
+      }
       MenuItem projectCompileItem;
    Menu debugMenu { menu, $"Debug", d, hasMargin = true };
       MenuItem debugStartResumeItem
@@ -1865,6 +1881,10 @@ class IDEWorkSpace : Window
       // toolBar.buttonRealClean.disabled          = unavailable;
       projectRegenerateItem.disabled            = unavailable;
       toolBar.buttonRegenerateMakefile.disabled = unavailable;
+#ifdef IDE_SHOW_INSTALL_MENU_BUTTON
+      projectInstallItem.disabled               = unavailable;
+      toolBar.buttonInstall.disabled            = unavailable;
+#endif
       projectCompileItem.disabled               = unavailable;
 
       AdjustPopupBuildMenus();
@@ -1891,6 +1911,7 @@ class IDEWorkSpace : Window
          menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectClean, 0);             if(menu) menu.disabled = unavailable;
          menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRealClean, 0);         if(menu) menu.disabled = unavailable;
          menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRegenerate, 0);        if(menu) menu.disabled = unavailable;
+         menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectInstall, 0);           if(menu) menu.disabled = unavailable;
          menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRemove, 0);            if(menu) menu.disabled = unavailable;
          menu = projectView.popupMenu.menu.FindItem(ProjectView::FileClean, 0);                if(menu) menu.disabled = unavailable;
          menu = projectView.popupMenu.menu.FindItem(ProjectView::FileCompile, 0);              if(menu) menu.disabled = unavailable;
index b24fffc..044a05d 100644 (file)
@@ -1517,7 +1517,7 @@ private:
       return !ide.projectView.stopBuild;
    }
 
-   bool ProcessBuildPipeOutput(DualPipe f, DirExpression objDirExp, bool isARun, List<ProjectNode> onlyNodes,
+   bool ProcessBuildPipeOutput(DualPipe f, DirExpression objDirExp, BuildType buildType, List<ProjectNode> onlyNodes,
       CompilerConfig compiler, ProjectConfig config, int bitDepth)
    {
       char line[65536];
@@ -1948,14 +1948,14 @@ private:
          ide.outputView.buildBox.Logf($"\nBuild cancelled by user.\n", line);
          f.Terminate();
       }
-      else if(loggedALine || !isARun)
+      else if(loggedALine || buildType != run)
       {
          if(f.GetExitCode() && !numErrors)
          {
             bool result = f.GetLine(line, sizeof(line)-1);
             ide.outputView.buildBox.Logf($"Fatal Error: child process terminated unexpectedly\n");
          }
-         else
+         else if(buildType != install)
          {
             if(!onlyNodes)
             {
@@ -2027,7 +2027,7 @@ private:
       }
    }
 
-   bool Build(bool isARun, List<ProjectNode> onlyNodes, CompilerConfig compiler, ProjectConfig config, int bitDepth, bool justPrint, SingleFileCompileMode mode)
+   bool Build(BuildType buildType, List<ProjectNode> onlyNodes, CompilerConfig compiler, ProjectConfig config, int bitDepth, bool justPrint, SingleFileCompileMode mode)
    {
       bool result = false;
       DualPipe f;
@@ -2065,7 +2065,9 @@ private:
       PathCatSlash(makeFilePath, makeFile);
 
       // TODO: TEST ON UNIX IF \" around makeTarget is ok
-      if(onlyNodes)
+      if(buildType == install)
+         makeTargets.concat(" install");
+      else if(onlyNodes)
       {
          if(compiler.type.isVC)
          {
@@ -2138,7 +2140,12 @@ private:
       {
          char cfDir[MAX_LOCATION];
          GetIDECompilerConfigsDir(cfDir, true, true);
-         sprintf(command, "%s %sCF_DIR=\"%s\"%s%s%s%s%s COMPILER=%s %s-j%d %s%s%s -C \"%s\"%s -f \"%s\"",
+         sprintf(command, "%s%s %sCF_DIR=\"%s\"%s%s%s%s%s COMPILER=%s %s-j%d %s%s%s -C \"%s\"%s -f \"%s\"",
+#if defined(__WIN32__)
+               "",
+#else
+               buildType == install ? "pkexec --user root " : "",
+#endif
                compiler.makeCommand,
                mode == debugPrecompile ? "ECP_DEBUG=y " : mode == debugCompile ? "ECC_DEBUG=y " : mode == debugGenerateSymbols ? "ECS_DEBUG=y " : "",
                cfDir,
@@ -2191,7 +2198,7 @@ private:
             else if(justPrint)
                result = ProcessPipeOutputRaw(f);
             else
-               result = ProcessBuildPipeOutput(f, objDirExp, isARun, onlyNodes, compiler, config, bitDepth);
+               result = ProcessBuildPipeOutput(f, objDirExp, buildType, onlyNodes, compiler, config, bitDepth);
             delete f;
             if(error)
                ide.outputView.buildBox.Logf("%s\n", command);
@@ -2333,7 +2340,7 @@ private:
 
    bool Compile(List<ProjectNode> nodes, CompilerConfig compiler, ProjectConfig config, int bitDepth, bool justPrint, SingleFileCompileMode mode)
    {
-      return Build(false, nodes, compiler, config, bitDepth, justPrint, mode);
+      return Build(build, nodes, compiler, config, bitDepth, justPrint, mode);
    }
 #endif
 
@@ -3344,6 +3351,74 @@ private:
          }
          f.Puts("\n");
 
+         test = false;
+         if(platforms || (config && config.platforms))
+         {
+            for(platform = (Platform)1; platform < Platform::enumSize; platform++)
+            {
+               PlatformOptions projectPOs, configPOs;
+               MatchProjectAndConfigPlatformOptions(config, platform, &projectPOs, &configPOs);
+
+               if((projectPOs && projectPOs.options.installCommands && projectPOs.options.installCommands.count) ||
+                     (configPOs && configPOs.options.installCommands && configPOs.options.installCommands.count))
+               {
+                  test = true;
+                  break;
+               }
+            }
+         }
+         if(test || (options && options.installCommands) ||
+               (config && config.options && config.options.installCommands))
+         {
+            f.Puts("install:\n");
+            if(options && options.installCommands)
+            {
+               for(s : options.installCommands)
+                  if(s && s[0]) f.Printf("\t%s\n", s);
+            }
+            if(config && config.options && config.options.installCommands)
+            {
+               for(s : config.options.installCommands)
+                  if(s && s[0]) f.Printf("\t%s\n", s);
+            }
+            if(platforms || (config && config.platforms))
+            {
+               ifCount = 0;
+               for(platform = (Platform)1; platform < Platform::enumSize; platform++)
+               {
+                  PlatformOptions projectPOs, configPOs;
+                  MatchProjectAndConfigPlatformOptions(config, platform, &projectPOs, &configPOs);
+
+                  if((projectPOs && projectPOs.options.installCommands && projectPOs.options.installCommands.count) ||
+                        (configPOs && configPOs.options.installCommands && configPOs.options.installCommands.count))
+                  {
+                     if(ifCount)
+                        f.Puts("else\n");
+                     ifCount++;
+                     f.Printf("ifdef %s\n", PlatformToMakefileTargetVariable(platform));
+
+                     if(projectPOs && projectPOs.options.installCommands && projectPOs.options.installCommands.count)
+                     {
+                        for(s : projectPOs.options.installCommands)
+                           if(s && s[0]) f.Printf("\t%s\n", s);
+                     }
+                     if(configPOs && configPOs.options.installCommands && configPOs.options.installCommands.count)
+                     {
+                        for(s : configPOs.options.installCommands)
+                           if(s && s[0]) f.Printf("\t%s\n", s);
+                     }
+                  }
+               }
+               if(ifCount)
+               {
+                  int c;
+                  for(c = 0; c < ifCount; c++)
+                     f.Puts("endif\n");
+               }
+            }
+            f.Puts("\n");
+         }
+
          f.Puts("# SYMBOL RULES\n");
          f.Puts("\n");
 
index 0a5ae5e..b393677 100644 (file)
@@ -332,6 +332,27 @@ public:
       get { return postbuildCommands; }
       isset { return  postbuildCommands && postbuildCommands.count; }
    }
+   property Array<String> installCommands
+   {
+      set
+      {
+         if(installCommands)
+            installCommands.Free();
+         if(value && value.count)
+         {
+            if(!installCommands)
+               installCommands = { };
+            for(s : value)
+               installCommands.Add(CopyValidateMakefilePath(s));
+            value.Free();
+            delete value;
+         }
+         else
+            delete installCommands;
+      }
+      get { return installCommands; }
+      isset { return  installCommands && installCommands.count; }
+   }
 
    ProjectOptions Copy()
    {
@@ -361,7 +382,8 @@ public:
          linkerOptions = CopyArrayString(linkerOptions),
          libraryDirs = CopyArrayString(libraryDirs),
          prebuildCommands = CopyArrayString(prebuildCommands),
-         postbuildCommands = CopyArrayString(postbuildCommands)
+         postbuildCommands = CopyArrayString(postbuildCommands),
+         installCommands = CopyArrayString(installCommands)
       };
    }
 
@@ -406,6 +428,7 @@ public:
       if(libraryDirs) { libraryDirs.Free(); delete libraryDirs; }
       if(prebuildCommands) { prebuildCommands.Free(); delete prebuildCommands; }
       if(postbuildCommands) { postbuildCommands.Free(); delete postbuildCommands; }
+      if(installCommands) { installCommands.Free(); delete installCommands; }
    }
 private:
    Array<String> includeDirs;
@@ -415,6 +438,7 @@ private:
    Array<String> libraryDirs;
    Array<String> prebuildCommands;
    Array<String> postbuildCommands;
+   Array<String> installCommands;
 
    property bool isEmpty
    {
@@ -443,7 +467,8 @@ private:
             excludeFromBuild == unset &&
             fastMath == unset &&
             (!prebuildCommands || !prebuildCommands.count) &&
-            (!postbuildCommands || !postbuildCommands.count) )
+            (!postbuildCommands || !postbuildCommands.count) &&
+            (!installCommands || !installCommands.count))
             return true;
          return false;          
       }
index 97b4583..ffc3606 100644 (file)
@@ -2570,9 +2570,10 @@ static ProjectOptions BlendFileConfigPlatformProjectOptions(ProjectNode node, Pr
    ProjectNode n;
    char * platformName = platform ? platform.OnGetString(0,0,0) : null;
 
-   Array<bool> optionConfigXplatformSet   { size = OPTION(postbuildCommands) };
-   Array<bool> optionDone                 { size = OPTION(postbuildCommands) };
-   Array<Array<String>> optionTempStrings { size = OPTION(postbuildCommands) };
+   // OPTION(ProjectOptions' last member) for size
+   Array<bool> optionConfigXplatformSet   { size = OPTION(installCommands) };
+   Array<bool> optionDone                 { size = OPTION(installCommands) };
+   Array<Array<String>> optionTempStrings { size = OPTION(installCommands) };
 
    GenericOptionTools<SetBool>              utilSetBool {
       bool OptionCheck(ProjectOptions options, int option) {
index fc3d7ba..13390d5 100644 (file)
@@ -95,7 +95,7 @@ static char * iconNames[] =
 enum PrepareMakefileMethod { normal, force, forceExists };
 
 enum CleanType { clean, realClean, cleanTarget };
-enum BuildType { build, rebuild, relink, run, start, restart, clean };
+enum BuildType { build, rebuild, relink, run, start, restart, clean, install };
 enum BuildState
 {
    none, buildingMainProject, buildingSecondaryProject, compilingFile;
@@ -215,7 +215,11 @@ class ProjectView : Window
          if(row)
          {
             bool showDebuggingMenuItems = mods.ctrl && mods.shift;
+            bool showInstallMenuItem = mods.ctrl && mods.shift;
             ProjectNode node = (ProjectNode)row.tag;
+#ifdef IDE_SHOW_INSTALL_MENU_BUTTON
+            showInstallMenuItem = true;
+#endif
             if(node.type == NodeTypes::project || node.type == resources || node.type == file || node.type == folder)
             {
                bool na = buildInProgress; // N/A - buildMenuUnavailable
@@ -232,7 +236,11 @@ class ProjectView : Window
                   MenuItem { pop, $"Clean"              , c         , NotifySelect = ProjectClean      , bitmap = mi.bitmap }.disabled = na; mi = ide.projectRealCleanItem;
                   MenuItem { pop, $"Real Clean"                     , NotifySelect = ProjectRealClean  , bitmap = mi.bitmap }.disabled = na; mi = ide.projectRegenerateItem;
                   MenuItem { pop, $"Regenerate Makefile", m         , NotifySelect = ProjectRegenerate , bitmap = mi.bitmap }.disabled = na;
-
+                  if(showInstallMenuItem)
+                  {
+                     mi = ide.projectInstallItem;
+                     MenuItem { pop, $"Install"            , t         , NotifySelect = ProjectInstall    , bitmap = mi.bitmap }.disabled = na;
+                  }
                   if(showDebuggingMenuItems && node.ContainsFilesWithExtension("ec"))
                   {
                      MenuDivider { pop };
@@ -797,7 +805,7 @@ class ProjectView : Window
          ide.AdjustBuildMenus();
          ide.AdjustDebugMenus();
 
-         result = prj.Build(buildType == run, null, compiler, config, bitDepth, justPrint, normal);
+         result = prj.Build(buildType, null, compiler, config, bitDepth, justPrint, normal);
 
          if(config)
          {
@@ -858,6 +866,39 @@ class ProjectView : Window
       return true;
    }
 
+   bool ProjectInstall(MenuItem selection, Modifiers mods)
+   {
+      Project prj = project;
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      int bitDepth = ide.workspace.bitDepth;
+      ProjectConfig config;
+      if(selection || !ide.activeClient)
+      {
+         DataRow row = fileList.currentRow;
+         ProjectNode node = row ? (ProjectNode)row.tag : null;
+         if(node) prj = node.project;
+      }
+      else
+      {
+         ProjectNode node = GetNodeFromWindow(ide.activeClient, null, false);
+         if(node)
+            prj = node.project;
+      }
+      config = prj.config;
+      if(!prj.GetConfigIsInDebugSession(config) ||
+            (!ide.DontTerminateDebugSession($"Project Install") && DebugStopForMake(prj, relink, compiler, config)))
+      {
+         BuildInterrim(prj, build, compiler, config, bitDepth, mods.ctrl && mods.shift);
+         if(ProjectPrepareForToolchain(prj, normal, false, false, compiler, config))
+         {
+            ide.outputView.buildBox.Logf($"\nInstalling project %s using the %s configuration...\n", prj.name, GetConfigName(config));
+            Build(prj, install, compiler, config, bitDepth, mods.ctrl && mods.shift);
+         }
+      }
+      delete compiler;
+      return true;
+   }
+
    bool ProjectLink(MenuItem selection, Modifiers mods)
    {
       Project prj = project;