Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development

EnvVars Plugin and PATH

<< < (9/9)

Jenna:

--- Quote from: MortenMacFly on February 13, 2012, 11:53:18 am ---I'll try myself, feel free to inspect and try, too...

Comments?

--- End quote ---

Another one to test:

--- Code: ---void CompilerGCC::SetupEnvironment()
{
    Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);

    if (!compiler)
        return;

    wxString currentPath;
    if ( !wxGetEnv(_T("PATH"), &currentPath) )
    {
        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);
}
--- End code ---

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:

--- Code: ---    wxPathList pathArray;
    pathArray.AddEnvList(_T("PATH"));

--- End code ---

instead of


--- Code: ---    wxArrayString pathArray = GetArrayFromString(currentPath, sep);

--- End code ---

I changed it in the codesnippet above.

MortenMacFly:

--- Quote from: jens on February 14, 2012, 09:10:18 am ---Another one to test:

--- End quote ---
Looks fine to me, too.


--- Quote from: jens on February 14, 2012, 09:10:18 am ---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.

--- End quote ---
Certainly tru. And (in fact) I did this already in my local copy literally since ages. I have a rather cleaned-up compiler plugin basically ready to commit for that purpose (that's also, why I can hardly provide true patches). So if there are no objections, I could step-by-step commit the changes.

MortenMacFly:
Concerning this:

--- Quote from: jens on February 14, 2012, 09:10:18 am ---
--- Code: ---    /* TODO (jens#1#): Is the above correct ?
       Or should we search in the whole systempath (pathList in this case) for the executable? */

--- End code ---

--- End quote ---
Yes, I think its correct. We should enforce that the user does a correct setup of the compiler. Otherwise we don't know, if we picked the right compiler if we search the whole system path. We may even find a wrong one, probably for another platform (avr) which we pick then as "correct". This can only go wrong and we will have a lot of trouble question in the forums hard to track.

But what might be wrong is the fact, tat we only check for the C compiler. For a C++ project this might not be needed. And for a Makefile project not, too.

ollydbg:
Is this issue fixed in the trunk?

To solve the problem I describe here: Does Compiler plugin automatically add lib search path to PATH environment, I need to modify PATH variable in the EnvVars plugin by setting the PATH variable to "%PATH%;E:\code\opencv\OpenCV-2.4.4\opencv\build\x86\mingw\bin;E:\code\gcc\nixman463dw2\bin", just the steps described in pkrcel's original post EnvVars Plugin and PATH, it works OK (C::B rev 8896)

I'm not clear how compiler plugin modify PATH, in my case, my compiler Tool Chain executable path is: E:\code\gcc\PCXMinGW463, but as the opencv library is prebuild, it need a libstdc++-6.dll, so I add the E:\code\gcc\nixman463dw2\bin to the PATH. So, I can guess that when compiling, I have two gcc paths. Does the compiler plugin always put the "Tool Chain executable path" path in the front of the PATH? I mean, the executables under "E:\code\gcc\PCXMinGW463" will be chosen to build my app?

Navigation

[0] Message Index

[*] Previous page

Go to full version