Author Topic: Adding a target type for embedded development?  (Read 17900 times)

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Adding a target type for embedded development?
« on: May 20, 2014, 05:57:33 pm »
Hi,

I'm looking into using Code::Blocks as an IDE to use with the homebrew toolchains I produce @ devkitpro.org - thinking about distributing a kind of "lite" version with the tools (reducing compiler set to just devkitARM, devkitPPC & devkitPSP & removing unrelated wizards & templates).

The binaries produced need to be run on the game consoles or via emulators - I can make the run button work by abusing the Dynamic Library target and setting a host application (either to suitable emulator or an application that sends the binary to the game console in question) but getting the debug button to work is a little more awkward. The IDE needs to launch an emulator with gdb support or an application that sends the binary to the game console and sets up a gdb proxy then launch gdb with the matching elf file. Currently I've managed to patch Code::Blocks with an "Embedded Application" target which just operates in the same way as the Dynamic Library target for run and replaces the extension on the output file with .elf for sending to gdb.

Here's the patch I have so far :-
Code
diff --git a/src/include/compiletargetbase.h b/src/include/compiletargetbase.h
index 3d09dfd..a6b255d 100644
--- a/src/include/compiletargetbase.h
+++ b/src/include/compiletargetbase.h
@@ -37,7 +37,8 @@ enum TargetType
     ttStaticLib     = 2, /**< Target produces a static library */
     ttDynamicLib    = 3, /**< Target produces a dynamic library */
     ttCommandsOnly  = 4, /**< Target only runs commands in pre-build and/or post-build steps */
-    ttNative        = 5  /**< Target produces a native binary */
+    ttNative        = 5, /**< Target produces a native binary */
+    ttEmbedded      = 6, /**< Target produces an Embedded binary */
 };
 
 enum MakeCommand
diff --git a/src/plugins/compilergcc/compilergcc.cpp b/src/plugins/compilergcc/compilergcc.cpp
index 3e82e3b..4d531f3 100644
--- a/src/plugins/compilergcc/compilergcc.cpp
+++ b/src/plugins/compilergcc/compilergcc.cpp
@@ -1902,7 +1902,8 @@ int CompilerGCC::Run(ProjectBuildTarget* target)
     }
 
     if (   target->GetTargetType() == ttDynamicLib
-        || target->GetTargetType() == ttStaticLib )
+        || target->GetTargetType() == ttStaticLib
+        || target->GetTargetType() == ttEmbedded )
     {
         // check for hostapp
         if (target->GetHostApplication().IsEmpty())
diff --git a/src/sdk/cbplugin.cpp b/src/sdk/cbplugin.cpp
index eb20772..f656de1 100644
--- a/src/sdk/cbplugin.cpp
+++ b/src/sdk/cbplugin.cpp
@@ -648,6 +648,24 @@ bool cbDebuggerPlugin::GetDebuggee(wxString &pathToDebuggee, wxString &workingDi
             }
             break;
 
+        case ttEmbedded:
+            {
+                if (target->GetHostApplication().IsEmpty())
+                {
+                    cbMessageBox(_("You must select a host application to \"run\" an Embedded Application..."));
+                    return false;
+                }
+                out = UnixFilename(target->GetOutputFilename());
+                Manager::Get()->GetMacrosManager()->ReplaceEnvVars(out); // apply env vars
+                wxFileName f(out);
+                f.MakeAbsolute(target->GetParentProject()->GetBasePath());
+                f.SetExt(_T("elf"));
+                out = f.GetFullPath();
+                Log(_("Adding file: ") + out);
+                ConvertDirectory(out);
+            }
+            break;
+
         case ttStaticLib:
         case ttDynamicLib:
             // check for hostapp
diff --git a/src/sdk/compiletargetbase.cpp b/src/sdk/compiletargetbase.cpp
index 4debe3a..6ce6fc3 100644
--- a/src/sdk/compiletargetbase.cpp
+++ b/src/sdk/compiletargetbase.cpp
@@ -177,7 +177,8 @@ wxString CompileTargetBase::SuggestOutputFilename()
         case ttExecutable:   suggestion = GetExecutableFilename(); break;
         case ttDynamicLib:   suggestion = GetDynamicLibFilename(); break;
         case ttStaticLib:    suggestion = GetStaticLibFilename();  break;
-        case ttNative:       suggestion = GetNativeFilename();     break;
+        case ttNative:      // fall through
+        case ttEmbedded:     suggestion = GetNativeFilename();     break;
         case ttCommandsOnly: // fall through
         default:
             suggestion.Clear();
@@ -279,6 +280,7 @@ void CompileTargetBase::GenerateTargetFilename(wxString& filename) const
             break;
         }
         case ttNative:
