Author Topic: XML based compilers  (Read 337032 times)

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5516
Re: XML based compilers
« Reply #120 on: August 28, 2012, 09:16:39 pm »
I had a nightly ready, but during testing on linux I found a showstopper, the 2 latest compiler option/directives are still missing.
They are present in some (did not check all of them) gcc derivatives/ports (like gnu arm), but are missing in the main gcc.
I am talking about :
 - std=c++11
 - Wzero-as-null-pointer-constant

How can we be sure not other options have disappeared ?

Next to the issue, I have a question what advice to we want to give wrt "default.conf",
We will ask the user to backup, but then what, do they need to remove something out of it (the compiler section, but for sure not the user sets) ?


EDIT : can the compiler detection at startup be explained, it made no sense to me.

Pre-suported compilers (which were absent) were now user defined ??
Other were grey-ed out.
Some where red ?

I don't get it, for ther majority of them I would have expected the same thing.
« Last Edit: August 28, 2012, 09:22:34 pm by killerbot »

Offline Jenna

  • Administrator
  • Lives here!
  • *****
  • Posts: 7252
Re: XML based compilers
« Reply #121 on: August 28, 2012, 10:12:53 pm »
My build is not the newest one (I have 8218), and the two options you have mentioned are there.

I start the xml-branch with an own personality and do not use the default.conf of trunk, maybe that's the reason.

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #122 on: August 28, 2012, 11:39:48 pm »
I had a nightly ready, but during testing on linux I found a showstopper, the 2 latest compiler option/directives are still missing.
In share\CodeBlocks\compilers (user, not global), XML files will be saved for any compilers to which flags have been changed/added/removed.  It is possible options_gcc.xml was generated during a previous test before the version detection was fixed.  These files are loaded preferentially, so either deleting it manually, or resetting the compiler should resolve the problem.


EDIT : can the compiler detection at startup be explained, it made no sense to me.
The ones labeled "user defined" mean that they were not detected, but the master path loaded from default.conf is different than that given by auto-detection (this happens either when the user has set their own path, or when auto-detection has changed defaults).
Grey-ed out means the compiler was simply not detected (but the master path loaded from default.conf is the same as auto-detection).
Red means that the master path was empty before auto-detection began.  The detection dialog will only be shown if at least one compiler has an empty path.  The purpose is to alert the user that the highlighted compiler(s) are invalid and (may) require attention.  (I have another idea to more accurately mark this - currently new compilers are incorrectly marked red as well; I should have a small patch for this soon.)

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #123 on: August 29, 2012, 01:02:57 am »
We will ask the user to backup, but then what, do they need to remove something out of it (the compiler section, but for sure not the user sets) ?
In my opinion, it should be fine to continue working with the same (unmodified) default.conf (of course, it still should be backed up just in case).

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9693
Re: XML based compilers
« Reply #124 on: August 29, 2012, 06:26:10 am »
My build is not the newest one (I have 8218), and the two options you have mentioned are there.
For me, too - both options are there.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5516
Re: XML based compilers
« Reply #125 on: August 29, 2012, 07:49:20 am »
I deleted the "output" folder again, and rerun "update" script, optiotns still don't show up in "options_gcc.xml"

