~ubuntu-branches/ubuntu/oneiric/codeblocks/oneiric

« back to all changes in this revision

Viewing changes to src/plugins/compilergcc/compilerMINGW.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
 
3
 * http://www.gnu.org/licenses/gpl-3.0.html
 
4
 *
 
5
 * $Revision: 4909 $
 
6
 * $Id: compilerMINGW.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
 
7
 * $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/plugins/compilergcc/compilerMINGW.cpp $
 
8
 */
 
9
 
 
10
#include <sdk.h>
 
11
#include <prep.h>
 
12
#include "compilerMINGW.h"
 
13
#include <wx/intl.h>
 
14
#include <wx/regex.h>
 
15
#include <wx/config.h>
 
16
#include <wx/fileconf.h>
 
17
#include <wx/msgdlg.h>
 
18
#include <wx/filename.h>
 
19
#include <wx/filefn.h>
 
20
#include "manager.h"
 
21
#include "logmanager.h"
 
22
#include "compilerMINGWgenerator.h"
 
23
 
 
24
#include <configmanager.h>
 
25
 
 
26
#ifdef __WXMSW__
 
27
    #include <wx/msw/registry.h>
 
28
#endif
 
29
 
 
30
CompilerMINGW::CompilerMINGW(const wxString& name, const wxString& ID)
 
31
    : Compiler(name, ID)
 
32
{
 
33
    Reset();
 
34
}
 
35
 
 
36
CompilerMINGW::~CompilerMINGW()
 
37
{
 
38
    //dtor
 
39
}
 
40
 
 
41
Compiler * CompilerMINGW::CreateCopy()
 
42
{
 
43
    Compiler* c = new CompilerMINGW(*this);
 
44
    c->SetExtraPaths(m_ExtraPaths); // wxArrayString doesn't seem to be copied with the default copy ctor...
 
45
    return c;
 
46
}
 
47
 
 
48
CompilerCommandGenerator* CompilerMINGW::GetCommandGenerator()
 
49
{
 
50
    return new CompilerMINGWGenerator;
 
51
}
 
52
 
 
53
void CompilerMINGW::Reset()
 