+        case ttEmbedded:
         {
             if (m_ExtensionGenerationPolicy == tgfpPlatformDefault)
                 filename << fname.GetName() << FileFilters::NATIVE_DOT_EXT;
@@ -355,7 +357,7 @@ wxString CompileTargetBase::GetNativeFilename()
 
     wxFileName fname(m_Filename);
     fname.SetName(fname.GetName());
-    fname.SetExt(FileFilters::NATIVE_EXT);
+    if (m_TargetType == ttNative) fname.SetExt(FileFilters::NATIVE_EXT);
     return fname.GetFullPath();
 }
 
diff --git a/src/sdk/scripting/bindings/sc_consts.cpp b/src/sdk/scripting/bindings/sc_consts.cpp
index 2b40563..71e2651 100644
--- a/src/sdk/scripting/bindings/sc_consts.cpp
+++ b/src/sdk/scripting/bindings/sc_consts.cpp
@@ -114,6 +114,7 @@ namespace ScriptBindings
         BIND_INT_CONSTANT(ttDynamicLib);
         BIND_INT_CONSTANT(ttCommandsOnly);
         BIND_INT_CONSTANT(ttNative);
+        BIND_INT_CONSTANT(ttEmbedded);
 
         // MakeCommand
         BIND_INT_CONSTANT(mcClean);
diff --git a/src/src/projectoptionsdlg.cpp b/src/src/projectoptionsdlg.cpp
index 6f11d07..3c4ba6f 100644
--- a/src/src/projectoptionsdlg.cpp
+++ b/src/src/projectoptionsdlg.cpp
@@ -274,6 +274,7 @@ void ProjectOptionsDlg::DoTargetChange(bool saveOld)
             case ttExecutable:
             case ttDynamicLib:
             case ttNative:
+            case ttEmbedded:
             case ttStaticLib:
                 txt->SetValue(target->GetOutputFilename());
                 txt->Enable(true);
@@ -285,6 +286,7 @@ void ProjectOptionsDlg::DoTargetChange(bool saveOld)
                 txtW->Enable((TargetType)cmb->GetSelection() == ttExecutable ||
                             (TargetType)cmb->GetSelection() == ttConsoleOnly ||
                             (TargetType)cmb->GetSelection() == ttNative ||
+                            (TargetType)cmb->GetSelection() == ttEmbedded ||
                             (TargetType)cmb->GetSelection() == ttDynamicLib);
                 txtO->SetValue(target->GetObjectOutput());
                 txtO->Enable(true);
@@ -294,6 +296,7 @@ void ProjectOptionsDlg::DoTargetChange(bool saveOld)
                 browseW->Enable((TargetType)cmb->GetSelection() == ttExecutable ||
                                 (TargetType)cmb->GetSelection() == ttConsoleOnly ||
                                 (TargetType)cmb->GetSelection() == ttNative ||
+                                (TargetType)cmb->GetSelection() == ttEmbedded ||
                                 (TargetType)cmb->GetSelection() == ttDynamicLib);
                 browseO->Enable(true);
                 break;
@@ -514,6 +517,16 @@ void ProjectOptionsDlg::OnProjectTypeChanged(cb_unused wxCommandEvent& event)
             txtI->SetValue(_T(""));
             txtD->SetValue(_T(""));
             break;
+        case ttEmbedded:
+            if (!libpre.IsEmpty() && name.StartsWith(libpre))
+            {
+                name.Remove(0, libpre.Length());
+                fname.SetName(name);
+            }
+            txt->SetValue(fname.GetFullPath());
+            txtI->SetValue(_T(""));
+            txtD->SetValue(_T(""));
+            break;
         case ttNative:
             if (ext != FileFilters::NATIVE_EXT)
                 fname.SetExt(FileFilters::NATIVE_EXT);
diff --git a/src/src/resources/project_options.xrc b/src/src/resources/project_options.xrc
index c3b2834..e7b8e58 100644
--- a/src/src/resources/project_options.xrc
+++ b/src/src/resources/project_options.xrc
@@ -399,6 +399,7 @@
  <item>Dynamic library</item>
  <item>Commands only</item>
  <item>Native</item>
+ <item>Embedded Application</item>
  </content>
  <style>wxCB_READONLY|wxCB_DROPDOWN</style>
  </object>

With just this patch I can launch an emulator with debug support manually then hit the debug button & things work as expected. Getting the emulator to launch automatically with the extra parameters to open a gdb port is slightly more involved.

Code
diff --git a/src/include/cbplugin.h b/src/include/cbplugin.h
index 6fe4131..a712a7c 100644
--- a/src/include/cbplugin.h
+++ b/src/include/cbplugin.h
@@ -622,6 +622,7 @@ class PLUGIN_EXPORT cbDebuggerPlugin: public cbPlugin
         void SwitchToPreviousLayout();
 
         bool GetDebuggee(wxString& pathToDebuggee, wxString& workingDirectory, ProjectBuildTarget* target);
