Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development
EnvVars Plugin and PATH
Jenna:
--- Quote from: MortenMacFly on February 13, 2012, 10:26:18 am ---I guess instead off caching, a better solution would be:
- you read what's currently in the PATH
- you check what needs to be prepended (so it is the folder looked into first)
- if it's not already in the PATH (at front) you put it there in front
So, assume you path is as follows:
C:\LALA
Your projects uses MinGW, so you need to prepend C:\MinGW\bin and C:\Tools\Bin, you end up in:
C:\MinGW\bin;C:\Tools\Bin;C:\LALA
Next time, you use MSVC, so you need to prepend C:\MSVC\bin and C:\WinSDK\Bin you end up in:
C:\MSVC\bin;C:\WinSDK\Bin;C:\MinGW\bin;C:\Tools\Bin;C:\LALA
Next time, you use MinGW again, you end up in:
C:\MinGW\bin;C:\Tools\Bin;C:\MSVC\bin;C:\WinSDK\Bin;C:\MinGW\bin;C:\Tools\Bin;C:\LALA
A clean-up step could remove any obsolete / path's appearing twice. I think there is even a nice wxWidgets class for this, namely wxPathList that helps a lot with the dirty work.
EDIT: One thing to consider for us are macros here btw!
--- End quote ---
That should be more or less what is done at the moment, see:
http://svn.berlios.de/wsvn/codeblocks/?op=revision&rev=5344&peg=5344
Needed master path and extra path always are prepended, to come first, doubles are removed.
If the toolchain is not setup correctly, there is nothing we can do in any case.
Actually we should get a path that looks like:
masterpath;extrapaths(s);currentpath_without_masterpath_and_extrapath(s)
Or with your example:
* C:\LALA
* C:\MinGW\bin;C:\Tools\Bin;C:\LALA
* C:\MSVC\bin;C:\WinSDK\Bin;C:\MinGW\bin;C:\Tools\Bin;C:\LALA
* C:\MinGW\bin;C:\Tools\Bin;C:\MSVC\bin;C:\WinSDK\Bin;C:\LALA
MortenMacFly:
--- Quote from: jens on February 13, 2012, 11:07:38 am ---That should be more or less what is done at the moment, see:
http://svn.berlios.de/wsvn/codeblocks/?op=revision&rev=5344&peg=5344
--- End quote ---
Yes, I've seen that already... But the current code is (sorry to say that, but...) a mess. :(
--- Quote from: jens on February 13, 2012, 11:07:38 am ---Actually we should get a path that looks like:
masterpath;extrapaths(s);currentpath_without_masterpath_and_extrapath(s)
--- End quote ---
Working on that... got it soon... will post here... ;-)
Jenna:
--- Quote from: MortenMacFly on February 13, 2012, 11:18:53 am ---
--- Quote from: jens on February 13, 2012, 11:07:38 am ---That should be more or less what is done at the moment, see:
http://svn.berlios.de/wsvn/codeblocks/?op=revision&rev=5344&peg=5344
--- End quote ---
Yes, I've seen that already... But the current code is (sorry to say that, but...) a mess. :(
--- End quote ---
That's correct, it's grown over some years and was never cleaned up.
So it looks chaotic and has codeparts that are no longer used (like oldpath).
--- Quote from: MortenMacFly on February 13, 2012, 11:18:53 am ---
--- Quote from: jens on February 13, 2012, 11:07:38 am ---Actually we should get a path that looks like:
masterpath;extrapaths(s);currentpath_without_masterpath_and_extrapath(s)
--- End quote ---
Working on that... got it soon... will post here... ;-)
--- End quote ---
It should work exactly like this at the moment, and it should be platform independent due to the use of wxPathList (without the need for us to care about different PATH-specs).
But the main question was/is:
do we really need to cache the systempath.
Can it be harmful not to do it (besides a probably misconfiguration by the user) ?
MortenMacFly:
--- Quote from: jens on February 13, 2012, 11:31:28 am ---But the main question was/is:
do we really need to cache the systempath.
Can it be harmful not to do it (besides a probably misconfiguration by the user) ?
--- End quote ---
No, we don't - that's the root of the original issue.
OK - I did some clean-up, merged the two methods into one as you proposed. Here is the new code, that should be really bullet-proof:
--- Code: ---void CompilerGCC::SetupEnvironment()
{
if (!CompilerFactory::GetCompiler(m_CompilerId))
return;
m_EnvironmentMsg.Clear();
// look for valid compiler in path
wxString pathDummy;
if ( !wxGetEnv(_T("PATH"), &pathDummy) )
{
m_EnvironmentMsg = _("Could not read the PATH environment variable!\n"
"This can't be good. There may be problems running "
"system commands and the application might not behave "
"the way it was designed to...");
return;
}
Manager::Get()->GetLogManager()->DebugLog(_T("PATH environment:"));
Manager::Get()->GetLogManager()->DebugLog(pathDummy);
const wxString pathSep = wxFileName::GetPathSeparator(); // "\\" or "/"
// Pre-pend the compiler's master path
Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
if (!compiler)
return;
wxString masterPath = compiler->GetMasterPath();
Manager::Get()->GetMacrosManager()->ReplaceMacros(masterPath);
while (masterPath.Last() == '\\' || masterPath.Last() == '/')
masterPath.RemoveLast();
wxString cApp = compiler->GetPrograms().C;
wxArrayString extraPaths = compiler->GetExtraPaths();
wxString extraPathsBinPath(wxEmptyString);
// compile new PATH list:
wxPathList pathList;
if ( !masterPath.Trim().IsEmpty() ) // would be very bad, if it *is* empty
{
// pre-pend "master path", "master path\bin" and "extra path's"
pathList.Add(masterPath); // in case there is no "bin" sub-folder
pathList.Add(masterPath + pathSep + _T("bin"));
}
for (unsigned int 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
pathList.AddEnvList(_T("PATH"));
bool caseSens = !(platform::windows);
// try to locate the path to the C compiler:
// it seems, under Win32, the above command doesn't search in paths with spaces...
// look directly for the file in question in masterPath
wxString binPath = pathList.FindAbsoluteValidPath(cApp);
if ( binPath.IsEmpty()
|| (pathList.Index(wxPathOnly(binPath), caseSens) == 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);
// Try again...
if ( binPath.IsEmpty()
|| (pathList.Index(wxPathOnly(binPath), caseSens)==wxNOT_FOUND) )
{
m_EnvironmentMsg << _("Can't find compiler executable in your search path's for ") << compiler->GetName() << _T('\n');
Manager::Get()->GetLogManager()->DebugLog(F(_T("Can't find compiler executable in your search path's (for %s)..."), compiler->GetName().wx_str()));
return; // failed to locate compiler executable in path's as provided
}
// Clean-up step: Locate duplicate entries and remove them
wxArrayString envPathArr;
for (size_t i=0; i<pathList.GetCount(); ++i)
{
wxString path = pathList[i].Trim();
while (path.Last() == '\\' || path.Last() == '/')
path.RemoveLast();
if ( !path.IsEmpty() )
{
path += pathSep;
if ( envPathArr.Index(path, caseSens)==wxNOT_FOUND )
envPathArr.Add(path);
}
}
// Compile the separator used to separate path's in envvars:
wxString path_app; // used in envvar to separate path's
if (platform::windows) path_app = _T(";"); else path_app = _T(":");
// Convert the PATH variable array into a string to apply.
wxString envPath(binPath + pathSep + path_app); // make sure the bin-path we found is in front
for (size_t i=0; i<envPathArr.GetCount(); ++i)
{
// Skip path to binary we added in front already:
if ( !envPathArr[i].IsSameAs(binPath + pathSep) )
envPath += (envPathArr[i] + path_app);
}
Manager::Get()->GetLogManager()->DebugLog(_T("Updating compiler PATH environment:"));
Manager::Get()->GetLogManager()->DebugLog(envPath);
wxSetEnv(_T("PATH"), envPath);
}
--- End code ---
EDIT: For syntax highlighting, see here:
http://pastebin.com/AcXYpNr3
I'll try myself, feel free to inspect and try, too...
Comments?
oBFusCATed:
--- Quote from: MortenMacFly on February 13, 2012, 11:53:18 am ---Comments?
--- End quote ---
// Style zealot hat on
Calling Manager::Get()->GetXXXManager() on multiple lines looks wrong and ugly to me
// Style zealot hat off
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version