54
{
 
55
    if (platform::windows)
 
56
    {
 
57
        m_Programs.C = _T("mingw32-gcc.exe");
 
58
        m_Programs.CPP = _T("mingw32-g++.exe");
 
59
        m_Programs.LD = _T("mingw32-g++.exe");
 
60
        m_Programs.DBG = _T("gdb.exe");
 
61
        m_Programs.LIB = _T("ar.exe");
 
62
        m_Programs.WINDRES = _T("windres.exe");
 
63
        m_Programs.MAKE = _T("mingw32-make.exe");
 
64
    }
 
65
    else
 
66
    {
 
67
        m_Programs.C = _T("gcc");
 
68
        m_Programs.CPP = _T("g++");
 
69
        m_Programs.LD = _T("g++");
 
70
        m_Programs.DBG = _T("gdb");
 
71
        m_Programs.LIB = _T("ar");
 
72
        m_Programs.WINDRES = _T("");
 
73
        m_Programs.MAKE = _T("make");
 
74
    }
 
75
    m_Switches.includeDirs = _T("-I");
 
76
    m_Switches.libDirs = _T("-L");
 
77
    m_Switches.linkLibs = _T("-l");
 
78
    m_Switches.defines = _T("-D");
 
79
    m_Switches.genericSwitch = _T("-");
 
80
    m_Switches.objectExtension = _T("o");
 
81
    m_Switches.needDependencies = true;
 
82
    m_Switches.forceCompilerUseQuotes = false;
 
83
    m_Switches.forceLinkerUseQuotes = false;
 
84
    m_Switches.logging = clogSimple;
 
85
    m_Switches.libPrefix = _T("lib");
 
86
    m_Switches.libExtension = _T("a");
 
87
    m_Switches.linkerNeedsLibPrefix = false;
 
88
    m_Switches.linkerNeedsLibExtension = false;
 
89
    m_Switches.supportsPCH = true;
 
90
    m_Switches.PCHExtension = _T("h.gch");
 
91
    m_Switches.UseFullSourcePaths = true; // use the GDB workaround !!!!!!!!
 
92
 
 
93
    // Summary of GCC options: http://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html
 
94
 
 
95
    m_Options.ClearOptions();
 
96
    m_Options.AddOption(_("Produce debugging symbols"),
 
97
                _T("-g"),
 
98
                _("Debugging"),
 
99
                _T(""),
 
100
                true,
 
101
                _T("-O -O1 -O2 -O3 -Os"),
 
102
                _("You have optimizations enabled. This is Not A Good Thing(tm) when producing debugging symbols..."));
 
103
    wxString gprof_link = _T("-pg");
 
104
    if (platform::windows)
 
105
        gprof_link = _T("-pg -lgmon");
 
106
    m_Options.AddOption(_("Profile code when executed"), _T("-pg"), _("Profiling"), gprof_link);
 
107
 
 
108
    wxString category = _("Warnings");
 
109
 
 
110
    // warnings
 
111
    m_Options.AddOption(_("In C mode, support all ISO C90 programs. In C++ mode, remove GNU extensions that conflict with ISO C++"), _T("-ansi"), category);
 
112
    m_Options.AddOption(_("Enable all compiler warnings (overrides every other setting)"), _T("-Wall"), category);
 
113
    m_Options.AddOption(_("Enable standard compiler warnings"), _T("-W"), category);
 
114
    m_Options.AddOption(_("Stop compiling after first error"), _T("-Wfatal-errors"), category);
 
115
    m_Options.AddOption(_("Inhibit all warning messages"), _T("-w"), category);
 
116
    m_Options.AddOption(_("Enable warnings demanded by strict ISO C and ISO C++"), _T("-pedantic"), category);
 
117
    m_Options.AddOption(_("Treat as errors the warnings demanded by strict ISO C and ISO C++"), _T("-pedantic-errors"), category);
 
118
    m_Options.AddOption(_("Warn if main() is not conformant"), _T("-Wmain"), category);
 
119
    // optimization
 
120
    category = _("Optimization");
 
121
    m_Options.AddOption(_("Strip all symbols from binary (minimizes size)"), _T(""), category, _T("-s"), true, _T("-g -ggdb"), _("Stripping the binary will strip debugging symbols as well!"));
 
122
    m_Options.AddOption(_("Optimize generated code (for speed)"), _T("-O"), category);
 
123
    m_Options.AddOption(_("Optimize more (for speed)"), _T("-O1"), category);
 
124
    m_Options.AddOption(_("Optimize even more (for speed)"), _T("-O2"), category);
 
125
    m_Options.AddOption(_("Optimize fully (for speed)"), _T("-O3"), category);
 
126
    m_Options.AddOption(_("Optimize generated code (for size)"), _T("-Os"), category);
 
127
    m_Options.AddOption(_("Expensive optimizations"), _T("-fexpensive-optimizations"), category);
 
128
    // machine dependent options - cpu arch
 
129
    category = _("CPU architecture tuning (choose none, or only one of these)");
 
130
    m_Options.AddOption(_("i386"), _T("-march=i386"), category);
 
131
    m_Options.AddOption(_("i486"), _T("-march=i486"), category);
 
132
    m_Options.AddOption(_("Intel Pentium"), _T("-march=i586"), category);
 
133
    m_Options.AddOption(_("Intel Pentium (MMX)"), _T("-march=pentium-mmx"), category);
 
134
    m_Options.AddOption(_("Intel Pentium PRO"), _T("-march=i686"), category);
 
135
    m_Options.AddOption(_("Intel Pentium 2 (MMX)"), _T("-march=pentium2"), category);
 
136
    m_Options.AddOption(_("Intel Pentium 3 (MMX, SSE)"), _T("-march=pentium3"), category);
 
137
    m_Options.AddOption(_("Intel Pentium 4 (MMX, SSE, SSE2)"), _T("-march=pentium4"), category);
 
138
    m_Options.AddOption(_("Intel Pentium 4 Prescott (MMX, SSE, SSE2, SSE3)"), _T("-march=prescott"), category);
 
139
    m_Options.AddOption(_("Intel Pentium 4 Nocona (MMX, SSE, SSE2, SSE3, 64bit extensions)"), _T("-march=nocona"), category);
 
140
    m_Options.AddOption(_("Intel Pentium M (MMX, SSE, SSE2)"), _T("-march=pentium-m"), category);
 
141
    m_Options.AddOption(_("AMD K6 (MMX)"), _T("-march=k6"), category);
 
142
    m_Options.AddOption(_("AMD K6-2 (MMX, 3DNow!)"), _T("-march=k6-2"), category);
 
143
    m_Options.AddOption(_("AMD K6-3 (MMX, 3DNow!)"), _T("-march=k6-3"), category);
 
144
    m_Options.AddOption(_("AMD Athlon (MMX, 3DNow!, enhanced 3DNow!, SSE prefetch)"), _T("-march=athlon"), category);
 
145
    m_Options.AddOption(_("AMD Athlon Thunderbird (MMX, 3DNow!, enhanced 3DNow!, SSE prefetch)"), _T("-march=athlon-tbird"), category);
 
146
    m_Options.AddOption(_("AMD Athlon 4 (MMX, 3DNow!, enhanced 3DNow!, full SSE)"), _T("-march=athlon-4"), category);
 
147
    m_Options.AddOption(_("AMD Athlon XP (MMX, 3DNow!, enhanced 3DNow!, full SSE)"), _T("-march=athlon-xp"), category);
 
148
    m_Options.AddOption(_("AMD Athlon MP (MMX, 3DNow!, enhanced 3DNow!, full SSE)"), _T("-march=athlon-mp"), category);
 
149
    m_Options.AddOption(_("AMD K8 core (x86-64 instruction set)"), _T("-march=k8"), category);
 
150
    m_Options.AddOption(_("AMD Opteron (x86-64 instruction set)"), _T("-march=opteron"), category);
 
151
    m_Options.AddOption(_("AMD Athlon64 (x86-64 instruction set)"), _T("-march=athlon64"), category);
 
152
    m_Options.AddOption(_("AMD Athlon-FX (x86-64 instruction set)"), _T("-march=athlon-fx"), category);
 
153
 
 
154
    m_Commands[(int)ctCompileObjectCmd].push_back(CompilerTool(_T("$compiler $options $includes -c $file -o $object")));
 
155
    m_Commands[(int)ctGenDependenciesCmd].push_back(CompilerTool(_T("$compiler -MM $options -MF $dep_object -MT $object $includes $file")));
 
156
    m_Commands[(int)ctCompileResourceCmd].push_back(CompilerTool(_T("$rescomp -i $file -J rc -o $resource_output -O coff $res_includes")));
 
157
    m_Commands[(int)ctLinkConsoleExeCmd].push_back(CompilerTool(_T("$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs")));
 
158
    if (platform::windows)
 
159
    {
 
160
        m_Commands[(int)ctLinkNativeCmd].push_back(CompilerTool(_T("$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs --subsystem,native")));
 
161
        m_Commands[(int)ctLinkExeCmd].push_back(CompilerTool(_T("$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs -mwindows")));
 
162
        m_Commands[(int)ctLinkDynamicCmd].push_back(CompilerTool(_T("$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")));
 
163
    }
 
164
    else
 
165
    {
 
166
        m_Commands[(int)ctLinkExeCmd] = m_Commands[(int)ctLinkConsoleExeCmd]; // no -mwindows
 
167
        m_Commands[(int)ctLinkNativeCmd] = m_Commands[(int)ctLinkConsoleExeCmd]; // no -mwindows
 
168
        m_Commands[(int)ctLinkDynamicCmd].push_back(CompilerTool(_T("$linker -shared $libdirs $link_objects $link_resobjects -o $exe_output $link_options $libs")));
 
169
    }
 
170
    m_Commands[(int)ctLinkStaticCmd].push_back(CompilerTool(_T("$lib_linker -r -s $static_output $link_objects")));
 
171
 
 
172
    LoadDefaultRegExArray();
 
173
 
 
174
    m_CompilerOptions.Clear();
 
175
    m_LinkerOptions.Clear();
 
176
    m_LinkLibs.Clear();
 
177
    m_CmdsBefore.Clear();
 
178
    m_CmdsAfter.Clear();
 
179
    SetVersionString();
 
180
}
 