+        bool GetHostForDebug(wxString &pathToHostApp, ProjectBuildTarget* target);
         bool EnsureBuildUpToDate(StartType startType);
         bool WaitingCompilerToFinish() const { return m_WaitingCompilerToFinish; }
 
diff --git a/src/include/compiletargetbase.h b/src/include/compiletargetbase.h
index a6b255d..61a5af7 100644
--- a/src/include/compiletargetbase.h
+++ b/src/include/compiletargetbase.h
@@ -140,6 +140,8 @@ class DLLIMPORT CompileTargetBase : public CompileOptionsBase
         virtual void SetExecutionParameters(const wxString& params); ///< Set the target's execution parameters to \c params
         virtual const wxString& GetHostApplication() const; ///< Read the target's host application
         virtual void SetHostApplication(const wxString& app); ///< Set the target's host application to \c app
+        virtual const wxString& GetHostDebugParameters() const; ///< Read the target's host application parameters for debug
+        virtual void SetHostDebugParameters(const wxString& params); ///< Set the target's host application parameters for debug to \c params
         virtual bool GetRunHostApplicationInTerminal() const; ///< Get the flag if the host app should be run in terminal
         virtual void SetRunHostApplicationInTerminal(bool in_terminal); ///! Set the flag if the host app should be run in terminal
         virtual void SetCompilerID(const wxString& id); ///< Set the target's compiler
@@ -160,6 +162,7 @@ class DLLIMPORT CompileTargetBase : public CompileOptionsBase
         wxString m_DepsOutput;
         wxString m_ExecutionParameters;
         wxString m_HostApplication;
+        wxString m_HostDebugParameters;
         OptionsRelation m_OptionsRelation[ortLast];
         TargetType m_TargetType;
         wxString m_CompilerId;
diff --git a/src/plugins/debuggergdb/debuggergdb.cpp b/src/plugins/debuggergdb/debuggergdb.cpp
index ad3a7ec..eb90a4b 100644
--- a/src/plugins/debuggergdb/debuggergdb.cpp
+++ b/src/plugins/debuggergdb/debuggergdb.cpp
@@ -812,10 +812,29 @@ int DebuggerGDB::DoDebug(bool breakOnEntry)
             }
         }
 
+        if(target->GetTargetType() == ttEmbedded)
+        {
+            wxString hostapp;
+            if (!GetHostForDebug(hostapp,target))
+            {
+                m_Canceled = true;
+                return -3;
+            }
+
+            wxString command;
+
+            command << hostapp << _T(" ") << target->GetExecutionParameters() << _T(" ") << target->GetHostDebugParameters();
+            Manager::Get()->GetMacrosManager()->ReplaceEnvVars(command);
+
+            Log(_T("Host Application: ") + command);
+            wxExecute(command, wxEXEC_ASYNC, NULL);
+        }
+
         if (target && !target->GetExecutionParameters().IsEmpty())
             m_State.GetDriver()->SetArguments(target->GetExecutionParameters());
 
         cmdline = m_State.GetDriver()->GetCommandLine(cmdexe, debuggee, GetActiveConfigEx().GetUserArguments());
+        // start the host application
     }
     else // m_PidToAttach != 0
         cmdline = m_State.GetDriver()->GetCommandLine(cmdexe, m_PidToAttach, GetActiveConfigEx().GetUserArguments());
@@ -863,6 +882,7 @@ int DebuggerGDB::DoDebug(bool breakOnEntry)
             ShowWindow(windowHandle, SW_HIDE);
     }
     #endif
+
     // start the gdb process
     wxString wdir = m_State.GetDriver()->GetDebuggersWorkingDirectory();
     if (wdir.empty())
diff --git a/src/sdk/cbplugin.cpp b/src/sdk/cbplugin.cpp
index 8e39929..3cfa20a 100644
--- a/src/sdk/cbplugin.cpp
+++ b/src/sdk/cbplugin.cpp
@@ -626,6 +626,34 @@ void cbDebuggerPlugin::SwitchToPreviousLayout()
     Manager::Get()->ProcessEvent(switchEvent);
 }
 