Here's my content of it :
Code
<?xml version="1.0"?>
<!DOCTYPE CodeBlocks_compiler_options>
<CodeBlocks_compiler_options>
    <if platform="windows">
        <Program name="C"         value="mingw32-gcc.exe"/>
        <Program name="CPP"       value="mingw32-g++.exe"/>
        <Program name="LD"        value="mingw32-g++.exe"/>
        <Program name="DBGconfig" value="gdb_debugger:Default"/>
        <Program name="LIB"       value="ar.exe"/>
        <Program name="WINDRES"   value="windres.exe"/>
        <Program name="MAKE"      value="mingw32-make.exe"/>
    </if>
    <else>
        <Program name="C"         value="gcc"/>
        <Program name="CPP"       value="g++"/>
        <Program name="LD"        value="g++"/>
        <Program name="DBGconfig" value="gdb_debugger:Default"/>
        <Program name="LIB"       value="ar"/>
        <Program name="WINDRES"   value=""/>
        <Program name="MAKE"      value="make"/>
    </else>

    <Switch name="includeDirs"             value="-I"/>
    <Switch name="libDirs"                 value="-L"/>
    <Switch name="linkLibs"                value="-l"/>
    <Switch name="defines"                 value="-D"/>
    <Switch name="genericSwitch"           value="-"/>
    <Switch name="objectExtension"         value="o"/>
    <Switch name="needDependencies"        value="true"/>
    <Switch name="forceCompilerUseQuotes"  value="false"/>
    <Switch name="forceLinkerUseQuotes"    value="false"/>
    <Switch name="logging"                 value="default"/>
    <Switch name="libPrefix"               value="lib"/>
    <Switch name="libExtension"            value="a"/>
    <Switch name="linkerNeedsLibPrefix"    value="false"/>
    <Switch name="linkerNeedsLibExtension" value="false"/>
    <Switch name="supportsPCH"             value="true"/>
    <Switch name="PCHExtension"            value="h.gch"/>
    <Switch name="UseFullSourcePaths"      value="true"/>

    <!-- Summary of GCC options: http://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html -->

    <Option name="Produce debugging symbols"
            option="-g"
            category="Debugging"
            checkAgainst="-O -O1 -O2 -O3 -Os"
            checkMessage="You have optimizations enabled. This is Not A Good Thing(tm) when producing debugging symbols..."
            supersedes="-s"/>
    <if platform="windows">
        <Option name="Profile code when executed"
                option="-pg"
                category="Profiling"
                additionalLibs="-pg -lgmon"
                supersedes="-s"/>
    </if>
    <else>
        <Option name="Profile code when executed"
                option="-pg"
                category="Profiling"
                additionalLibs="-pg"
                supersedes="-s"/>
    </else>

    <!-- warnings -->
    <Common name="warnings"/>
    <Category name="Warnings">
        <Option name="Enable Effective-C++ warnings (thanks Scott Meyers)"
                option="-Weffc++"/>
        <Option name="Warn whenever a switch statement does not have a default case"
                option="-Wswitch-default"/>
        <Option name="Warn whenever a switch statement has an index of enumerated type and lacks a case for one or more of the named codes of that enumeration"
                option="-Wswitch-enum"/>
        <if exec="C -dumpversion"
            regex="^[4-9]\.[0-9]"
            default="true">
            <Option name="Warn if a user supplied include directory does not exist"
                    option="-Wmissing-include-dirs"/>
        </if>
        <Option name="Warn if a global function is defined without a previous declaration"
                option="-Wmissing-declarations"/>
        <Option name="Warn if the compiler detects that code will never be executed"
                option="-Wunreachable-code"/>
        <Option name="Warn if a function can not be inlined and it was declared as inline"
                option="-Winline"/>
        <Option name="Warn if floating point values are used in equality comparisons"
                option="-Wfloat-equal"/>
        <Option name="Warn if an undefined identifier is evaluated in an '#if' directive"
                option="-Wundef"/>
        <Option name="Warn whenever a pointer is cast such that the required alignment of the target is increased"
                option="-Wcast-align"/>
        <Option name="Warn if anything is declared more than once in the same scope"
                option="-Wredundant-decls"/>
        <Option name="Warn about unitialized variables which are initialized with themselves"
                option="-Winit-self"/>
        <Option name="Warn whenever a local variable shadows another local variable, parameter or global variable or whenever a built-in function is shadowed"
                option="-Wshadow"/>
    </Category>

    <!-- optimization -->
    <Common name="optimization"/>
    <Option name="Don't keep the frame pointer in a register for functions that don't need one"
            option="-fomit-frame-pointer"
            category="Optimization"
            checkAgainst="-g -ggdb"
            checkMessage="You have debugging symbols enabled. This is Not A Good Thing(tm) when optimizing..."/>

    <!-- machine dependent options - cpu arch -->
    <Common name="architecture"/>

    <Command name="CompileObject"
             value="$compiler $options $includes -c $file -o $object"/>
    <Command name="GenDependencies"
             value="$compiler -MM $options -MF $dep_object -MT $object $includes $file"/>
    <Command name="CompileResource"
             value="$rescomp $res_includes -J rc -O coff -i $file -o $resource_output"/>
    <Command name="LinkConsoleExe"
             value="$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs"/>
    <if platform="windows">
        <Command name="LinkNative"
                 value="$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs -Wl,--subsystem,native"/>
        <Command name="LinkExe"
                 value="$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs -mwindows"/>
        <Command name="LinkDynamic"
                 value="$linker -shared -Wl,--output-def=$def_output -Wl,--out-implib=$static_output -Wl,--dll $libdirs $link_objects $link_resobjects -o $exe_output $link_options $libs"/>
    </if>
    <else>
        <Command name="LinkNative"
                 value="$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs"/>
        <Command name="LinkExe"
                 value="$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs"/>
        <Command name="LinkDynamic"
                 value="$linker -shared $libdirs $link_objects $link_resobjects -o $exe_output $link_options $libs"/>
    </else>
    <Command name="LinkStatic"
             value="$lib_linker -r -s $static_output $link_objects"/>
    <Common name="cmds"/>

    <Common name="re"/>

    <Common name="sort"/>
