I'll try myself, feel free to inspect and try, too...
Comments?
Another one to test:
void CompilerGCC::SetupEnvironment()
{
Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
if (!compiler)
return;
wxString currentPath;
if ( !wxGetEnv(_T("PATH"), ¤tPath) )
{
InfoWindow::Display(_("Environment error"),
_("Could not read the PATH environment variable!\n"
"This can't be good. There may be problems running\n"
"system commands and the application might not behave\n"
"the way it was designed to..."),
15000, 3000);
return;
}
Manager::Get()->GetLogManager()->DebugLogError(_T("PATH environment:"));
Manager::Get()->GetLogManager()->DebugLogError(currentPath);
const wxString sep=platform::windows?_T(";"):_T(":");
const wxString pathSep = wxFileName::GetPathSeparator(); // "\\" or "/"
wxString cApp = compiler->GetPrograms().C;
wxArrayString extraPaths = compiler->GetExtraPaths();
wxString extraPathsBinPath(wxEmptyString);
// Get configured masterpath, expand macros and remove trailing seperators
wxString masterPath = compiler->GetMasterPath();
Manager::Get()->GetMacrosManager()->ReplaceMacros(masterPath);
while (masterPath.Last() == '\\' || masterPath.Last() == '/')
masterPath.RemoveLast();
// Prepend "masterpath/bin" and "masterpath"
wxPathList pathList;
if ( !masterPath.Trim().IsEmpty() ) // would be very bad, if it *is* empty
{
pathList.Add(masterPath + pathSep + _T("bin"));
pathList.Add(masterPath); // in case there is no "bin" sub-folder
}
// Get configured extrapath(s), expand macros and remove trailing seperators
for (size_t i=0; i<extraPaths.GetCount(); ++i)
{
wxString extraPath = extraPaths[i];
Manager::Get()->GetMacrosManager()->ReplaceMacros(extraPath);
while (extraPath.Last() == '\\' || extraPath.Last() == '/')
extraPath.RemoveLast();
if (!extraPath.Trim().IsEmpty())
{
// Remember, if we found the C application in the extra path's:
if ( extraPathsBinPath.IsEmpty()
&& wxFileExists(extraPath + pathSep + cApp ) )
extraPathsBinPath = extraPath;
pathList.Add(extraPath);
}
}
// append what has already been in the PATH envvar
// if we do it this way, paths are automatically normalized
// and doubles are removed
wxPathList pathArray;
pathArray.AddEnvList(_T("PATH"));
pathList.Add(pathArray);
bool caseSense = !(platform::windows);
// try to locate the path to the C compiler:
wxString binPath = pathList.FindAbsoluteValidPath(cApp);
// it seems, under Win32, the above command doesn't search in paths with spaces...
// look directly for the file in question in masterPath if it is not already found
if (binPath.IsEmpty()
|| (pathList.Index(wxPathOnly(binPath), caseSense) == wxNOT_FOUND) )
{
if (wxFileExists(masterPath + pathSep + _T("bin") + pathSep + cApp))
binPath = masterPath + pathSep + _T("bin");
else if (wxFileExists(masterPath + pathSep + cApp))
binPath = masterPath;
else if (!extraPathsBinPath.IsEmpty())
binPath = extraPathsBinPath;
}
else
binPath = wxPathOnly(binPath);
/* TODO (jens#1#): Is the above correct ?
Or should we search in the whole systempath (pathList in this case) for the executable ?*/
// Try again...
if ( binPath.IsEmpty() ||
(pathList.Index(wxPathOnly(binPath), caseSense) == wxNOT_FOUND) )
{
InfoWindow::Display(_("Environment error"),
_("Can't find compiler executable in your configured search path's for ") + compiler->GetName() + _T('\n'));
Manager::Get()->GetLogManager()->DebugLogError(F(_T("Can't find compiler executable in your configured search path's (for %s)..."), compiler->GetName().wx_str()));
return; // failed to locate compiler executable in path's as provided
}
// Convert the pathList into a string to apply.
wxString envPath(binPath); // make sure the bin-path we found is in front
// and remove it from pathList
pathList.Remove(binPath);
for (size_t i=0; i<pathList.GetCount(); ++i)
{
envPath += (sep + pathList[i] );
}
Manager::Get()->GetLogManager()->DebugLogError(_T("Updating compiler PATH environment:"));
Manager::Get()->GetLogManager()->DebugLogError(envPath);
wxSetEnv(_T("PATH"), envPath);
}
I mades some changes, they are mostly commented in the sources.
It avoids the trailing path-seperators in the path(s) and the trailing seperator at the end of the system-path value.
I use the ability of wxPathList to avoid doubles and to normalize the paths, to avoid redundance.
I do not use
m_EnvironmentMsg, because it isonly used for generated makefiles, which are not supported since ages.
It's tested on linux, but not (yet) on windows, seems to work as expected.
By the way (and off-topic here):
I think we should remove all the makefile generation stuff from our sources, because it is not used anymore.
We have a working (as far as I know) tool from the community to create makefiles from project files, that works (again as far as I know) much better and can surely be wrapped by (or possibly be converted to) a plugin to fully integrate it into C::B.
EDIT:I think it's safer to use:
wxPathList pathArray;
pathArray.AddEnvList(_T("PATH"));
instead of
wxArrayString pathArray = GetArrayFromString(currentPath, sep);
I changed it in the codesnippet above.