+bool cbDebuggerPlugin::GetHostForDebug(wxString &pathToHostApp, ProjectBuildTarget* target)
+{
+    if(!target)
+        return false;
+
+    if (target->GetTargetType() != ttEmbedded)
+        return false;
+
+    if (target->GetHostApplication().IsEmpty())
+        return false;
+
+    wxString out;
+    out = UnixFilename(target->GetHostApplication());
+    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(out); // apply env vars
+    Log(_("Adding file: ") + out);
+    ConvertDirectory(out);
+
+    if (out.empty())
+    {
+        Log(_("Couldn't find the path to the host application!"), Logger::error);
+        return false;
+    }
+
+    pathToHostApp = out;
+
+    return true;
+}
+
 bool cbDebuggerPlugin::GetDebuggee(wxString &pathToDebuggee, wxString &workingDirectory, ProjectBuildTarget* target)
 {
     if (!target)
diff --git a/src/sdk/compiletargetbase.cpp b/src/sdk/compiletargetbase.cpp
index 6ce6fc3..3a6ba5a 100644
--- a/src/sdk/compiletargetbase.cpp
+++ b/src/sdk/compiletargetbase.cpp
@@ -502,6 +502,20 @@ void CompileTargetBase::SetExecutionParameters(const wxString& params)
     SetModified(true);
 }
 