</CodeBlocks_compiler_options>

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5516
Re: XML based compilers
« Reply #126 on: August 29, 2012, 07:56:20 am »
ok I think I found out why there's a problem . From options_common_warnings.xml :

Code
        <if exec="C -dumpversion"
            regex="^4\.[7-9]|^[5-9]\.[0-9]"
            default="true">
            <Option name="Have g++ follow the C++11 ISO C++ language standard"
                    option="-std=c++11"
                    supersedes="-std=c++98 -std=c++0x"/>
            <Option name="zero as null pointer constant"
                    option="-Wzero-as-null-pointer-constant"/>
        </if>

Now if we do :

Code
killerbot@XIII:~/CodeBlocks/xmlcompiler/xml_compiler/src> gcc -dumpversion
4.6
killerbot@XIII:~/CodeBlocks/xmlcompiler/xml_compiler/src> gcc-4.7 -dumpversion
4.7
killerbot@XIII:~/CodeBlocks/xmlcompiler/xml_compiler/src>
You can see that the system compiler is still gcc.
HOWEVER in my existing CB (so in default.conf), we had/have :
Code
			<gcc>
<NAME>
<str>
<![CDATA[GNU GCC Compiler]]>
</str>
</NAME>
<MASTER_PATH>
<str>
<![CDATA[/usr]]>
</str>
</MASTER_PATH>
<C_COMPILER>
<str>
<![CDATA[gcc-4.7]]>
</str>
</C_COMPILER>
<CPP_COMPILER>
<str>
<![CDATA[g++-4.7]]>
</str>
</CPP_COMPILER>
<LINKER>
<str>
<![CDATA[g++-4.7]]>
</str>
</LINKER>
</gcc>

Meaning that either the info in default.conf get's ignored, or do we just have a one time migration problem, and in the latter case can it be avoided ?

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #127 on: August 29, 2012, 02:45:29 pm »
I deleted the "output" folder again, and rerun "update" script, optiotns still don't show up in "options_gcc.xml"
The folder ~/.codeblocks/share/codeblocks/compilers is the one you want to clean.

Meaning that either the info in default.conf get's ignored, or do we just have a one time migration problem, and in the latter case can it be avoided ?
However, I think you are correct and have found a bug; I will have to double check, but at the point in time when the compiler is executed to retrieve the version number, it *might* not have yet loaded non-default names from the user configuration file.  I will look into this.

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #128 on: August 30, 2012, 04:27:41 am »
This patch should resolve the above issues.
Code
Index: src/sdk/autodetectcompilers.cpp
===================================================================
--- src/sdk/autodetectcompilers.cpp (revision 8275)
+++ src/sdk/autodetectcompilers.cpp (working copy)
@@ -44,25 +44,12 @@
         list->InsertColumn(0, _("Compiler"), wxLIST_FORMAT_LEFT, 380);
         list->InsertColumn(1, _("Status"),   wxLIST_FORMAT_LEFT, 100);
 