181
 
 
182
void CompilerMINGW::LoadDefaultRegExArray()
 
183
{
 
184
    m_RegExes.Clear();
 
185
    m_RegExes.Add(RegExStruct(_("Fatal error"), cltError, _T("FATAL:[ \t]*(.*)"), 1));
 
186
    m_RegExes.Add(RegExStruct(_("'In function...' info"), cltInfo, _T("(") + FilePathWithSpaces + _T("):[ \t]+") + _T("([iI]n ([cC]lass|[cC]onstructor|[dD]estructor|[fF]unction|[mM]ember [fF]unction).*)"), 2, 1));
 
187
    m_RegExes.Add(RegExStruct(_("'Instantiated from' info"), cltInfo, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t]+([iI]nstantiated from .*)"), 3, 1, 2));
 
188
    m_RegExes.Add(RegExStruct(_("Resource compiler error"), cltError, _T("windres.exe:[ \t](") + FilePathWithSpaces + _T("):([0-9]+):[ \t](.*)"), 3, 1, 2));
 
189
    m_RegExes.Add(RegExStruct(_("Resource compiler error (2)"), cltError, _T("windres.exe:[ \t](.*)"), 1));
 
190
    m_RegExes.Add(RegExStruct(_("Preprocessor warning"), cltWarning, _T("(") + FilePathWithSpaces + _T("):([0-9]+):([0-9]+):[ \t]([Ww]arning:[ \t].*)"), 4, 1, 2));
 
191
    m_RegExes.Add(RegExStruct(_("Preprocessor error"), cltError, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[0-9]+:[ \t](.*)"), 3, 1, 2));
 
192
    m_RegExes.Add(RegExStruct(_("Compiler note"), cltInfo, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t]([Nn]ote:[ \t].*)"), 3, 1, 2));
 
193
    m_RegExes.Add(RegExStruct(_("General note"), cltInfo, _T("([Nn]ote:[ \t].*)"), 1));
 
194
    m_RegExes.Add(RegExStruct(_("Compiler warning"), cltWarning, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t]([Ww]arning:[ \t].*)"), 3, 1, 2));
 
195
    m_RegExes.Add(RegExStruct(_("Compiler error"), cltError, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t](.*)"), 3, 1, 2));
 
196
    m_RegExes.Add(RegExStruct(_("Linker error"), cltError, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[0-9]+:[ \t](.*)"), 3, 1, 2));
 
197
    m_RegExes.Add(RegExStruct(_("Linker error (2)"), cltError, FilePathWithSpaces + _T("\\(.text\\+[0-9A-Za-z]+\\):([ \tA-Za-z0-9_:+/\\.-]+):[ \t](.*)"), 2, 1));
 
198
    m_RegExes.Add(RegExStruct(_("Linker error (lib not found)"), cltError, _T(".*(ld.*):[ \t](cannot find.*)"), 2, 1));
 
199
    m_RegExes.Add(RegExStruct(_("Undefined reference"), cltError, _T("(") + FilePathWithSpaces + _T("):[ \t](undefined reference.*)"), 2, 1));
 
200
    m_RegExes.Add(RegExStruct(_("General warning"), cltWarning, _T("([Ww]arning:[ \t].*)"), 1));
 
201
    m_RegExes.Add(RegExStruct(_("Auto-import info"), cltInfo, _T("([Ii]nfo:[ \t].*)\\(auto-import\\)"), 1));
 
202
}
 
203
 
 
204
AutoDetectResult CompilerMINGW::AutoDetectInstallationDir()
 
205
{
 
206
    // try to find MinGW in environment variable PATH first
 
207
    wxPathList list;
 
208
    list.AddEnvList(_T("PATH"));
 
209
    wxString path = list.FindAbsoluteValidPath(m_Programs.C);
 
210
    if (!path.IsEmpty())
 
211
    {
 
212
        wxFileName fname(path);
 
213
        fname.RemoveLastDir();
 
214
        m_MasterPath = fname.GetPath(wxPATH_GET_VOLUME);
 
215
        return adrDetected;
 
216
    }
 
217
 
 
218
    wxString sep = wxFileName::GetPathSeparator();
 
219
    if (platform::windows)
 
220
    {
 
221
        // look first if MinGW was installed with Code::Blocks (new in beta6)
 
222
        m_MasterPath = ConfigManager::GetExecutableFolder();
 
223
        if (!wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C))
 
224
            // if that didn't do it, look under C::B\MinGW, too (new in 08.02)
 
225
            m_MasterPath += sep + _T("MinGW");
 
226
        if (!wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C))
 
227
        {
 
228
            // no... search for MinGW installation dir
 
229
            wxString windir = wxGetOSDirectory();
 
230
            wxFileConfig ini(_T(""), _T(""), windir + _T("/MinGW.ini"), _T(""), wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_NO_ESCAPE_CHARACTERS);
 
231
            m_MasterPath = ini.Read(_T("/InstallSettings/InstallPath"), _T("C:\\MinGW"));
 
232
            if (!wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C))
 
233
            {
 
234
#ifdef __WXMSW__ // for wxRegKey
 
235
                // not found...
 
236
                // look for dev-cpp installation
 
237
                wxRegKey key; // defaults to HKCR
 
238
                key.SetName(_T("HKEY_LOCAL_MACHINE\\Software\\Dev-C++"));
 
239
                if (key.Exists() && key.Open(wxRegKey::Read))
 
240
                {
 
241
                    // found; read it
 
242
                    key.QueryValue(_T("Install_Dir"), m_MasterPath);
 
243
                }
 
244
                else
 
245
                {
 
246
                    // installed by inno-setup
 
247
                    // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Minimalist GNU for Windows 4.1_is1
 
248
                    wxString name;
 
249
                    long index;
 
250
                    key.SetName(_T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
 
251
                    //key.SetName("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion");
 
252
                    bool ok = key.GetFirstKey(name, index);
 
253
                    while (ok && !name.StartsWith(_T("Minimalist GNU for Windows")))
 
254
                    {
 
255
                        ok = key.GetNextKey(name, index);
 
256
                    }
 
257
                    if (ok)
 
258
                    {
 
259
                        name = key.GetName() + _T("\\") + name;
 
260
                        key.SetName(name);
 
261
                        if (key.Exists() && key.Open(wxRegKey::Read))
 
262
                            key.QueryValue(_T("InstallLocation"), m_MasterPath);
 
263
                    }
 
264
                }
 
265
#endif
 
266
            }
 
267
        }
 
268
        else
 
269
            m_Programs.MAKE = _T("make.exe"); // we distribute "make" not "mingw32-make"
 
270
    }
 
271
    else
 
272
        m_MasterPath = _T("/usr");
 
273
 
 
274
    AutoDetectResult ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C) ? adrDetected : adrGuessed;
 
275
    // don't add lib/include dirs. GCC knows where its files are located
 
276
 
 
277
    SetVersionString();
 
278
    return ret;
 
279
}
 
280
 
 
281
void CompilerMINGW::SetVersionString()
 
282
{
 
283
    wxArrayString output, errors;
 
284
    wxString sep = wxFileName::GetPathSeparator();
 
285
    wxString masterpath = m_MasterPath;
 
286
 
 
287
    /* We should read the master path from the configuration manager as
 
288
     * the m_MasterPath is empty if AutoDetectInstallationDir() is not
 
289
     * called
 
290
     */
 
291
    ConfigManager* cmgr = Manager::Get()->GetConfigManager(_T("compiler"));
 
292
    if (cmgr)
 
293
        cmgr->Read(_T("/sets/gcc/master_path"), &masterpath);
 
294
 
 
295
    if (masterpath.IsEmpty())
 
296
    {
 
297
        if (platform::windows)
 
298
            masterpath = _T("C:\\MinGW");
 
299
        else
 
300
            masterpath = _T("/usr");
 
301
    }
 
302
    wxString gcc_command = masterpath + sep + _T("bin") + sep + m_Programs.C;
 
303
    if (!wxFileExists(gcc_command))
 
304
        return;
 
305
    long result = wxExecute(gcc_command + _T(" --version"), output, errors, wxEXEC_NODISABLE);
 
306
    if (result > 0)
 
307
    {
 
308
        Manager::Get()->GetLogManager()->DebugLog(_T("Error in executing ") + gcc_command);
 
309
    }
 
310
    else
 
311
    {
 
312
        if (output.GetCount() > 0)
 
313
        {
 
314
            wxRegEx reg_exp;
 
315
            if (reg_exp.Compile(_T("[0-9][.][0-9][.][0-9]")) && reg_exp.Matches(output[0]))
 
316
                m_VersionString = reg_exp.GetMatch(output[0]);
 
317
            else
 
318
            {
 
319
                m_VersionString = output[0].Mid(10);
 
320
                m_VersionString = m_VersionString.Left(5);
 
321
                m_VersionString.Trim(false);
 
322
            }
 
323
        }
 
324
    }
 
325
}