+const wxString& CompileTargetBase::GetHostDebugParameters() const
+{
+    return m_HostDebugParameters;
+}
+
+void CompileTargetBase::SetHostDebugParameters(const wxString& params)
+{
+    if (m_HostDebugParameters == params)
+        return;
+
+    m_HostDebugParameters = params;
+    SetModified(true);
+}
+
 const wxString& CompileTargetBase::GetHostApplication() const
 {
     return m_HostApplication;
diff --git a/src/sdk/projectloader.cpp b/src/sdk/projectloader.cpp
index 8d42065..191d446 100644
--- a/src/sdk/projectloader.cpp
+++ b/src/sdk/projectloader.cpp
@@ -541,6 +541,7 @@ void ProjectLoader::DoBuildTargetOptions(TiXmlElement* parentNode, ProjectBuildT
     wxString compilerId = m_pProject->GetCompilerID();
     wxString parameters;
     wxString hostApplication;
+    wxString hostDebugParameters;
     bool runHostApplicationInTerminal = false;
     bool includeInTargetAll = m_IsPre_1_2 ? true : false;
     bool createStaticLib = false;
@@ -603,6 +604,9 @@ void ProjectLoader::DoBuildTargetOptions(TiXmlElement* parentNode, ProjectBuildT
         if (node->Attribute("host_application"))
             hostApplication = UnixFilename(cbC2U(node->Attribute("host_application")));
 
+        if (node->Attribute("host_application_debug_parameters"))
+            hostDebugParameters = cbC2U(node->Attribute("host_application_debug_parameters"));
+
         if (node->Attribute("run_host_application_in_terminal"))
         {
             wxString runInTerminal = cbC2U(node->Attribute("run_host_application_in_terminal"));
@@ -672,6 +676,7 @@ void ProjectLoader::DoBuildTargetOptions(TiXmlElement* parentNode, ProjectBuildT
         target->SetAdditionalOutputFiles(added);
         target->SetExecutionParameters(parameters);
         target->SetHostApplication(hostApplication);
+        target->SetHostDebugParameters(hostDebugParameters);
         target->SetRunHostApplicationInTerminal(runHostApplicationInTerminal);
         target->SetIncludeInTargetAll(includeInTargetAll); // used in versions prior to 1.5
         target->SetCreateDefFile(createDefFile);
@@ -1368,6 +1373,10 @@ bool ProjectLoader::ExportTargetAsProject(const wxString& filename, const wxStri
                 AddElement(tgtnode, "Option", "run_host_application_in_terminal", 1);
             else
                 AddElement(tgtnode, "Option", "run_host_application_in_terminal", 0);
+            if (!target->GetHostDebugParameters().IsEmpty())
+            {
+                AddElement(tgtnode, "Option", "host_application_debug_parameters", target->GetHostDebugParameters());
+            }
         }
 
         // used in versions prior to 1.5
diff --git a/src/sdk/resources/select_target.xrc b/src/sdk/resources/select_target.xrc
index 6e5afbd..5a13af8 100644
--- a/src/sdk/resources/select_target.xrc
+++ b/src/sdk/resources/select_target.xrc
@@ -87,6 +87,21 @@
         <border>8</border>
       </object>
       <object class="sizeritem">
+        <object class="wxStaticText" name="ID_STATICTEXT3">
+          <label>Host application debug arguments:</label>
+        </object>
+        <flag>wxTOP|wxLEFT|wxALIGN_LEFT|wxALIGN_TOP</flag>
+        <border>8</border>
+      </object>
+      <object class="sizeritem">
+        <object class="wxTextCtrl" name="txtHostDebugParameters">
+          <style>wxTE_MULTILINE</style>
+        </object>
+        <flag>wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP</flag>
+        <border>8</border>
+        <option>1</option>
+      </object>
+      <object class="sizeritem">
         <object class="wxStaticLine" name="ID_STATICLINE1"/>
         <flag>wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP</flag>
         <border>8</border>
diff --git a/src/sdk/selecttargetdlg.cpp b/src/sdk/selecttargetdlg.cpp
index 6b04606..bd2dc84 100644
--- a/src/sdk/selecttargetdlg.cpp
+++ b/src/sdk/selecttargetdlg.cpp
@@ -72,6 +72,7 @@ void SelectTargetDlg::UpdateSelected()
         XRCCTRL(*this, "chkSetAsDefaultExec", wxCheckBox)->SetValue(name == m_pProject->GetDefaultExecuteTarget());
         XRCCTRL(*this, "txtParams", wxTextCtrl)->SetValue(target->GetExecutionParameters());
         XRCCTRL(*this, "txtHostApp", wxTextCtrl)->SetValue(target->GetHostApplication());
+        XRCCTRL(*this, "txtHostDebugParameters", wxTextCtrl)->SetValue(target->GetHostDebugParameters());
         XRCCTRL(*this, "chkHostInTerminal", wxCheckBox)->SetValue(target->GetRunHostApplicationInTerminal());
     }
     XRCCTRL(*this, "wxID_OK", wxButton)->Enable(target);
@@ -153,6 +154,16 @@ void SelectTargetDlg::EndModal(int retCode)
                 execution_parameters[pos] = ' ';
             }
             target->SetExecutionParameters(execution_parameters);
+
+            wxString debug_parameters = XRCCTRL(*this, "txtHostDebugParameters", wxTextCtrl)->GetValue();
+            pos = 0;
+
+            while ((pos = debug_parameters.find('\n', pos)) != wxString::npos)
+            {
+                debug_parameters[pos] = ' ';
+            }
+            target->SetHostDebugParameters(debug_parameters);
+
             target->SetHostApplication(XRCCTRL(*this, "txtHostApp", wxTextCtrl)->GetValue());
             target->SetRunHostApplicationInTerminal(XRCCTRL(*this, "chkHostInTerminal", wxCheckBox)->IsChecked());
         }

Would these patches be acceptable for inclusion in Code::Blocks? It might be a useful feature for others working with embedded targets.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Adding a target type for embedded development?
« Reply #1 on: May 20, 2014, 11:48:05 pm »
As far as I know the Additional shell commands in the projects setting for the debugger are meant for doing just this same thing.
There are reports that they are broken, so this should be checked.
Please give them a try.

As I've told you on IRC, adding more app types is not the best of ideas (it adds more burden to plugin developers to implement more cases).
Increases the chance to miss some of the cases and so on.
I'd prefer not to add new type if possible.

p.s. It would be easier (at least for me) if you start a fork of my repo on github - https://github.com/obfuscated/codeblocks_sf
« Last Edit: May 20, 2014, 11:50:33 pm by oBFusCATed »
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Adding a target type for embedded development?
« Reply #2 on: May 21, 2014, 12:32:57 am »
"Host application debug arguments" sounds pretty bizarre and not that useful.
And it should probably be disabled for non-embedded targets.

Can you post some example screen shots why these changes are useful to you?
What are you entering there and so on?
Probably post some logs from the debugger (enable full logging please).
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Re: Adding a target type for embedded development?
« Reply #3 on: May 21, 2014, 03:06:48 am »
As far as I know the Additional shell commands in the projects setting for the debugger are meant for doing just this same thing.
There are reports that they are broken, so this should be checked.
Please give them a try.

I tried those in the first place but they didn't seem to do anything at all.

Quote
As I've told you on IRC, adding more app types is not the best of ideas (it adds more burden to plugin developers to implement more cases).
Increases the chance to miss some of the cases and so on.
I'd prefer not to add new type if possible.

I can see why. My first attempt at this involved adding a new type for each binary along with additional extensions for them ... then I caught a grip ;)
 
Quote
p.s. It would be easier (at least for me) if you start a fork of my repo on github - https://github.com/obfuscated/codeblocks_sf

Excellent, I was using a git svn clone of the SF repo for this & I found that a bit of a pain to deal with. Thanks for that :)

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Re: Adding a target type for embedded development?
« Reply #4 on: May 21, 2014, 03:42:57 am »
"Host application debug arguments" sounds pretty bizarre and not that useful.

It lets me add arguments to the emulator that open ports for a gdb connection. Could have a less awkward name I admit.



if that --arm9gdb=8000 is added then the emulator will wait for a connection before running the application. Obviously that's a bit useless for the run button.