-        bool firstRun = true;
         for (size_t i = 0; i < CompilerFactory::GetCompilersCount(); ++i)
         {
             Compiler* compiler = CompilerFactory::GetCompiler(i);
             if (!compiler)
                 continue;
-            if (!compiler->GetMasterPath().IsEmpty())
-            {
-                firstRun = false; // all master paths are empty on first run
-                break;
-            }
-        }
 
-        for (size_t i = 0; i < CompilerFactory::GetCompilersCount(); ++i)
-        {
-            Compiler* compiler = CompilerFactory::GetCompiler(i);
-            if (!compiler)
-                continue;
-
             list->InsertItem(list->GetItemCount(), compiler->GetName());
 
             wxString path = compiler->GetMasterPath();
@@ -71,7 +58,7 @@
 
             int idx = list->GetItemCount() - 1;
             int highlight = 0;
-            if (path.IsEmpty() && !firstRun)
+            if (path.IsEmpty() && Manager::Get()->GetConfigManager(wxT("compiler"))->Exists(wxT("/sets/") + compiler->GetID() + wxT("/name")))
             {
                 // Here, some user-interaction is required not to show this
                 // dialog again on each new start-up of C::B.
Index: src/sdk/compiler.cpp
===================================================================
--- src/sdk/compiler.cpp (revision 8275)
+++ src/sdk/compiler.cpp (working copy)
@@ -814,6 +814,16 @@
     int depth = 0;
     wxString categ;
     bool exclu = false;
+
+    wxString baseKey = GetParentID().IsEmpty() ? wxT("/sets") : wxT("/user_sets");
+    ConfigManager* cfg = Manager::Get()->GetConfigManager(wxT("compiler"));
+    wxString cmpKey;
+    cmpKey.Printf(wxT("%s/set%3.3d"), baseKey.c_str(), CompilerFactory::GetCompilerIndex(this) + 1);
+    if (!cfg->Exists(cmpKey + wxT("/name")))
+        cmpKey.Printf(wxT("%s/%s"), baseKey.c_str(), m_ID.c_str());
+    if (!cfg->Exists(cmpKey + wxT("/name")))
+        cmpKey.Replace(wxT("-"), wxEmptyString);
+
     while (node)
     {
         const wxString value = node->GetAttribute(wxT("value"), wxEmptyString);
@@ -837,19 +847,19 @@
         {
             wxString prog = node->GetAttribute(wxT("name"), wxEmptyString);
             if (prog == wxT("C"))
-                m_Programs.C = value;
+                m_Programs.C       = cfg->Read(cmpKey + wxT("/c_compiler"),   value);
             else if (prog == wxT("CPP"))
-                m_Programs.CPP = value;
+                m_Programs.CPP     = cfg->Read(cmpKey + wxT("/cpp_compiler"), value);
             else if (prog == wxT("LD"))
-                m_Programs.LD = value;
+                m_Programs.LD      = cfg->Read(cmpKey + wxT("/linker"),       value);
             else if (prog == wxT("DBGconfig"))
                 m_Programs.DBGconfig = value;
             else if (prog == wxT("LIB"))
-                m_Programs.LIB = value;
+                m_Programs.LIB     = cfg->Read(cmpKey + wxT("/lib_linker"),   value);
             else if (prog == wxT("WINDRES"))
-                m_Programs.WINDRES = value;
+                m_Programs.WINDRES = cfg->Read(cmpKey + wxT("/res_compiler"), value);
             else if (prog == wxT("MAKE"))
-                m_Programs.MAKE = value;
+                m_Programs.MAKE    = cfg->Read(cmpKey + wxT("/make"),         value);
         }
         else if (node->GetName() == wxT("Switch"))
         {

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #129 on: September 02, 2012, 09:37:07 pm »
I had a nightly ready, but during testing on linux I found a showstopper, the 2 latest compiler option/directives are still missing.
They are present in some (did not check all of them) gcc derivatives/ports (like gnu arm), but are missing in the main gcc.
I am talking about :
 - std=c++11
 - Wzero-as-null-pointer-constant
I forgot to ask, has the last patch fixed this on your computer?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5516
Re: XML based compilers
« Reply #130 on: September 03, 2012, 07:36:21 am »
testing this again this evening

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5516
Re: XML based compilers
« Reply #131 on: September 03, 2012, 08:18:21 pm »
good and bad news.

The 2 compiler options remain in pace.

However it still breaks existing configuration of compilers. I have told CB that gcc, is to be gcc-4.7.
Aka that means in default.conf the following :
Code
			<gcc>
<NAME>
<str>
<![CDATA[GNU GCC Compiler]]>
</str>
</NAME>
<MASTER_PATH>
<str>
<![CDATA[/usr]]>
</str>
</MASTER_PATH>
<C_COMPILER>
<str>
<![CDATA[gcc-4.7]]>
</str>
</C_COMPILER>
<CPP_COMPILER>
<str>
<![CDATA[g++-4.7]]>
</str>
</CPP_COMPILER>
<LINKER>
<str>
<![CDATA[g++-4.7]]>
</str>
</LINKER>
</gcc>

However with the new build this is back to defaults in the default.conf (as also through the GUI)
==> only NAME/MASTER_PATH remain, the other are gone.

Personally I think we should fix this first, since this breaks users existing configurations.

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #132 on: September 04, 2012, 01:13:46 am »
Personally I think we should fix this first, since this breaks users existing configurations.
After four hours of just trying to find the cause of the bug, I would agree, it should be fixed first ;).  This bug was far worse than first apparent.  It actually deletes all renamed executables on the second launch after the change has been made.

My last bug fix patch fixed a small problem, but created this much larger one.  The following patch fixes it (and has been much more thoroughly tested both on Windows and Linux).
Code
Index: src/sdk/compiler.cpp
===================================================================
--- src/sdk/compiler.cpp (revision 8345)
+++ src/sdk/compiler.cpp (working copy)
@@ -843,23 +843,41 @@
                 continue;
             }
         }
-        else if (node->GetName() == wxT("Program"))
+        else if (node->GetName() == wxT("Program")) // configuration is read so execution of renamed programs work, m_Mirror is needed to reset names to their defaults before leaving this function
         {
             wxString prog = node->GetAttribute(wxT("name"), wxEmptyString);
             if (prog == wxT("C"))
-                m_Programs.C       = cfg->Read(cmpKey + wxT("/c_compiler"),   value);
+            {
+                m_Programs.C = cfg->Read(cmpKey + wxT("/c_compiler"), value);
+                m_Mirror.Programs.C = value;
+            }
             else if (prog == wxT("CPP"))
-                m_Programs.CPP     = cfg->Read(cmpKey + wxT("/cpp_compiler"), value);
+            {
+                m_Programs.CPP = cfg->Read(cmpKey + wxT("/cpp_compiler"), value);
+                m_Mirror.Programs.CPP = value;
+            }
             else if (prog == wxT("LD"))
-                m_Programs.LD      = cfg->Read(cmpKey + wxT("/linker"),       value);
+            {
+                m_Programs.LD = cfg->Read(cmpKey + wxT("/linker"), value);
+                m_Mirror.Programs.LD = value;
+            }
             else if (prog == wxT("DBGconfig"))
                 m_Programs.DBGconfig = value;
             else if (prog == wxT("LIB"))
-                m_Programs.LIB     = cfg->Read(cmpKey + wxT("/lib_linker"),   value);
+            {
+                m_Programs.LIB = cfg->Read(cmpKey + wxT("/lib_linker"), value);
+                m_Mirror.Programs.LIB = value;
+            }
             else if (prog == wxT("WINDRES"))
+            {
                 m_Programs.WINDRES = cfg->Read(cmpKey + wxT("/res_compiler"), value);
+                m_Mirror.Programs.WINDRES = value;
+            }
             else if (prog == wxT("MAKE"))
-                m_Programs.MAKE    = cfg->Read(cmpKey + wxT("/make"),         value);
+            {
+                m_Programs.MAKE = cfg->Read(cmpKey + wxT("/make"), value);
+                m_Mirror.Programs.MAKE = value;
+            }
         }
         else if (node->GetName() == wxT("Switch"))
         {
@@ -1000,6 +1018,13 @@
         }
         node = node->GetNext();
     }