The other issue was that I need to send a binary to the emulator (in this case it's a container format that includes a file system) but gdb needs the elf to get debug info.
Quote
And it should probably be disabled for non-embedded targets.

Hadn't quite figured out how to do that yet. Any pointers?

Here's the debugger log

Code
Building to ensure sources are up-to-date
Selecting target:
Debug
Adding source dir: C:\Users\davem_000\projects\devkitIDEtest\test\
Adding source dir: C:\Users\davem_000\projects\devkitIDEtest\test\
Adding file: C:\Users\davem_000\projects\devkitIDEtest\test\test-debug.elf
Changing directory to: C:/Users/davem_000/projects/devkitIDEtest/test/
Adding file: C:\Users\davem_000\projects\devkitPro\devkitIDE\src\devel\emulators\desmume\desmume.exe
Host Application: C:/Users/davem_000/projects/devkitPro/devkitIDE/src/devel/emulators/desmume/desmume.exe test-debug.nds --arm9gdb=8000

[debug]Command-line: arm-none-eabi-gdb.exe -nx -fullname  -quiet  -args C:/Users/davem_000/projects/devkitIDEtest/test/test-debug.elf
[debug]Working dir : C:\Users\davem_000\projects\devkitIDEtest\test

Starting debugger: arm-none-eabi-gdb.exe -nx -fullname  -quiet  -args C:/Users/davem_000/projects/devkitIDEtest/test/test-debug.elf
done

[debug]> set prompt >>>>>>cb_gdb:

Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Connecting to remote target
Setting breakpoints

[debug]Reading symbols from C:/Users/davem_000/projects/devkitIDEtest/test/test-debug.elf...done.
[debug](gdb) >>>>>>cb_gdb:
[debug]> show version
[debug]GNU gdb (GDB) 7.7
[debug]Copyright (C) 2014 Free Software Foundation, Inc.
[debug]License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[debug]This is free software: you are free to change and redistribute it.
[debug]There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
[debug]and "show warranty" for details.
[debug]This GDB was configured as "--host=i686-w64-mingw32 --target=arm-none-eabi".
[debug]Type "show configuration" for configuration details.
[debug]For bug reporting instructions, please see:
[debug]<http://www.gnu.org/software/gdb/bugs/>.
[debug]Find the GDB manual and other documentation resources online at:
[debug]<http://www.gnu.org/software/gdb/documentation/>.
[debug]For help, type "help".
[debug]Type "apropos word" to search for commands related to "word".
[debug]>>>>>>cb_gdb:
[debug]> set confirm off

Debugger name and version: GNU gdb (GDB) 7.7

[debug]>>>>>>cb_gdb:
[debug]> set width 0
[debug]>>>>>>cb_gdb:
[debug]> set height 0
[debug]>>>>>>cb_gdb:
[debug]> set breakpoint pending on
[debug]>>>>>>cb_gdb:
[debug]> set print asm-demangle on
[debug]>>>>>>cb_gdb:
[debug]> set unwindonsignal on
[debug]>>>>>>cb_gdb:
[debug]> set print elements 0
[debug]>>>>>>cb_gdb:
[debug]> set disassembly-flavor att
[debug]No symbol "disassembly" in current context.
[debug]>>>>>>cb_gdb:
[debug]> catch throw
[debug]Catchpoint 1 (throw)
[debug]>>>>>>cb_gdb:
[debug]> source C:\Users\davem_000\projects\codeblocks-svn\src\devel\share\devkitide/scripts/stl-views-1.0.3.gdb
[debug]>>>>>>cb_gdb:
[debug]> directory C:/Users/davem_000/projects/devkitIDEtest/test/
[debug]Source directories searched: C:/Users/davem_000/projects/devkitIDEtest/test;$cdir;$cwd
[debug]>>>>>>cb_gdb:
[debug]> set args $(TARGET_OUTPUT_FILE)
[debug]>>>>>>cb_gdb:
[debug]> target extended-remote tcp:localhost:8000
[debug]Remote debugging using tcp:localhost:8000
[debug]0x02000000 in _start ()
[debug]>>>>>>cb_gdb:

Connected

[debug]> break "C:/Users/davem_000/projects/devkitIDEtest/test/source/main.c:20"

In _start () ()

[debug]> break "C:/Users/davem_000/projects/devkitIDEtest/test/source/main.c:20"
[debug]Breakpoint 2 at 0x200cc18: file c:/Users/davem_000/projects/devkitIDEtest/test/source/main.c, line 20.
[debug]>>>>>>cb_gdb:
[debug]> continue
[debug]Note: breakpoint 2 also set at pc 0x200cc18.
[debug]Breakpoint 3 at 0x200cc18: file c:/Users/davem_000/projects/devkitIDEtest/test/source/main.c, line 20.
[debug]>>>>>>cb_gdb:
[debug]Continuing.
[debug]Breakpoint 2, main () at c:/Users/davem_000/projects/devkitIDEtest/test/source/main.c:20
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:20:585:beg:0x200cc18
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:20

[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> bt 30
[debug]#0  main () at c:/Users/davem_000/projects/devkitIDEtest/test/source/main.c:20
[debug]>>>>>>cb_gdb:
[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 0
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:22:671:beg:0x200cc28
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:22

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 0
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:21:642:beg:0x200cc2c
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:21

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 0
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:23:693:beg:0x200cc30
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:23

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 1
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]Breakpoint 2, main () at c:/Users/davem_000/projects/devkitIDEtest/test/source/main.c:20
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:20:585:beg:0x200cc18
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:20

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 1
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:22:671:beg:0x200cc28
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:22

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 1
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:21:642:beg:0x200cc2c
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:21

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 1
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:23:693:beg:0x200cc30
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:23

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 2
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> next
[debug]Breakpoint 2, main () at c:/Users/davem_000/projects/devkitIDEtest/test/source/main.c:20
[debug]c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:20:585:beg:0x200cc18
[debug]>>>>>>cb_gdb:

At c:\Users\davem_000\projects\devkitIDEtest\test\source\main.c:20

[debug]> info locals
[debug]message = 0x2012900 "Hello World!"
[debug]iteration = 2
[debug]>>>>>>cb_gdb:
[debug]> info args
[debug]No arguments.
[debug]>>>>>>cb_gdb:
[debug]> quit

Debugger finished with status 0

If the additional shell commands worked then I could possibly do this with the Static/Dynamic Library types but it's not a library & I expect there may be issues with the link command when I come to try using the Code::Blocks build system instead of a custom Makefile. It also seems a bit naff ;) There's also the problem that debug then makes gdb attempt to run the host application with library targets which obviously doesn't work too well.

That Host Application stuff should probably also be disabled for target types that don't use it

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Re: Adding a target type for embedded development?
« Reply #5 on: May 22, 2014, 01:20:45 pm »
Did you want me to do a pull request against your git repo?

https://github.com/WinterMute/codeblocks_sf/compare/add-embedded-target

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Adding a target type for embedded development?
« Reply #6 on: May 22, 2014, 01:50:55 pm »
As you like, I've never done the pull-request-thing. Just tell me the branch...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Re: Adding a target type for embedded development?
« Reply #7 on: May 26, 2014, 06:17:47 pm »
The branch is at https://github.com/WinterMute/codeblocks_sf/tree/add-embedded-target

I did a pull request as well, not sure if you saw it.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Adding a target type for embedded development?
« Reply #8 on: May 26, 2014, 07:47:53 pm »
Yes, I have... will try to find some time...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Adding a target type for embedded development?
« Reply #9 on: June 24, 2014, 01:04:58 am »
Here http://forums.codeblocks.org/index.php/topic,19390.new.html another user needed similar feature to the one you're proposing.
The thing is that he has nothing to do with embedded development, so using a target named embedded would be awkward for him.

As you know I'm against adding another type.
I'm thinking why don't we just add the possibility to setup host application in both console and native targets?
And also in both these targets we can add the host app parameters. Probably we should not call it host, but probably simulator or wrapper app.

What do you think?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Re: Adding a target type for embedded development?
« Reply #10 on: November 24, 2014, 01:07:08 pm »
Hi,

Sorry to take so long replying. Only just noticed you'd replied.

Currently I'm using a custom Makefile to build which works fine regardless of the target type. The problem comes when attempting to use code::blocks build system where the link step for the console and native targets just use the linker to output the final file.

Here's the build log with my Makefile for a 3DS homebrew application.
Code
-------------- Build: Debug in 3dstest1 (compiler: devkitARM)---------------

Checking if target is up-to-date: make.exe -q -f Makefile Debug
Running command: make.exe -f Makefile Debug
main.c
arm-none-eabi-gcc -MMD -MP -MF /c/Users/davem_000/projects/test/3dstest1/Debug/main.d -g -Wall -O2 -mword-relocations -fomit-frame-pointer -ffast-math -march=armv6k -mtune=mpcore -mfloat-abi=softfp -I/c/Users/davem_000/projects/test/3dstest1/include -I/c/devkitPro/libctru/include -I/c/Users/davem_000/projects/test/3dstest1/build -DARM11 -D_3DS -c /c/Users/davem_000/projects/test/3dstest1/source/main.c -o main.o
arm-none-eabi-gcc -specs=3dsx.specs -g -march=armv6k -mtune=mpcore -mfloat-abi=softfp -Wl,-Map,3dstest1-debug.map   main.o  -L/c/devkitPro/libctru/lib -lctru -lm -o /c/Users/davem_000/projects/test/3dstest1/3dstest1-debug.elf
arm-none-eabi-nm -CSn /c/Users/davem_000/projects/test/3dstest1/3dstest1-debug.elf > 3dstest1-debug.lst
3dsxtool /c/Users/davem_000/projects/test/3dstest1/3dstest1-debug.elf /c/Users/davem_000/projects/test/3dstest1/3dstest1-debug.3dsx
smdhtool --create "3dstest1-debug" "Built with devkitARM & ctrulib" "Unspecified Author" /c/devkitPro/libctru/default_icon.png /c/Users/davem_000/projects/test/3dstest1/3dstest1-debug.smdh
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))


And here's what it does if I switch off the custom Makefile option

Code

-------------- Build: Debug in 3dstest1 (compiler: devkitARM)---------------

arm-none-eabi-gcc.exe -march=armv6k -mtune=mpcore -mfloat-abi=softfp -g -Wall -O2 -mword-relocations -Ic:\devkitPro\devkitARM\..\libctru\include -Ic:\devkitPro\devkitARM\arm-none-eabi\include -c source\main.c -o obj\Debug\source\main.o
arm-none-eabi-g++.exe -Lc:\devkitPro\devkitARM\..\libctru\lib -o 3dstest1-debug.3dsx obj\Debug\source\main.o  -specs=3dsx.specs  -lctru
Output file is 3dstest1-debug.3dsx with size 211.99 KB
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))

So what I was intending to do is have the ttEmbedded target link an elf and then another script which performs the steps that build the final binary and/or support files. These final steps will be different for each platform devkitARM supports.

If that makes any sense ...



Offline scarphin

  • Lives here!
  • ****
  • Posts: 644
Re: Adding a target type for embedded development?
« Reply #11 on: November 24, 2014, 08:17:22 pm »
You can change the output extension to .elf in 'project->properties->build targets->output filename' and then use post-build steps to build the final output binaries and/or other files if I understood your problem correctly. You can also consult the avr project wizard as it performs similar build and post-build steps for an avr project, just create a dummy avr project and check the project settings for further reference.

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Re: Adding a target type for embedded development?
« Reply #12 on: November 26, 2014, 08:48:41 pm »
If I change the extension to .elf then the run and debug buttons don't work. The main point of this was to be able to launch an emulator to run the final binary with the run button. The debug button launches the emulator with a gdb port & starts gdb which connects to that.