+    // reset programs to their actual defaults (customized settings are loaded in a different function)
+    m_Programs.C       = m_Mirror.Programs.C;
+    m_Programs.CPP     = m_Mirror.Programs.CPP;
+    m_Programs.LD      = m_Mirror.Programs.LD;
+    m_Programs.LIB     = m_Mirror.Programs.LIB;
+    m_Programs.WINDRES = m_Mirror.Programs.WINDRES;
+    m_Programs.MAKE    = m_Mirror.Programs.MAKE;
 }
 
 void Compiler::LoadRegExArray(const wxString& name, bool globalPrecedence, int recursion)

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #133 on: September 04, 2012, 02:03:27 am »
The following patch fixes it (and has been much more thoroughly tested both on Windows and Linux).
... but not thoroughly enough.  There is still a small recursion issue that needs to be dealt with.

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: XML based compilers
« Reply #134 on: September 04, 2012, 04:28:12 am »
There is still a small recursion issue that needs to be dealt with.
... and dealt with.
Code
Index: src/sdk/compiler.cpp
===================================================================
--- src/sdk/compiler.cpp (revision 8345)
+++ src/sdk/compiler.cpp (working copy)
@@ -843,23 +843,41 @@
                 continue;
             }
         }
-        else if (node->GetName() == wxT("Program"))
+        else if (node->GetName() == wxT("Program")) // configuration is read so execution of renamed programs work, m_Mirror is needed to reset before leaving this function
         {
             wxString prog = node->GetAttribute(wxT("name"), wxEmptyString);
             if (prog == wxT("C"))
-                m_Programs.C       = cfg->Read(cmpKey + wxT("/c_compiler"),   value);
+            {
+                m_Programs.C = cfg->Read(cmpKey + wxT("/c_compiler"), value);
+                m_Mirror.Programs.C = value;
+            }
             else if (prog == wxT("CPP"))
-                m_Programs.CPP     = cfg->Read(cmpKey + wxT("/cpp_compiler"), value);
+            {
+                m_Programs.CPP = cfg->Read(cmpKey + wxT("/cpp_compiler"), value);
+                m_Mirror.Programs.CPP = value;
+            }
             else if (prog == wxT("LD"))
-                m_Programs.LD      = cfg->Read(cmpKey + wxT("/linker"),       value);
+            {
+                m_Programs.LD = cfg->Read(cmpKey + wxT("/linker"), value);
+                m_Mirror.Programs.LD = value;
+            }
             else if (prog == wxT("DBGconfig"))
                 m_Programs.DBGconfig = value;
             else if (prog == wxT("LIB"))
-                m_Programs.LIB     = cfg->Read(cmpKey + wxT("/lib_linker"),   value);
+            {
+                m_Programs.LIB = cfg->Read(cmpKey + wxT("/lib_linker"), value);
+                m_Mirror.Programs.LIB = value;
+            }
             else if (prog == wxT("WINDRES"))
+            {
                 m_Programs.WINDRES = cfg->Read(cmpKey + wxT("/res_compiler"), value);
+                m_Mirror.Programs.WINDRES = value;
+            }
             else if (prog == wxT("MAKE"))
-                m_Programs.MAKE    = cfg->Read(cmpKey + wxT("/make"),         value);
+            {
+                m_Programs.MAKE = cfg->Read(cmpKey + wxT("/make"), value);
+                m_Mirror.Programs.MAKE = value;
+            }
         }
         else if (node->GetName() == wxT("Switch"))
         {
@@ -1000,6 +1018,15 @@
         }
         node = node->GetNext();
     }
+    if (recursion == 0) // reset programs to their actual defaults (customized settings are loaded in a different function)
+    {
+        m_Programs.C       = m_Mirror.Programs.C;
+        m_Programs.CPP     = m_Mirror.Programs.CPP;
+        m_Programs.LD      = m_Mirror.Programs.LD;
+        m_Programs.LIB     = m_Mirror.Programs.LIB;
+        m_Programs.WINDRES = m_Mirror.Programs.WINDRES;
+        m_Programs.MAKE    = m_Mirror.Programs.MAKE;
+    }
 }
 
 void Compiler::LoadRegExArray(const wxString& name, bool globalPrecedence, int recursion)