This could also work with an application to upload binaries to, in my case, a game console & work in the same way there.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Adding a target type for embedded development?
« Reply #13 on: November 26, 2014, 09:10:45 pm »
Then what about my proposal to add host app for every possible target type?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline WinterMute

  • Multiple posting newcomer
  • *
  • Posts: 25
    • devkitPro
Re: Adding a target type for embedded development?
« Reply #14 on: November 27, 2014, 09:00:37 pm »
OK, I've played around with this some more and it'll work for me if the native target can use the host application.

This patch uses the Host Application to run ttNative target if it's set and also fixes the static & dynamic lib targets so variables can be used in the execution parameters. This should also work for the guy with the MPI program.

I'm wondering if it would be better to just  the ReplaceEnvVars method on the completed command string though.

What do you think about going this way? 

Code
diff --git a/src/plugins/compilergcc/compilergcc.cpp b/src/plugins/compilergcc/compilergcc.cpp
index f435b8c..3ceeefe 100644
--- a/src/plugins/compilergcc/compilergcc.cpp
+++ b/src/plugins/compilergcc/compilergcc.cpp
@@ -1911,19 +1911,28 @@ int CompilerGCC::Run(ProjectBuildTarget* target)
             m_pProject->SetCurrentlyCompilingTarget(0);
             return -1;
         }
-        Manager::Get()->GetMacrosManager()->ReplaceEnvVars(hostapStr);
         command << hostapStr << strSPACE;
         command << target->GetExecutionParameters();
+        Manager::Get()->GetMacrosManager()->ReplaceEnvVars(command);
     }
     else if (target->GetTargetType() != ttCommandsOnly)
     {
-        command << execStr << strSPACE;
-        command << target->GetExecutionParameters();
-        // each shell execution must be enclosed to "":
-        // xterm -T X -e /bin/sh -c "/usr/bin/cb_console_runner X"
-        // here is last \"
-        if (commandIsQuoted)
-            command << strQUOTE;
+        if (target->GetTargetType() == ttNative && !target->GetHostApplication().IsEmpty())
+        {
+            command << hostapStr << strSPACE;
+            command << target->GetExecutionParameters();
+            Manager::Get()->GetMacrosManager()->ReplaceEnvVars(command);
+        }
+        else
+        {
+            command << execStr << strSPACE;
+            command << target->GetExecutionParameters();
+            // each shell execution must be enclosed to "":
+            // xterm -T X -e /bin/sh -c "/usr/bin/cb_console_runner X"
+            // here is last \"
+            if (commandIsQuoted)
+                command << strQUOTE;
+        }
     }
     else
     {