void CompileOptionsBase::RemoveLibDir(const wxString& option)
{
    wxString entry = UnixFilename(option);
    int idx = m_LibDirs.Index(entry, case_sensitive);
    if (idx != wxNOT_FOUND)
    {
        m_LibDirs.RemoveAt(idx);
        SetModified(true);
    }
}
Пример #2
0
void CompileOptionsBase::RemoveBuildScript(const wxString& script)
{
    wxString envopt = UnixFilename(script);
    int idx = m_Scripts.Index(envopt, case_sensitive);
    if (idx != wxNOT_FOUND)
    {
        m_Scripts.RemoveAt(idx);
        SetModified(true);
    }
}
Пример #3
0
void ConfigManager::InitPaths()
{
    ConfigManager::config_folder = ConfigManager::GetUserDataFolder();
    ConfigManager::home_folder = wxStandardPathsBase::Get().GetUserConfigDir();
    ConfigManager::app_path = ::DetermineExecutablePath();
    wxString res_path = ::DetermineResourcesPath();

    // if non-empty, the app has overriden it (e.g. "--prefix" was passed in the command line)
    if (data_path_global.IsEmpty())
    {
        if (platform::windows)
            ConfigManager::data_path_global = app_path + _T("\\share\\codeblocks");
        else if (platform::macosx)
            ConfigManager::data_path_global = res_path + _T("/share/codeblocks");
        else
            ConfigManager::data_path_global = wxStandardPathsBase::Get().GetDataDir();
    }
    else
        ConfigManager::data_path_global = UnixFilename(data_path_global);

#ifdef CB_AUTOCONF
    if (plugin_path_global.IsEmpty())
    {
        if (platform::windows || platform::macosx)
            ConfigManager::plugin_path_global = data_path_global;
        else
        {
            // It seems we can not longer rely on wxStandardPathsBase::Get().GetPluginsDir(),
            // because its behaviour has changed on some systems (at least Fedora 14 64-bit).
            // So we create the pathname manually
            ConfigManager::plugin_path_global = ((const wxStandardPaths&)wxStandardPaths::Get()).GetInstallPrefix() + _T("/lib/codeblocks/plugins");
            // first assume, we use standard-paths
            if (!wxDirExists(ConfigManager::plugin_path_global) && wxIsPlatform64Bit())
            {
                // if standard-path does not exist and we are on 64-bit system, use lib64 instead
                ConfigManager::plugin_path_global = ((const wxStandardPaths&)wxStandardPaths::Get()).GetInstallPrefix() + _T("/lib64/codeblocks/plugins");
            }
        }
    }
#endif

    wxString dataPathUser = ConfigManager::config_folder + wxFILE_SEP_PATH + _T("share");
#ifdef __linux__
    if (!has_alternate_user_data_path)
      dataPathUser = wxString::FromUTF8(g_build_filename (g_get_user_data_dir(), NULL));
#endif // __linux__

    ConfigManager::data_path_user = dataPathUser + wxFILE_SEP_PATH + _T("codeblocks");

    CreateDirRecursively(ConfigManager::config_folder);
    CreateDirRecursively(ConfigManager::data_path_user   + _T("/plugins/"));
    CreateDir(ConfigManager::data_path_user   + _T("/scripts/"));

    ConfigManager::temp_folder = wxStandardPathsBase::Get().GetTempDir();
}
Пример #4
0
// class constructor
PipedProcess::PipedProcess(void** pvThis, wxEvtHandler* parent, int id, bool pipe, const wxString& dir)
    : wxProcess(parent, id),
	m_Parent(parent),
	m_Id(id),
	m_Pid(0),
	m_pvThis(pvThis)
{
	wxSetWorkingDirectory(UnixFilename(dir));
	if (pipe)
		Redirect();
}
Пример #5
0
// class constructor
PipedProcess::PipedProcess(PipedProcess** pvThis, wxEvtHandler* parent, int id, bool pipe, const wxString& dir)
    : wxProcess(parent, id),
    m_Parent(parent),
    m_Id(id),
    m_Pid(0),
    m_pvThis(pvThis)
{
    const wxString &unixDir = UnixFilename(dir);
    if (!unixDir.empty())
        wxSetWorkingDirectory(unixDir);
    if (pipe)
        Redirect();
}
void CompileTargetBase::SetImportLibraryFilename(const wxString& filename)
{
    if (filename.IsEmpty())
    {
        m_ImportLibraryFilename = _T("$(TARGET_NAME)");
        SetModified(true);
        return;
    }
    else if (m_ImportLibraryFilename == filename)
        return;

    m_ImportLibraryFilename = UnixFilename(filename);
}
void CompileTargetBase::SetOutputFilename(const wxString& filename)
{
    if (filename.IsEmpty())
    {
        m_OutputFilename = SuggestOutputFilename();
        SetModified(true);
        return;
    }
    else if (m_OutputFilename == filename)
        return;
    m_OutputFilename = UnixFilename(filename);
    GenerateTargetFilename(m_OutputFilename);
    SetModified(true);
}
Пример #8
0
wxString ParserBase::FindFirstFileInIncludeDirs(const wxString& file)
{
    wxString FirstFound = m_GlobalIncludes.GetItem(file);
    if (FirstFound.IsEmpty())
    {
        wxArrayString FoundSet = FindFileInIncludeDirs(file,true);
        if (FoundSet.GetCount())
        {
            FirstFound = UnixFilename(FoundSet[0]);
            m_GlobalIncludes.AddItem(file, FirstFound);
        }
    }
    return FirstFound;
}
void CompileOptionsBase::SetBuildScripts(const wxArrayString& scripts)
{
    if (m_Scripts == scripts)
        return;

    // make sure we don't have duplicate entries
    // that's why we don't assign the array but rather copy it entry by entry...

    m_Scripts.Clear();
    for (size_t i = 0; i < scripts.GetCount(); ++i)
    {
        wxString entry = UnixFilename(scripts[i]);
        if (m_Scripts.Index(entry, case_sensitive) == wxNOT_FOUND)
            m_Scripts.Add(entry);
    }
    SetModified(true);
}
Пример #10
0
bool Parser::RemoveFile(const wxString& filename)
{
    TRACK_THREAD_LOCKER(s_TokensTreeCritical);
    wxCriticalSectionLocker locker(s_TokensTreeCritical);
    THREAD_LOCKER_SUCCESS(s_TokensTreeCritical);

    size_t index = m_TokensTree->GetFileIndex(UnixFilename(filename));
    const bool result = m_TokensTree->m_FilesStatus.count(index);

    m_TokensTree->RemoveFile(filename);
    m_TokensTree->m_FilesMap.erase(index);
    m_TokensTree->m_FilesStatus.erase(index);
    m_TokensTree->m_FilesToBeReparsed.erase(index);
    m_TokensTree->m_Modified = true;

    return result;
}
wxString CompileTargetBase::SuggestOutputFilename()
{
    wxString suggestion;
    switch (m_TargetType)
    {
        case ttConsoleOnly: // fall through
        case ttExecutable:  suggestion = GetExecutableFilename(); break;
        case ttDynamicLib:  suggestion = GetDynamicLibFilename(); break;
        case ttStaticLib:   suggestion = GetStaticLibFilename();  break;
        case ttNative:      suggestion = GetNativeFilename();     break;
        default:
            suggestion.Clear();
            break;
    }
    wxFileName fname(suggestion);
    return UnixFilename(fname.GetFullName());
}
Пример #12
0
bool Parser::AddFile(const wxString& filename, cbProject* project, bool isLocal)
{
    if (project != m_Project)
        return false;

    wxString file = UnixFilename(filename);
    if (IsFileParsed(file))
        return false;

    if (m_ParsingType == ptUndefined)
        m_ParsingType = ptAddFileToParser;

    AddParse(file);
    if (project)
        m_NeedMarkFileAsLocal = true;

    return true;
}
Пример #13
0
bool ScriptingManager::LoadBuffer(const wxString& buffer, const wxString& debugName)
{
    // includes guard to avoid recursion
    wxString incName = UnixFilename(debugName);
    if (m_IncludeSet.find(incName) != m_IncludeSet.end())
    {
        Manager::Get()->GetLogManager()->LogWarning(F(_T("Ignoring Include(\"%s\") because it would cause recursion..."), incName.wx_str()));
        return true;
    }
    m_IncludeSet.insert(incName);

//    wxCriticalSectionLocker c(cs);

    s_ScriptErrors.Clear();

    // compile script
    SquirrelObject script;
    try
    {
        script = SquirrelVM::CompileBuffer(cbU2C(buffer), cbU2C(debugName));
    }
    catch (SquirrelError e)
    {
        cbMessageBox(wxString::Format(_T("Filename: %s\nError: %s\nDetails: %s"), debugName.c_str(), cbC2U(e.desc).c_str(), s_ScriptErrors.c_str()), _("Script compile error"), wxICON_ERROR);
        m_IncludeSet.erase(incName);
        return false;
    }

    // run script
    try
    {
        SquirrelVM::RunScript(script);
    }
    catch (SquirrelError e)
    {
        cbMessageBox(wxString::Format(_T("Filename: %s\nError: %s\nDetails: %s"), debugName.c_str(), cbC2U(e.desc).c_str(), s_ScriptErrors.c_str()), _("Script run error"), wxICON_ERROR);
        m_IncludeSet.erase(incName);
        return false;
    }
    m_IncludeSet.erase(incName);
    return true;
}
Пример #14
0
size_t ParserBase::FindTokensInFile(const wxString& fileName, TokenIdxSet& result, short int kindMask)
{
    result.clear();
    wxString file = UnixFilename(fileName);
    TRACE(_T("Parser::FindTokensInFile() : Searching for file '%s' in tokens tree..."), file.wx_str());

    TRACK_THREAD_LOCKER(s_TokensTreeCritical);
    wxCriticalSectionLocker locker(s_TokensTreeCritical);
    THREAD_LOCKER_SUCCESS(s_TokensTreeCritical);

    TokenIdxSet tmpresult;
    if ( !m_TokensTree->FindTokensInFile(file, tmpresult, kindMask) )
        return 0;

    for (TokenIdxSet::iterator it = tmpresult.begin(); it != tmpresult.end(); ++it)
    {
        Token* token = m_TokensTree->at(*it);
        if (token)
            result.insert(*it);
    }
    return result.size();
}
void PluginsConfigurationDlg::FillList()
{
    wxListCtrl* list = XRCCTRL(*this, "lstPlugins", wxListCtrl);
    if (list->GetColumnCount() == 0)
    {
        list->InsertColumn(0, _T("Title"));
        list->InsertColumn(1, _T("Version"));
        list->InsertColumn(2, _T("Enabled"), wxLIST_FORMAT_CENTER);
        list->InsertColumn(3, _T("Filename"));
    }

    PluginManager* man = Manager::Get()->GetPluginManager();
    const PluginElementsArray& plugins = man->GetPlugins();

    // populate Plugins checklist
    list->DeleteAllItems();
    for (unsigned int i = 0; i < plugins.GetCount(); ++i)
    {
        const PluginElement* elem = plugins[i];

        long idx = list->InsertItem(i, elem->info.title);
        list->SetItem(idx, 1, elem->info.version);
        list->SetItem(idx, 2, elem->plugin->IsAttached() ? _("Yes") : _("No"));
        list->SetItem(idx, 3, UnixFilename(elem->fileName));
        list->SetItemData(idx, (long)elem);

        if (!elem->plugin->IsAttached())
            list->SetItemTextColour(idx, wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
        else
            list->SetItemTextColour(idx, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
    }

    list->SetColumnWidth(0, wxLIST_AUTOSIZE);
    list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
    list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
    list->SetColumnWidth(3, wxLIST_AUTOSIZE);

    list->SortItems(sortByTitle, 0);
}
Пример #16
0
void MSVC10Loader::SetConfigurationValuesPath(const TiXmlElement* root, const char* key, size_t target, const wxString& defconfig, wxString* globaltarget)
{
    wxString config;
    for (const TiXmlElement* e=root->FirstChildElement(key); e; e=e->NextSiblingElement(key))
    {
        if (!GetConfigurationName(e,config,defconfig))
          continue;

        wxString* value;
        if (config.IsEmpty())
        {
            if (!globaltarget) continue;
            value = globaltarget;
        }
        else
            value = (wxString*)((char*)&m_pc[config]+target);

        *value = UnixFilename(GetText(e));
        if ((*value).Last()!=wxFILE_SEP_PATH)
            *value += wxFILE_SEP_PATH;
    }
}
Пример #17
0
bool Parser::IsFileParsed(const wxString& filename)
{
    bool isParsed = false;
    {
        TRACK_THREAD_LOCKER(s_TokensTreeCritical);
        wxCriticalSectionLocker locker(s_TokensTreeCritical);
        THREAD_LOCKER_SUCCESS(s_TokensTreeCritical);

        isParsed = m_TokensTree->IsFileParsed(UnixFilename(filename));
    }

    if (!isParsed)
    {
        TRACK_THREAD_LOCKER(s_ParserCritical);
        wxCriticalSectionLocker locker(s_ParserCritical);
        THREAD_LOCKER_SUCCESS(s_ParserCritical);

        StringList::iterator it = std::find(m_BatchParseFiles.begin(), m_BatchParseFiles.end(), filename);
        isParsed = it != m_BatchParseFiles.end();
    }

    return isParsed;
}
Пример #18
0
/** external deps are manually set by the user
  * e.g. a static library linked to the project is an external dep (if set as such by the user)
  * so that a re-linking is forced if the static lib is updated
  */
bool DirectCommands::AreExternalDepsOutdated(ProjectBuildTarget* target,
                                             const wxString& buildOutput,
                                             wxArrayString*  filesMissing) const
{
    Compiler* compiler = CompilerFactory::GetCompiler(target->GetCompilerID());

    // if no output, probably a commands-only target; nothing to relink
    // but we have to check other dependencies
    time_t timeOutput = 0;
    if (!buildOutput.IsEmpty())
    {
        wxString output = buildOutput;
        Manager::Get()->GetMacrosManager()->ReplaceMacros(output);
        depsTimeStamp(output.mb_str(), &timeOutput);
        // if build output exists, check for updated static libraries
        if (timeOutput)
        {
            // look for static libraries in target/project library dirs
            wxArrayString libs = target->GetLinkLibs();
            const wxArrayString& prjLibs = target->GetParentProject()->GetLinkLibs();
            const wxArrayString& cmpLibs = compiler->GetLinkLibs();
            AppendArray(prjLibs, libs);
            AppendArray(cmpLibs, libs);

            const wxArrayString& prjLibDirs = target->GetParentProject()->GetLibDirs();
            const wxArrayString& cmpLibDirs = compiler->GetLibDirs();
            wxArrayString libDirs = target->GetLibDirs();
            AppendArray(prjLibDirs, libDirs);
            AppendArray(cmpLibDirs, libDirs);

            for (size_t i = 0; i < libs.GetCount(); ++i)
            {
                wxString lib = libs[i];

                // if user manually pointed to a library, without using the lib dirs,
                // then just check the file directly w/out involving the search dirs...
                if (lib.Contains(_T("/")) || lib.Contains(_T("\\")))
                {
                    Manager::Get()->GetMacrosManager()->ReplaceMacros(lib, target);
                    lib = UnixFilename(lib);
                    time_t timeExtDep;
                    depsTimeStamp(lib.mb_str(), &timeExtDep);
                    if (timeExtDep > timeOutput)
                    {
                        // force re-link
                        Manager::Get()->GetLogManager()->DebugLog(F(_T("Forcing re-link of '%s/%s' because '%s' is newer"),
                                                                        target->GetParentProject()->GetTitle().wx_str(),
                                                                        target->GetTitle().wx_str(),
                                                                        lib.wx_str()));
                        return true;
                    }
                    continue;
                }

                if (!lib.StartsWith(compiler->GetSwitches().libPrefix))
                    lib = compiler->GetSwitches().libPrefix + lib;
                if (!lib.EndsWith(_T(".") + compiler->GetSwitches().libExtension))
                    lib += _T(".") + compiler->GetSwitches().libExtension;

                for (size_t l = 0; l < libDirs.GetCount(); ++l)
                {
                    wxString dir = libDirs[l] + wxFILE_SEP_PATH + lib;
                    Manager::Get()->GetMacrosManager()->ReplaceMacros(dir, target);
                    dir = UnixFilename(dir);
                    time_t timeExtDep;
                    depsTimeStamp(dir.mb_str(), &timeExtDep);
                    if (timeExtDep > timeOutput)
                    {
                        // force re-link
                        Manager::Get()->GetLogManager()->DebugLog(F(_T("Forcing re-link of '%s/%s' because '%s' is newer"),
                                                                        target->GetParentProject()->GetTitle().wx_str(),
                                                                        target->GetTitle().wx_str(),
                                                                        dir.wx_str()));
                        return true;
                    }
                }
            }
        }
    }

    // array is separated by ;
    wxArrayString extDeps  = GetArrayFromString(target->GetExternalDeps(), _T(";"));
    wxArrayString addFiles = GetArrayFromString(target->GetAdditionalOutputFiles(), _T(";"));
    for (size_t i = 0; i < extDeps.GetCount(); ++i)
    {
        if (extDeps[i].IsEmpty())
            continue;

        Manager::Get()->GetMacrosManager()->ReplaceMacros(extDeps[i]);
        time_t timeExtDep;
        depsTimeStamp(extDeps[i].mb_str(), &timeExtDep);
        // if external dep doesn't exist, no need to relink
        // but we have to check other dependencies
        if (!timeExtDep)
        {
            if (filesMissing) filesMissing->Add(extDeps[i]);
            continue;
        }

        // let's check the additional output files
        for (size_t j = 0; j < addFiles.GetCount(); ++j)
        {
            if (addFiles[j].IsEmpty())
                continue;

            Manager::Get()->GetMacrosManager()->ReplaceMacros(addFiles[j]);
            time_t timeAddFile;
            depsTimeStamp(addFiles[j].mb_str(), &timeAddFile);
            // if additional file doesn't exist, we can skip it
            if (!timeAddFile)
            {
                if (filesMissing) filesMissing->Add(addFiles[j]);
                continue;
            }

            // if external dep is newer than additional file, relink
            if (timeExtDep > timeAddFile)
                return true;
        }

        // if no output, probably a commands-only target; nothing to relink
        // but we have to check other dependencies
        if (buildOutput.IsEmpty())
            continue;

        // now check the target's output
        // this is moved last because, for "commands only" targets,
        // it would return before we had a chance to check the
        // additional output files (above)

        // if build output doesn't exist, relink
        if (!timeOutput)
            return true;

        // if external dep is newer than build output, relink
        if (timeExtDep > timeOutput)
            return true;
    }
    return false; // no force relink
}
bool MSVC7WorkspaceLoader::Open(const wxString& filename, wxString& Title)
{
    bool askForCompiler = false;
    bool askForTargets = false;
    switch (cbMessageBox(_("Do you want the imported projects to use the default compiler?\n"
                           "(If you answer No, you will be asked for each and every project"
                           " which compiler to use...)"), _("Question"), wxICON_QUESTION | wxYES_NO | wxCANCEL))
    {
        case wxID_YES:
            askForCompiler = false; break;
        case wxID_NO:
            askForCompiler = true; break;
        case wxID_CANCEL:
            return false;
    }
    switch (cbMessageBox(_("Do you want to import all configurations (e.g. Debug/Release) from the "
                           "imported projects?\n"
                           "(If you answer No, you will be asked for each and every project"
                           " which configurations to import...)"), _("Question"), wxICON_QUESTION | wxYES_NO | wxCANCEL))
    {
        case wxID_YES:
            askForTargets = false;
            break;
        case wxID_NO:
            askForTargets = true;
            break;
        case wxID_CANCEL:
            return false;
    }

    wxFileInputStream file(filename);
    if (!file.Ok())
        return false; // error opening file???

    wxArrayString comps;
    wxTextInputStream input(file);

    // read "header"
    if (!file.Eof())
    {
        // skip unicode BOM, if present
        EncodingDetector detector(filename);
        if (detector.IsOK() && detector.UsesBOM())
        {
            int skipBytes = detector.GetBOMSizeInBytes();
            for (int i = 0; i < skipBytes; ++i)
            {
                char c;
                file.Read(&c, 1);
            }
        }

        wxString line = input.ReadLine();
        // skip initial empty lines (if any)
        while (line.IsEmpty() && !file.Eof())
        {
            line = input.ReadLine();
        }
        comps = GetArrayFromString(line, _T(","));
        line = comps[0];
        line.Trim(true);
        line.Trim(false);
        if (line != _T("Microsoft Visual Studio Solution File"))
        {
            Manager::Get()->GetLogManager()->DebugLog(_T("Unsupported format."));
            return false;
        }
        line = comps.GetCount() > 1 ? comps[1] : wxString(wxEmptyString);
        line.Trim(true);
        line.Trim(false);
        wxString _version = line.AfterLast(' '); // want the version number
        if ((_version != _T("7.00")) && (_version != _T("8.00")))
            Manager::Get()->GetLogManager()->DebugLog(_T("Version not recognized. Will try to parse though..."));
    }

    ImportersGlobals::UseDefaultCompiler = !askForCompiler;
    ImportersGlobals::ImportAllTargets = !askForTargets;

    wxProgressDialog progress(_("Importing MSVC 7 solution"),
                              _("Please wait while importing MSVC 7 solution..."),
                              100, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);

    int count = 0;
    wxArrayString keyvalue;
    cbProject* project = 0;
    cbProject* firstproject = 0;
    wxString uuid;
    bool depSection = false;  // ProjectDependencies section?
    bool slnConfSection = false; // SolutionConfiguration section?
    bool projConfSection = false; // ProjectConfiguration section?
    bool global = false;  // global section or project section?
    wxFileName wfname = filename;
    wfname.Normalize();
    Manager::Get()->GetLogManager()->DebugLog(_T("Workspace dir: ") + wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
    while (!file.Eof())
    {
        wxString line = input.ReadLine();
        line.Trim(true);
        line.Trim(false);

        if (line.StartsWith(_T("Project(")))
        {
            // example wanted line:
            //Project("{UUID of the solution}") = "project name to display", "project filename", "project UUID".
            // UUID type 4 for projects (i.e. random based), UUID type 1 for solutions (i.e. time+host based)
            keyvalue = GetArrayFromString(line, _T("="));
            if (keyvalue.GetCount() != 2) continue;
            // ignore keyvalue[0], i.e. solution UUID/GUID

            // the second part contains the project title and filename
            comps = GetArrayFromString(keyvalue[1], _T(","));
            if (comps.GetCount() < 3) continue;

            // read project title and trim quotes
            wxString prjTitle = comps[0];
            prjTitle.Trim(true);
            prjTitle.Trim(false);
            if (prjTitle.IsEmpty()) continue;
            if (prjTitle.GetChar(0) == _T('\"'))
            {
                prjTitle.Truncate(prjTitle.Length() - 1);
                prjTitle.Remove(0, 1);
            }

            // read project filename and trim quotes
            wxString prjFile = comps[1];
            prjFile.Trim(true);
            prjFile.Trim(false);
            if (prjFile.IsEmpty()) continue;
            if (prjFile.GetChar(0) == _T('\"'))
            {
                prjFile.Truncate(prjFile.Length() - 1);
                prjFile.Remove(0, 1);
            }

            // read project UUID, i.e. "{35AFBABB-DF05-43DE-91A7-BB828A874015}"
            uuid = comps[2];
            uuid.Replace(_T("\""), _T("")); // remove quotes

            ++count;
            wxFileName fname(UnixFilename(prjFile));
            fname.Normalize(wxPATH_NORM_ALL, wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), wxPATH_NATIVE);
            #if wxCHECK_VERSION(2, 9, 0)
            Manager::Get()->GetLogManager()->DebugLog(F(_T("Found project '%s' in '%s'"), prjTitle.wx_str(), fname.GetFullPath().wx_str()));
            #else
            Manager::Get()->GetLogManager()->DebugLog(F(_T("Found project '%s' in '%s'"), prjTitle.c_str(), fname.GetFullPath().c_str()));
            #endif

            int percentage = ((int)file.TellI())*100 / (int)(file.GetLength());
            if (!progress.Update(percentage, _("Importing project: ") + prjTitle))
                break;

            project = Manager::Get()->GetProjectManager()->LoadProject(fname.GetFullPath(), false);
            if (!firstproject) firstproject = project;
            if (project) registerProject(uuid, project);
        }
        else if (line.StartsWith(_T("GlobalSection(ProjectDependencies)")))
        {
            depSection = true;
            global = true;
        }
        else if (line.StartsWith(_T("ProjectSection(ProjectDependencies)")))
        {
            depSection = true;
            global = false;
        }
        else if (line.StartsWith(_T("GlobalSection(ProjectConfiguration)")))
        {
            projConfSection = true;
        }
        else if (line.StartsWith(_T("GlobalSection(SolutionConfiguration)")))
        {
            slnConfSection = true;
        }
        else if (line.StartsWith(_T("EndGlobalSection")) || line.StartsWith(_T("EndProjectSection")))
        {
            depSection = false;
            projConfSection = false;
            slnConfSection = false;
        }
        else if (depSection)
        {
            // start reading a dependency
            keyvalue = GetArrayFromString(line, _T("="));
            if (keyvalue.GetCount() != 2) continue;
            if (global) {
                // {31635C8-67BF-4808-A918-0FBF822771BD}.0 = {658BFA12-8417-49E5-872A-33F0973544DC}
                // i.e. project on the left of '=' depend on the project on the right
                keyvalue[0]= keyvalue[0].BeforeFirst(_T('.'));
                addDependency(keyvalue[0], keyvalue[1]);
            }
            else
            {
                // {F87429BF-4583-4A67-BD6F-6CA8AA27702A} = {F87429BF-4583-4A67-BD6F-6CA8AA27702A}
                // i.e. both uuid are the dependency
                addDependency(uuid, keyvalue[1]);
            }
        }
        else if (slnConfSection)
        {
            // either "Debug = Debug" in V8 or "ConfigName.0 = Debug" in V7
            // ignore every on the left of equal sign
            line = line.AfterLast('=');
            line.Trim(true);
            line.Trim(false);
            addWorkspaceConfiguration(line);
        }
        else if (projConfSection && line.StartsWith(_T("{")))
        {
            // {X}.Debug TA.ActiveCfg = Debug TA|Win32     ---> match solution configuration to project configuration or just say what is the active config?
            // {X}.Debug TA.Build.0 = Debug TA|Win32       ---> we have to build (others are not build)
            keyvalue = GetArrayFromString(line, _T("="));
            wxArrayString key = GetArrayFromString(keyvalue[0], _T("."));
            wxArrayString value = GetArrayFromString(keyvalue[1], _T("|"));
            if (key[2] == _T("Build")) addConfigurationMatching(key[0], key[1], value[0]);
        }
    }

    Manager::Get()->GetProjectManager()->SetProject(firstproject);
    updateProjects();
    ImportersGlobals::ResetDefaults();

    Title = wxFileName(filename).GetName() + _(" workspace");
    return count != 0;
}
Пример #20
0
bool cbMGMakefile::reLoadDependecies(const wxString &p_DepsFileName,ProjectBuildTarget *p_pTarget,Compiler* p_pCompiler)
{
    m_Deps.Clear();
    if ( !wxFileExists( p_DepsFileName ) ) return false;

    wxString l_Buf;
    wxString l_VarName;
    wxTextFile l_DepFile;
    bool IsSkipThisFile = true;
    if (l_DepFile.Open( p_DepsFileName, wxConvFile ))
    {
        for ( unsigned long i = 0; i < l_DepFile.GetLineCount(); i++ )
        {
            l_Buf = l_DepFile[i];
            l_Buf.Trim(true);
            // Wrong! Don't uncomment it! Being deleted '\t' symbol! l_Buf.Trim(false);
            if ( l_Buf.IsEmpty() )
            {
                l_VarName.Clear();
                IsSkipThisFile = true;
                continue;
            }
            if ( _T('#') == l_Buf[0] ) continue;
            if ( _T('\t') == l_Buf[0] )
            {
                if ( !IsSkipThisFile )
                {
                    if ( _T('"') == l_Buf[1] )
                    {
                        wxString l_TmpName = l_Buf.AfterFirst( _T('\t') );
                        if (!l_TmpName.IsEmpty() && l_TmpName.GetChar(0) == _T('"') && l_TmpName.Last() == _T('"'))
                            l_TmpName = l_TmpName.Mid(1, l_TmpName.Length() - 2);
                        QuoteStringIfNeeded( l_TmpName );
                        m_Deps.AppendValue( l_VarName, l_TmpName );
                    }
                }
            }
            else
            {
                l_VarName = l_Buf.AfterFirst(_T(' '));
                bool IsSource = l_VarName.Matches( _T("source:*") );
                if ( IsSource )
                {
                    l_VarName = l_VarName.AfterFirst( _T(':') );
                }
                /*
                 * You would MUST found source file and get his filename from project
                 * !!! .depend file content lowcase filenames
                 */
                wxFileName l_DepFileName = l_VarName;
                ProjectFile *pf = m_pProj->GetFileByFilename( l_DepFileName.GetFullPath(), l_DepFileName.IsRelative(), false );
                if ( pf )
                {
                    const pfDetails& pfd = pf->GetFileDetails( p_pTarget );
                    if ( p_pCompiler->GetSwitches().UseFullSourcePaths )
                    {
                        l_VarName = UnixFilename( pfd.source_file_absolute_native );
                    }
                    else
                    {
                        l_VarName = pfd.source_file;
                    }
                    QuoteStringIfNeeded( l_VarName );
                    IsSkipThisFile = false;
                }
                else
                {
                    IsSkipThisFile = true;
                }
            }
        }
    }
    /* FIXME (kisoftcb#1#): Next code for debug only!
    wxTextFile l_DebFile;
    l_DebFile.Create( _T("D:/DepsFile.log") );
    m_Deps.SaveAllVars( l_DebFile );
    l_DebFile.Write();
    l_DebFile.Close(); */
}
Пример #21
0
bool cbMGMakefile::SaveMakefile()
{
    bool l_Ret = false;
    wxString l_FullFilename = m_Path + m_Filename;

    if ( m_Overwrite && wxFileExists( l_FullFilename ) ) wxRemoveFile( l_FullFilename );

    wxTextFile l_File;
    if ( !l_File.Create( l_FullFilename ) )
    {
        wxString lMsg = _( "File " ) + l_FullFilename + _(" is exists!\nOverwrite?" );
        if (wxID_YES == cbMessageBox(lMsg, _("Warning"), wxICON_EXCLAMATION | wxYES_NO, (wxWindow *)Manager::Get()->GetAppWindow()))
        {
            wxRemoveFile( l_FullFilename );
        }
        else
        {
            return l_Ret;
        }
    }
    // for active target only!
    wxString l_ActiveTargetName = m_pProj->GetActiveBuildTarget();
    ProjectBuildTarget* l_pTarget = m_pProj->GetBuildTarget( l_ActiveTargetName );
    if ( !l_pTarget )
    {
        wxString l_Msg = _( "Can't found an active target!\n"
                            "C::B MakefileGen could not complete the operation." );
        cbMessageBox( l_Msg, _( "Error" ), wxICON_ERROR | wxOK, (wxWindow *)Manager::Get()->GetAppWindow() );
        Manager::Get()->GetMessageManager()->DebugLog( l_Msg );
        return l_Ret;
    }

    const wxString& l_CompilerId = l_pTarget->GetCompilerID();
    Compiler* l_pCompiler = CompilerFactory::GetCompiler( l_CompilerId );

    if ( !getDependencies( l_pTarget, l_pCompiler ) ) return false;

    m_Variables.AddVariable(_T("CPP"),l_pCompiler->GetPrograms().CPP);
    m_Variables.AddVariable(_T("CC"),l_pCompiler->GetPrograms().C);
    m_Variables.AddVariable(_T("LD"),l_pCompiler->GetPrograms().LD);
    m_Variables.AddVariable(_T("LIB"),l_pCompiler->GetPrograms().LIB);
    m_Variables.AddVariable(_T("WINDRES"),l_pCompiler->GetPrograms().WINDRES);

    const wxArrayString& l_CommandsBeforeBuild = l_pTarget->GetCommandsBeforeBuild();
    const wxArrayString& l_CommandsAfterBuild = l_pTarget->GetCommandsAfterBuild();

    wxString l_TargetFileName = l_pTarget->GetOutputFilename();
    Manager::Get()->GetMacrosManager()->ReplaceMacros(l_TargetFileName, l_pTarget);
    wxFileName l_OutFileName = UnixFilename(l_TargetFileName);
    cbMGRule l_Rule;
    if ( 0 == l_ActiveTargetName.CmpNoCase( _T( "default" ) ) )
    {
        l_Rule.SetTarget( _T( "all" ) );
    }
    else
    {
        l_Rule.SetTarget( l_ActiveTargetName );
    }
    wxString l_Pre;
    if ( l_CommandsBeforeBuild.GetCount() > 0 )
    {
        l_Pre = cmdbefore + _T(" ");
    }
    l_Pre += l_OutFileName.GetFullPath();
    if ( l_CommandsAfterBuild.GetCount() > 0 )
    {
        l_Pre += _T(" ") + cmdafter;
    }

    l_Rule.SetPrerequisites( l_Pre );
    m_Rules.Add( l_Rule );

    if ( l_CommandsBeforeBuild.GetCount() > 0 )
    {
        l_Rule.Clear();
        l_Rule.SetTarget( cmdphony );
        l_Rule.SetPrerequisites( cmdbefore );
        m_Rules.Add( l_Rule );
        l_Rule.Clear();
        l_Rule.SetTarget( cmdbefore );
        for ( unsigned long idx = 0; idx < l_CommandsBeforeBuild.GetCount(); idx ++ )
        {
            l_Rule.AddCommand( l_CommandsBeforeBuild[ idx ] );
        }
        m_Rules.Add( l_Rule );
    }
    if ( l_CommandsAfterBuild.GetCount() > 0 )
    {
        l_Rule.Clear();
        l_Rule.SetTarget( cmdphony );
        l_Rule.SetPrerequisites( cmdafter );
        m_Rules.Add( l_Rule );
        l_Rule.Clear();
        l_Rule.SetTarget( cmdafter );
        for ( unsigned long idx = 0; idx < l_CommandsAfterBuild.GetCount(); idx ++ )
        {
            l_Rule.AddCommand( l_CommandsAfterBuild[ idx ] );
        }
        m_Rules.Add( l_Rule );
    }
    l_Rule.Clear();
    l_Rule.SetTarget( l_OutFileName.GetFullPath() );
    l_Rule.SetPrerequisites( objs );

    wxString kind_of_output = _T( "unknown" );
    CommandType ct = ctInvalid; // get rid of compiler warning
    switch ( l_pTarget->GetTargetType() )
    {
    case ttConsoleOnly:
        ct = ctLinkConsoleExeCmd;
        kind_of_output = _T( "console executable" );
        break;

    case ttExecutable:
        ct = ctLinkExeCmd;
        kind_of_output = _T( "executable" );
        break;

    case ttDynamicLib:
        ct = ctLinkDynamicCmd;
        kind_of_output = _T( "dynamic library" );
        break;

    case ttStaticLib:
        ct = ctLinkStaticCmd;
        kind_of_output = _T( "static library" );
        break;

    case ttNative:
        ct = ctLinkNativeCmd;
        kind_of_output = _T( "native" );
        break;
    case ttCommandsOnly:
        ct = ctLinkConsoleExeCmd;
        kind_of_output = _T( "commands only" );
        break;

//      case ttCommandsOnly:
//          // add target post-build commands
//          ret.Clear();
//          AppendArray(GetPostBuildCommands(target), ret);
//          return ret;
//          break;
        break;
    }
    /*if(ttCommandsOnly == lTarget->GetTargetType())
    {
      GetPostBuildCommands(lTarget);
    }
    else*/
    {
        l_Rule.AddCommand( _T( "echo Building " ) + kind_of_output + _T( " " ) + l_OutFileName.GetFullPath() );
        wxString l_LinkerCmd = l_pCompiler->GetCommand( ct );
        l_pCompiler->GenerateCommandLine( l_LinkerCmd,
                                          l_pTarget,
                                          NULL,
                                          l_OutFileName.GetFullPath(),
                                          oobjs,
                                          wxEmptyString,
                                          wxEmptyString );
        l_Rule.AddCommand( l_LinkerCmd );
    }
    m_Rules.Add( l_Rule );

    // Form rules
    wxString l_Tmp;

    unsigned long ii;

    wxString macro;
    wxString file;
    wxString object;
    wxString FlatObject;
    wxString deps;

    cbMGSortFilesArray files = GetProjectFilesSortedByWeight(l_pTarget,true,false);
    unsigned long lnb_files = files.GetCount();
    for ( ii = 0; ii < lnb_files; ii++ )
    {
        l_Rule.Clear();
        ProjectFile* pf = files[ ii ];
        const pfDetails& pfd = pf->GetFileDetails( l_pTarget );
        wxString l_Object = ( l_pCompiler->GetSwitches().UseFlatObjects )?pfd.object_file_flat:pfd.object_file;
        wxString l_CompilerCmd;
        // lookup file's type
        FileType ft = FileTypeOf( pf->relativeFilename );
        bool isResource = ft == ftResource;
        bool isHeader = ft == ftHeader;
        if ( !isHeader || l_pCompiler->GetSwitches().supportsPCH )
        {
            pfCustomBuild& pcfb = pf->customBuild[l_pCompiler->GetID()];
            l_CompilerCmd = pcfb.useCustomBuildCommand
                            ? pcfb.buildCommand
                            : l_pCompiler->GetCommand( isResource ? ctCompileResourceCmd : ctCompileObjectCmd );
            wxString l_SourceFile;
            if ( l_pCompiler->GetSwitches().UseFullSourcePaths )
            {
                l_SourceFile = UnixFilename( pfd.source_file_absolute_native );
                // for resource files, use short from if path because if windres bug with spaces-in-paths
                if ( isResource )
                {
                    l_SourceFile = pf->file.GetShortPath();
                }
            }
            else
            {
                l_SourceFile = pfd.source_file;
            }
            QuoteStringIfNeeded( l_SourceFile );
            l_pCompiler->GenerateCommandLine( l_CompilerCmd,
                                              l_pTarget,
                                              pf,
                                              l_SourceFile,
                                              l_Object,
                                              pfd.object_file_flat,
                                              pfd.dep_file );
            m_Variables.AppendValue( _T( "OBJS" ), l_Object );
            l_Rule.SetTarget( l_Object );
            l_Rule.SetPrerequisites( l_SourceFile );
            l_Rule.AddCommand( _T( "echo Compiling: " ) + l_SourceFile );
            l_Rule.AddCommand( l_CompilerCmd );
            m_Rules.Add( l_Rule );
        }
    }
    for ( unsigned long i=0; i < m_Deps.Count(); i++ )
    {
        l_Rule.Clear();
        l_Rule.SetTarget( m_Deps.GetVarName( i ) );
        l_Rule.SetPrerequisites( m_Deps.GetVariable( i ) );
        m_Rules.Add( l_Rule );
    }

    l_Rule.Clear();
    l_Rule.SetTarget( cmdphony );
    l_Rule.SetPrerequisites( cmdclean );
    m_Rules.Add( l_Rule );
    l_Rule.Clear();
    l_Rule.SetTarget( cmdclean );
    l_Rule.AddCommand( _T( "echo Delete $(OBJS) " ) + l_OutFileName.GetFullPath() );
#ifdef __WXMSW__
    l_Rule.AddCommand( _T( "del /f $(OBJS) " ) + l_OutFileName.GetFullPath() );
#else
    l_Rule.AddCommand( _T( "rm -f $(OBJS) " ) + l_OutFileName.GetFullPath() );
#endif
    m_Rules.Add( l_Rule );

    // save header
    l_File.AddLine( sHeader );
    l_File.AddLine( wxEmptyString );
    m_Variables.SaveAllVars( l_File );
    SaveAllRules( l_File );

    l_File.Write();
    l_File.Close();
    l_Ret = true;
    return l_Ret;
}
Пример #22
0
bool WorkspaceLoader::Open(const wxString& filename, wxString& Title)
{
    TiXmlDocument doc;
    if (!TinyXML::LoadDocument(filename, &doc))
        return false;

//    ProjectManager* pMan = Manager::Get()->GetProjectManager();
//    LogManager* pMsg = Manager::Get()->GetLogManager();

    if (!GetpMan() || !GetpMsg())
        return false;

    // BUG: Race condition. to be fixed by Rick.
    // If I click close AFTER pMan and pMsg are calculated,
    // I get a segfault.
    // I modified classes projectmanager and logmanager,
    // so that when self==NULL, they do nothing
    // (constructors, destructors and static functions excempted from this)
    // This way, we'll use the *manager::Get() functions to check for nulls.

    TiXmlElement* root = doc.FirstChildElement("CodeBlocks_workspace_file");
    if (!root)
    {
        // old tag
        root = doc.FirstChildElement("Code::Blocks_workspace_file");
        if (!root)
        {
            GetpMsg()->DebugLog(_T("Not a valid Code::Blocks workspace file..."));
            return false;
        }
    }
    TiXmlElement* wksp = root->FirstChildElement("Workspace");
    if (!wksp)
    {
        GetpMsg()->DebugLog(_T("No 'Workspace' element in file..."));
        return false;
    }

    Title = cbC2U(wksp->Attribute("title")); // Conversion to unicode is automatic (see wxString::operator= )

    TiXmlElement* proj = wksp->FirstChildElement("Project");
    if (!proj)
    {
        GetpMsg()->DebugLog(_T("Workspace file contains no projects..."));
        return false;
    }

    // first loop to load projects
    while (proj)
    {
        if(Manager::isappShuttingDown() || !GetpMan() || !GetpMsg())
            return false;
        wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename")));
        if (projectFilename.IsEmpty())
        {
            GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?"));
        }
        else
        {
            wxFileName fname(projectFilename);
            wxFileName wfname(filename);
            fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
            int active = 0;
            int ret = proj->QueryIntAttribute("active", &active);
            switch (ret)
            {
                case TIXML_SUCCESS:
                    if (active == 1)
					{
						cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), true); // activate it
						if(!pProject)
						{
							cbMessageBox(_("Unable to open ") + projectFilename,
							 _("Opening WorkSpace") + filename, wxICON_WARNING);
						}
					}
                    break;
                case TIXML_WRONG_TYPE:
                    GetpMsg()->DebugLog(F(_T("Error %s: %s"), doc.Value(), doc.ErrorDesc()));
                    GetpMsg()->DebugLog(_T("Wrong attribute type (expected 'int')"));
                    break;
                default:
					cbProject* pProject = GetpMan()->LoadProject(fname.GetFullPath(), false); // don't activate it
					if(!pProject)
					{
						cbMessageBox(_("Unable to open ") + projectFilename,
						 _("Opening WorkSpace") + filename, wxICON_WARNING);
					}
                    break;
            }
        }
        proj = proj->NextSiblingElement("Project");
    }

    // second loop to setup dependencies
    proj = wksp->FirstChildElement("Project");
    while (proj)
    {
        cbProject* thisprj = 0;
        wxString projectFilename = UnixFilename(cbC2U(proj->Attribute("filename")));
        if (projectFilename.IsEmpty())
        {
            GetpMsg()->DebugLog(_T("'Project' node exists, but no filename?!?"));
            thisprj = 0;
        }
        else
        {
            wxFileName fname(projectFilename);
            wxFileName wfname(filename);
            fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
            thisprj = Manager::Get()->GetProjectManager()->IsOpen(fname.GetFullPath());
        }

        if (thisprj)
        {
            TiXmlElement* dep = proj->FirstChildElement("Depends");
            while (dep)
            {
                wxFileName fname(UnixFilename(cbC2U(dep->Attribute("filename"))));
                wxFileName wfname(filename);
                fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
                cbProject* depprj = Manager::Get()->GetProjectManager()->IsOpen(fname.GetFullPath());
                if (depprj)
                    Manager::Get()->GetProjectManager()->AddProjectDependency(thisprj, depprj);
                dep = dep->NextSiblingElement("Depends");
            }
        }
        proj = proj->NextSiblingElement("Project");
    }

    return true;
}
Пример #23
0
bool MSVC7Loader::DoImport(TiXmlElement* conf)
{
    ProjectBuildTarget* bt = m_pProject->GetBuildTarget(m_ConfigurationName);
    if (!bt)
        bt = m_pProject->AddBuildTarget(m_ConfigurationName);
    bt->SetCompilerID(m_pProject->GetCompilerID());

    // See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcext/html/vxlrfvcprojectenginelibraryruntimelibraryoption.asp


    m_OutDir = ReplaceMSVCMacros(cbC2U(conf->Attribute("OutputDirectory")));
    m_IntDir = ReplaceMSVCMacros(cbC2U(conf->Attribute("IntermediateDirectory")));
    if (m_IntDir.StartsWith(_T(".\\"))) m_IntDir.Remove(0,2);
    bt->SetObjectOutput(m_IntDir);

    // see MSDN: ConfigurationTypes Enumeration
    wxString conftype = cbC2U(conf->Attribute("ConfigurationType"));
    if (conftype.IsSameAs(_T("1"))) // typeApplication 1, no difference between console or gui here, we must check the subsystem property of the linker
        bt->SetTargetType(ttExecutable);
    else if (conftype.IsSameAs(_T("2"))) // typeDynamicLibrary 2
        bt->SetTargetType(ttDynamicLib);
    else if (conftype.IsSameAs(_T("4"))) // typeStaticLibrary 4
        bt->SetTargetType(ttStaticLib);
    else if (conftype.IsSameAs(_T("-1"))) // typeNative -1, check subsystem property of the linker to make sure
        bt->SetTargetType(ttNative);
    else if (conftype.IsSameAs(_T("10"))) // typeGeneric 10
        bt->SetTargetType(ttCommandsOnly);
    else // typeUnknown 0
    {
        bt->SetTargetType(ttCommandsOnly);
        Manager::Get()->GetLogManager()->DebugLog(_T("unrecognized project type"));
    }

    TiXmlElement* tool = conf->FirstChildElement("Tool");
    if (!tool)
    {
        Manager::Get()->GetLogManager()->DebugLog(_T("No 'Tool' node..."));
        return false;
    }

    for (; tool; tool=tool->NextSiblingElement("Tool"))
    {
        if (strcmp(tool->Attribute("Name"), "VCLinkerTool") == 0 ||
            strcmp(tool->Attribute("Name"), "VCLibrarianTool") == 0)
        {
            // linker
            wxString tmp;

            if ((bt->GetTargetType()==ttExecutable) || (bt->GetTargetType()==ttNative))
            {
                tmp = cbC2U(tool->Attribute("SubSystem"));
                //subSystemNotSet 0
                //subSystemConsole 1
                //subSystemWindows 2
                if (tmp.IsSameAs(_T("1")))
                {
                    bt->SetTargetType(ttConsoleOnly);
                    //bt->AddLinkerOption("/SUBSYSTEM:CONSOLE"); // don't know if it is necessary
                }
                else if (tmp.IsSameAs(_T("3")))
                    bt->SetTargetType(ttNative);
            } // else we keep executable

            tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("OutputFile")));
            tmp = UnixFilename(tmp);
            if (tmp.Last() == _T('.')) tmp.RemoveLast();
            if (bt->GetTargetType() == ttStaticLib)
            {
                // convert the lib name
                Compiler* compiler = CompilerFactory::GetCompiler(m_pProject->GetCompilerID());
                if (compiler)
                {
                    wxString prefix = compiler->GetSwitches().libPrefix;
                    wxString suffix = compiler->GetSwitches().libExtension;
                    wxFileName fname = tmp;
                    if (!fname.GetName().StartsWith(prefix))
                        fname.SetName(prefix + fname.GetName());
                    fname.SetExt(suffix);
                    tmp = fname.GetFullPath();
                }
            }
            bt->SetOutputFilename(tmp);
            m_TargetPath = wxFileName(tmp).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
            m_TargetFilename = wxFileName(tmp).GetFullName();

            tmp = cbC2U(tool->Attribute("AdditionalLibraryDirectories"));
            wxArrayString arr;
            ParseInputString(tmp, arr);
            for (unsigned int i = 0; i < arr.GetCount(); ++i)
            {
                bt->AddLibDir(ReplaceMSVCMacros(arr[i]));
            }

            if (!m_ConvertSwitches) // no point importing this option, if converting to GCC
            {
                tmp = cbC2U(tool->Attribute("IgnoreDefaultLibraryNames"));
                arr = GetArrayFromString(tmp, _T(";"));
                if (arr.GetCount()==1) arr = GetArrayFromString(tmp, _T(","));
                for (unsigned int i = 0; i < arr.GetCount(); ++i)
                {
                    bt->AddLinkerOption(wxString(_T("/NODEFAULTLIB:")) + arr[i]);
                }
            }

#if 0
            // no need since "/nologo" appear on the invocation commands of compilers/linkers
            if (!m_ConvertSwitches)
            {
                tmp = tool->Attribute("SuppressStartupBanner");
                if (tmp.IsSameAs("TRUE"))
                    bt->AddLinkerOption("/nologo");
            }
#endif

            tmp = cbC2U(tool->Attribute("GenerateDebugInformation"));
            if (tmp.IsSameAs(_T("TRUE")))
            {
                //bt->AddCompilerOption(m_ConvertSwitches ? "-g" : "/Zi"); // no !
                if (!m_ConvertSwitches)
                    bt->AddLinkerOption(_T("/debug"));
            }

            // other options: /MACHINE:I386, /INCREMENTAL:YES, /STACK:10000000
            if (!m_ConvertSwitches)
            {
                arr = GetArrayFromString(ReplaceMSVCMacros(cbC2U(tool->Attribute("AdditionalOptions"))), _T(" "));
                for (unsigned int i = 0; i < arr.GetCount(); ++i) bt->AddLinkerOption(arr[i]);
            }
            // else ignore all options

            tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("AdditionalDependencies")));
            arr = GetArrayFromString(tmp, _T(" "));
            for (unsigned int i = 0; i < arr.GetCount(); ++i)
            {
                tmp = arr[i];
                if (tmp.Right(4).CmpNoCase(_T(".lib")) == 0)
                    tmp.Remove(tmp.Length() - 4);
                if ((tmp == _T("/dll")) || (tmp == _T("/DLL")))
                    bt->AddLinkerOption(_T("--dll"));
                else
                    bt->AddLinkLib(tmp);
            }

            if (!m_ConvertSwitches)
            {
                tmp = cbC2U(tool->Attribute("LinkIncremental"));
                if (tmp.IsSameAs(_T("1"))) // 1 -> no, default is yes
                    bt->AddLinkerOption(_T("/INCREMENTAL:NO"));
            }

            if (!m_ConvertSwitches)
            {
                tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("ProgramDatabaseFile")));
                if (!tmp.IsEmpty())
                    bt->AddLinkerOption(wxString(_T("/pdb:")) + UnixFilename(tmp));
            }

            if (!m_ConvertSwitches)
            {
                tmp = ReplaceMSVCMacros(cbC2U(tool->Attribute("ModuleDefinitionFile")));
                if (!tmp.IsEmpty())
                    bt->AddLinkerOption(_T("/DEF:\"") + tmp + _T("\""));
            }
        }
        else if (strcmp(tool->Attribute("Name"), "VCCLCompilerTool") == 0)
        {
            unsigned int i;
            wxString tmp;
            wxArrayString arr;

            // compiler
            tmp = cbC2U(tool->Attribute("AdditionalIncludeDirectories"));
            // vc70 uses ";" while vc71 uses "," separators
            // NOTE (mandrav#1#): No, that is *not* the case (what were they thinking at MS?)
            // try with comma (,) which is the newest I believe
            ParseInputString(tmp, arr); // This will parse recursively
            for (i = 0; i < arr.GetCount(); ++i)
            {
                bt->AddIncludeDir(ReplaceMSVCMacros(arr[i]));
                bt->AddResourceIncludeDir(ReplaceMSVCMacros(arr[i]));
            }

            tmp = cbC2U(tool->Attribute("PreprocessorDefinitions"));
            arr = GetArrayFromString(tmp, _T(","));
            if (arr.GetCount() == 1) // if it fails, try with semicolon
                arr = GetArrayFromString(tmp, _T(";"));
            for (unsigned int j = 0; j < arr.GetCount(); ++j)
            {
                if (m_ConvertSwitches)
                    bt->AddCompilerOption(wxString(_T("-D")) + arr[j]);
                else
                    bt->AddCompilerOption(wxString(_T("/D")) + arr[j]);
            }

            tmp = cbC2U(tool->Attribute("WarningLevel"));
            if (m_ConvertSwitches)
            {
                if (tmp.IsSameAs(_T("0")))
                    bt->AddCompilerOption(_T("-w"));
                else if (tmp.IsSameAs(_T("1")) || tmp.IsSameAs(_T("2")) || tmp.IsSameAs(_T("3")))
                    bt->AddCompilerOption(_T("-W"));
                else if (tmp.IsSameAs(_T("4")))
                    bt->AddCompilerOption(_T("-Wall"));
            }
            else
            {
                bt->AddCompilerOption(wxString(_T("/W")) + tmp);
            }

/* For more details on "DebugInformationFormat", please visit
   http://msdn2.microsoft.com/en-us/library/aa652260(VS.71).aspx
   http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.debugoption(VS.80).aspx */
            tmp = cbC2U(tool->Attribute("DebugInformationFormat"));
            if (tmp.IsSameAs(_T("3")))
                bt->AddCompilerOption(m_ConvertSwitches ? _T("") : _T("/Zi"));
            else if (tmp.IsSameAs(_T("4")))
                bt->AddCompilerOption(m_ConvertSwitches ? _T("-g") : _T("/ZI"));


            tmp = cbC2U(tool->Attribute("InlineFunctionExpansion"));
            if (!m_ConvertSwitches && tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("/Ob1"));

            /* Optimization :
            optimizeDisabled 0
            optimizeMinSpace 1
            optimizeMaxSpeed 2
            optimizeFull 3
            optimizeCustom 4
            */
            tmp = cbC2U(tool->Attribute("Optimization"));
            if (m_ConvertSwitches)
            {
                if      (tmp.IsSameAs(_T("0"))) bt->AddCompilerOption(_T("-O0"));
                else if (tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("-O1"));
                else if (tmp.IsSameAs(_T("2"))) bt->AddCompilerOption(_T("-O2"));
                else if (tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(_T("-O3"));
                //else if (tmp.IsSameAs("4")) bt->AddCompilerOption("-O1"); // nothing to do ?
            }
            else
            {
                if      (tmp.IsSameAs(_T("0"))) bt->AddCompilerOption(_T("/Od"));
                else if (tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("/O1"));
                else if (tmp.IsSameAs(_T("2"))) bt->AddCompilerOption(_T("/O2"));
                else if (tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(_T("/Ox"));
                //else if (tmp.IsSameAs("4")) bt->AddCompilerOption("/O1"); // nothing to do ?
            }

            if (!m_ConvertSwitches)
            {
                tmp = cbC2U(tool->Attribute("Detect64BitPortabilityProblems"));
                if (tmp.IsSameAs(_T("TRUE")))
                    bt->AddCompilerOption(_T("/Wp64"));

                tmp = cbC2U(tool->Attribute("MinimalRebuild"));
                if (tmp.IsSameAs(_T("TRUE")))
                    bt->AddCompilerOption(_T("/Gm"));
/*
                RuntimeLibrary :
                rtMultiThreaded          0 --> /MT
                rtMultiThreadedDebug     1 --> /MTd
                rtMultiThreadedDLL       2 --> /MD
                rtMultiThreadedDebugDLL  3 --> /MDd
                rtSingleThreaded         4 --> /ML
                rtSingleThreadedDebug    5 --> /MLd
*/
                tmp = cbC2U(tool->Attribute("RuntimeLibrary"));
                if      (tmp.IsSameAs(_T("0"))) bt->AddCompilerOption(_T("/MT"));
                else if (tmp.IsSameAs(_T("1"))) bt->AddCompilerOption(_T("/MTd"));
                else if (tmp.IsSameAs(_T("2"))) bt->AddCompilerOption(_T("/MD"));
                else if (tmp.IsSameAs(_T("3"))) bt->AddCompilerOption(_T("/MDd"));
                else if (tmp.IsSameAs(_T("4"))) bt->AddCompilerOption(_T("/ML"));
                else if (tmp.IsSameAs(_T("5"))) bt->AddCompilerOption(_T("/MLd"));

#if 0
                tmp = cbC2U(tool->Attribute("SuppressStartupBanner"));
                if (tmp.IsSameAs(_T("TRUE"))) bt->AddCompilerOption("/nologo");
#endif
/*
                runtimeBasicCheckNone 0
                runtimeCheckStackFrame 1  --> /RTCs or /GZ
                runtimeCheckUninitVariables 2
                runtimeBasicCheckAll 3
*/
                tmp = cbC2U(tool->Attribute("BasicRuntimeChecks"));
                if (tmp.IsSameAs(_T("1")))
                    bt->AddCompilerOption(_T("/GZ"));

                tmp = cbC2U(tool->Attribute("ExceptionHandling"));
                if (tmp.IsSameAs(_T("TRUE"))) bt->AddCompilerOption(_T("EHsc")); // add C++ exception handling

            }

            tmp = cbC2U(tool->Attribute("RuntimeTypeInfo"));
            if (tmp.IsSameAs(_T("TRUE")))
                bt->AddCompilerOption(m_ConvertSwitches ? _T("-frtti") : _T("/GR"));

/*
            AdditionalOptions=" /Zm1000 /GR  -DCMAKE_INTDIR=\&quot;Debug\&quot;"
            ObjectFile="Debug\"
            /Zm<n> max memory alloc (% of default)
*/
            tmp = cbC2U(tool->Attribute("AdditionalOptions"));
            //tmp = ReplaceMSVCMacros(tmp);
            arr = GetArrayFromString(tmp, _T(" "));
            for (i=0; i<arr.GetCount(); ++i)
            {
                if (arr[i].IsSameAs(_T("/D")) || arr[i].IsSameAs(_T("-D")))
                {
                    bt->AddCompilerOption((m_ConvertSwitches? _T("-D"):_T("/D")) + arr[i+1]);
                    ++i;
                }
                else if (arr[i].StartsWith(_T("/D")) || arr[i].StartsWith(_T("-D")))
                    bt->AddCompilerOption((m_ConvertSwitches? _T("-D"):_T("/D")) + arr[i].Mid(2));
                else if (arr[i].IsSameAs(_T("/Zi")))
                    bt->AddCompilerOption(m_ConvertSwitches? _T("-g"):_T("/Zi"));
                else if (!m_ConvertSwitches)
                    bt->AddCompilerOption(arr[i]);
            }

            tmp = cbC2U(tool->Attribute("ForcedIncludeFiles"));
            if (!tmp.IsEmpty())
            {
                wxArrayString FIfiles;
                ParseInputString(tmp, FIfiles);
                for (size_t j = 0; j < FIfiles.GetCount(); ++j)
                    bt->AddCompilerOption(m_ConvertSwitches? _T("-include ") + ReplaceMSVCMacros(FIfiles[j])
                                          : _T("/FI ") + ReplaceMSVCMacros(FIfiles[j]));
            }

        }
        else if (strcmp(tool->Attribute("Name"), "VCPreBuildEventTool") == 0)
        {
            // pre-build step
            wxString cmd = ReplaceMSVCMacros(cbC2U(tool->Attribute("CommandLine")));
            if (!cmd.IsEmpty())
                bt->AddCommandsBeforeBuild(cmd);
        }
        else if (strcmp(tool->Attribute("Name"), "VCPostBuildEventTool") == 0)
        {
            // post-build step
            wxString cmd = ReplaceMSVCMacros(cbC2U(tool->Attribute("CommandLine")));
            if (!cmd.IsEmpty())
                bt->AddCommandsAfterBuild(cmd);
        }
    }
    return true;
}
Пример #24
0
wxArrayString DirectCommands::GetTargetLinkCommands(ProjectBuildTarget* target, bool force)
{
    wxArrayString ret;
    wxString output = target->GetOutputFilename();
    Manager::Get()->GetMacrosManager()->ReplaceMacros(output, target);

    wxFileName out = UnixFilename(output);
    wxString linkfiles;
    wxString FlatLinkFiles;
    wxString resfiles;
    bool IsOpenWatcom = target->GetCompilerID().IsSameAs(_T("ow"));

    time_t outputtime;
    depsTimeStamp(output.mb_str(), &outputtime);
    if (!outputtime)
        force = true;
    if (AreExternalDepsOutdated(out.GetFullPath(), target->GetAdditionalOutputFiles(), target->GetExternalDeps()))
        force = true;

    Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;

    wxString prependHack; // part of the following hack
    if (target->GetTargetType() == ttStaticLib)
    {
        // QUICK HACK: some linkers (e.g. bcc, dmc) require a - or + in front of
        // object files for static library. What we 'll do here until we redesign
        // the thing, is to accept this symbol as part of the $link_objects macro
        // like this:
        // $+link_objects
        // $-link_objects
        // $-+link_objects
        // $+-link_objects
        //
        // So, we first scan the command for this special case and, if found,
        // set a flag so that the linkfiles array is filled with the correct options
        wxString compilerCmd = compiler->GetCommand(ctLinkStaticCmd);
        wxRegEx re(_T("\\$([-+]+)link_objects"));
        if (re.Matches(compilerCmd))
            prependHack = re.GetMatch(compilerCmd, 1);
    }

    // get all the linkable objects for the target
    MyFilesArray files = GetProjectFilesSortedByWeight(target, false, true);
    wxString allfile;
    if (files.GetCount() == 0)
    {
        ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking stage skipped (build target has no object files to link)"));
        return ret;
    }
    if (IsOpenWatcom && target->GetTargetType() != ttStaticLib)
        linkfiles << _T("file ");
    for (unsigned int i = 0; i < files.GetCount(); ++i)
    {
        ProjectFile* pf = files[i];

        // we have to test again for each file if it is to be compiled
        // and we can't check the file for existence because we 're still
        // generating the command lines that will create the files...
        wxString macro = _T("$compiler");
        if(m_pCompiler->GetParentID().Matches(_T("lcy")))
        {
            if(pf->file.GetExt().Lower().IsSameAs(FileFilters::LD_EXT))
            continue;
        }

       // allfile = allfile + _T(" ") + pf->GetObjName().BeforeLast(_T('.'))+_T('.')+pf->file.GetExt();

        compiler->GenerateCommandLine(macro, target, pf, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString);
        if (macro.IsEmpty())
            continue;

        const pfDetails& pfd = pf->GetFileDetails(target);
        wxString Object = (target->GetUseFlatObjects())?pfd.object_file_flat:pfd.object_file;

        if (FileTypeOf(pf->relativeFilename) == ftResource)
        {
            // -----------------------------------------
            // Following lines have been modified for OpenWatcom
            if (IsOpenWatcom)
                resfiles << _T("option resource=") << Object << _T(" ");
            else
                resfiles << Object << _T(" ");
            // ------------------------------------------
        }
        else
        {
            // -----------------------------------------
            // Following lines have been modified for OpenWatcom
            if (IsOpenWatcom && target->GetTargetType() != ttStaticLib)
            {
                linkfiles << prependHack << Object << _T(","); // see QUICK HACK above (prependHack)
                FlatLinkFiles << prependHack << pfd.object_file_flat << _T(","); // see QUICK HACK above (prependHack)
            }
            else
            {
                linkfiles << prependHack << Object << _T(" "); // see QUICK HACK above (prependHack)
                FlatLinkFiles << prependHack << pfd.object_file_flat << _T(" "); // see QUICK HACK above (prependHack)
            }
            // -----------------------------------------
        }

        // timestamp check
        if (!force)
        {
            time_t objtime;
            depsTimeStamp(pfd.object_file_native.mb_str(), &objtime);
            if (objtime > outputtime)
                force = true;
        }



        // Why was this here?
//        if(m_doYield)
//            Manager::Yield();
    }
    if (IsOpenWatcom)
    {
        linkfiles.Trim();
        if (linkfiles.Right(1).IsSameAs(_T(",")))
            linkfiles = linkfiles.BeforeLast(_T(','));
    }

    if (!force)
        return ret;


    if(target->GetCompilerID().Lower().Matches(_T("dsp")))  /// 2012-8-29 lcy
        {
//            FlatLinkFiles.Replace(_T(".obj"),_T(".cln"));
            FlatLinkFiles.Replace(_T("\\"),_T(" "));
//            linkfiles.Replace(_T(".obj"),_T(".cln"));
            linkfiles.Replace(_T("\\"),_T(" "));
        }
    // create output dir
    out.MakeAbsolute(m_pProject->GetBasePath());
    wxString dstname = out.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    Manager::Get()->GetMacrosManager()->ReplaceMacros(dstname, target);
    if (!dstname.IsEmpty() && !CreateDirRecursively(dstname, 0755))
    {
            cbMessageBox(_("Can't create output directory ") + dstname);
    }

    // add actual link command
    wxString kind_of_output;
    CommandType ct = ctCount; // get rid of compiler warning
    switch (target->GetTargetType())
    {
        case ttConsoleOnly:
            ct = ctLinkConsoleExeCmd;
            kind_of_output = _("console executable");
            break;

        case ttExecutable:
            ct = ctLinkExeCmd;
            kind_of_output = _("executable");
            break;

        case ttDynamicLib:
            ct = ctLinkDynamicCmd;
            kind_of_output = _("dynamic library");
            break;

        case ttStaticLib:
            ct = ctLinkStaticCmd;
            kind_of_output = _("static library");
            break;

        case ttNative:
            ct = ctLinkNativeCmd;
            kind_of_output = _("native");
            break;


        case ttCommandsOnly:
            // add target post-build commands
            ret.Clear();
            AppendArray(GetPostBuildCommands(target), ret);
            return ret;
            break;
        default:
            wxString ex;
            ex.Printf(_T("Encountered invalid TargetType (value = %d)"), target->GetTargetType());
            cbThrow(ex);
        break;
    }
    wxString compilerCmd = compiler->GetCommand(ct);
    compiler->GenerateCommandLine(compilerCmd,
                                             target,
                                             0,
                                             _T(""),
                                             linkfiles,
                                             FlatLinkFiles,
                                             resfiles);
    if(target->GetCompilerID().Lower().Matches(_T("dsp")))   /// 2012-8-29 lcy
    {
        compilerCmd.Replace(_("#allfile"),allfile);
    }
    if (!compilerCmd.IsEmpty())
    {
        switch (compiler->GetSwitches().logging)
        {
            case clogFull:
                ret.Add(wxString(COMPILER_SIMPLE_LOG) + compilerCmd);
                break;

            default: // linker always simple log (if not full)
                ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking ") + kind_of_output + _T(": ") + output);
                break;
        }

        // for an explanation of the following, see GetTargetCompileCommands()
        if (target && ret.GetCount() != 0)
            ret.Add(wxString(COMPILER_TARGET_CHANGE) + target->GetTitle());

        // the 'true' will make sure all commands will be prepended by
        // COMPILER_WAIT signal
        AddCommandsToArray(compilerCmd, ret, true, true);
    }
    else
        ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping linking (no linker program set): ") + output);
    return ret;
}
Пример #25
0
void pfDetails::Update(ProjectBuildTarget* target, ProjectFile* pf)
{
    wxString sep = wxFILE_SEP_PATH;
    wxFileName tmp;

    wxFileName prjbase(target->GetParentProject()->GetBasePath());

    wxString objOut = target ? target->GetObjectOutput() : _T(".");
    wxString depsOut = target ? target->GetDepsOutput() : _T(".");

    // we must replace any macros here early because if the macros expand
    // to absolute paths (like global vars usually do), we 're gonna create
    // invalid filenames below
    Manager::Get()->GetMacrosManager()->ReplaceMacros(objOut, target);
    Manager::Get()->GetMacrosManager()->ReplaceMacros(depsOut, target);
    source_file_native = pf->relativeFilename;
    source_file_absolute_native = pf->file.GetFullPath();

    tmp = pf->GetObjName();
    FileType ft = FileTypeOf(pf->relativeFilename);

    Compiler* compiler = target
                            ? CompilerFactory::GetCompiler(target->GetCompilerID())
                            : CompilerFactory::GetDefaultCompiler();

    // support for precompiled headers
    if (target && ft == ftHeader && compiler && compiler->GetSwitches().supportsPCH)
    {
        switch (target->GetParentProject()->GetModeForPCH())
        {
            case pchSourceDir:
            {
                // if PCH is for a file called all.h, we create
                // all.h.gch/<target>_all.h.gch
                // (that's right: a directory)
                wxString new_gch = target->GetTitle() + _T('_') + pf->GetObjName();
                // make sure we 're not generating subdirs
                size_t len = new_gch.Length();
                for (size_t i = 0; i < len; ++i)
                {
                    wxChar c = new_gch[i];
                    if (c == _T('/') || c == _T('\\') || c == _T('.'))
                        new_gch[i] = _T('_');
                }

                wxFileName fn(source_file_native);
                object_file_native = fn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) +
                                    fn.GetName() + _T('.') + compiler->GetSwitches().PCHExtension +
                                    wxFILE_SEP_PATH +
                                    new_gch;
                object_file_flat_native = object_file_native;
                break;
            }

            case pchObjectDir:
            {
                object_file_native = objOut + sep + tmp.GetFullPath();
                object_file_flat_native = objOut + sep + tmp.GetFullName();
                break;
            }

            case pchSourceFile:
            {
                object_file_native = pf->GetObjName();
                object_file_flat_native = object_file_native;
                break;
            }
        }
    }
    else
    {
        if (pf->GetParentProject())
        {
            wxFileName fname(pf->relativeToCommonTopLevelPath);
            if (pf->generatedFiles.size())
            {
                // for files generating other files,
                // use the first generated file's "object name"
                fname.Assign(pf->generatedFiles[0]->relativeToCommonTopLevelPath);
            }
            /* NOTE: In case the source file resides in a different volume
            * than the volume where project file is,
            * then the object file will be created as follows.
            *
            * Project object output dir: C:\Foo\obj\Debug
            * Source: D:\Source\foo.cpp
            * Obj file: C:\Foo\obj\Debug\D\Source\foo.o
            */
            wxString fileVol = fname.GetVolume();
            wxString obj_file_full_path = fname.GetFullPath();
            bool diffVolume = false;

            if (platform::windows
                && (!fileVol.IsEmpty() && !fileVol.IsSameAs(prjbase.GetVolume())))
            {
                objOut += fileVol;
                obj_file_full_path = obj_file_full_path.AfterFirst(_T('\\'));
                diffVolume = true;
            }

            if (ft == ftResource || ft == ftResourceBin)
            {
                if (pf->GetParentProject()->GetExtendedObjectNamesGeneration())
                {
                    object_file_native = objOut + sep + obj_file_full_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();

                    object_file_native += FileFilters::RESOURCEBIN_DOT_EXT;
                    object_file_flat_native += FileFilters::RESOURCEBIN_DOT_EXT;
                }
                else
                {
                    fname.SetExt(FileFilters::RESOURCEBIN_EXT);
                    wxString obj_file_path = fname.GetFullPath();
                    if (diffVolume)
                        obj_file_path = obj_file_path.AfterFirst(_T('\\'));
                    object_file_native = objOut + sep + obj_file_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();
                }
            }
            else
            {
                if (pf->GetParentProject()->GetExtendedObjectNamesGeneration())
                {
                    object_file_native = objOut + sep + obj_file_full_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();

                    if (compiler)
                    {
                        object_file_native += _T('.') + compiler->GetSwitches().objectExtension;
                        object_file_flat_native += _T('.') + compiler->GetSwitches().objectExtension;
                    }
                }
                else
                {
                    if (compiler)
                        fname.SetExt(compiler->GetSwitches().objectExtension);
                    wxString obj_file_path = fname.GetFullPath();
                    if (diffVolume)
                        obj_file_path = obj_file_path.AfterFirst(_T('\\'));
                    object_file_native = objOut + sep + obj_file_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();
                }
            }
        }
    }
    wxFileName o_file(object_file_native);
    wxFileName o_file_flat(object_file_flat_native);
    o_file.MakeAbsolute(prjbase.GetFullPath());
    o_file_flat.MakeAbsolute(prjbase.GetFullPath());
    object_dir_native = o_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    object_dir_flat_native = o_file_flat.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    object_file_absolute_native = o_file.GetFullPath();
    object_file_flat_absolute_native = o_file_flat.GetFullPath();
    tmp.SetExt(_T("depend"));
    dep_file_native = depsOut + sep + tmp.GetFullPath();
    wxFileName d_file(dep_file_native);
    d_file.MakeAbsolute(prjbase.GetFullPath());
    dep_dir_native = d_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    dep_file_absolute_native = o_file.GetFullPath();

    source_file = UnixFilename(source_file_native);
    QuoteStringIfNeeded(source_file);

    object_file = UnixFilename(object_file_native);
    QuoteStringIfNeeded(object_file);

    object_file_flat = UnixFilename(object_file_flat_native);
    QuoteStringIfNeeded(object_file_flat);

    dep_file = UnixFilename(dep_file_native);
    QuoteStringIfNeeded(dep_file);

    object_dir = UnixFilename(object_dir_native);
    QuoteStringIfNeeded(object_dir);

    object_dir_flat = UnixFilename(object_dir_flat_native);
    QuoteStringIfNeeded(object_dir_flat);

    dep_dir = UnixFilename(dep_dir_native);
    QuoteStringIfNeeded(dep_dir);

    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_absolute_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_absolute_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_absolute_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(source_file);
}
Пример #26
0
wxArrayString DirectCommands::GetCompileFileCommand(ProjectBuildTarget* target, ProjectFile* pf) const
{
    wxArrayString ret;
    wxArrayString ret_generated;

    // is it compilable?
    if (!pf || !pf->compile)
        return ret;

    if (pf->compilerVar.IsEmpty())
    {
        Manager::Get()->GetLogManager()->DebugLog(_("Cannot resolve compiler var for project file."));
        return ret;
    }

    Compiler* compiler = target
                       ? CompilerFactory::GetCompiler(target->GetCompilerID())
                       : m_pCompiler;
    if (!compiler)
    {
        Manager::Get()->GetLogManager()->DebugLog(_("Can't access compiler for file."));
        return ret;
    }

    const pfDetails& pfd = pf->GetFileDetails(target);
    wxString object      = (compiler->GetSwitches().UseFlatObjects)
                         ? pfd.object_file_flat : pfd.object_file;
    wxString object_dir  = (compiler->GetSwitches().UseFlatObjects)
                         ? pfd.object_dir_flat_native : pfd.object_dir_native;
    // create output dir
    if (!object_dir.IsEmpty() && !CreateDirRecursively(object_dir, 0755))
        Manager::Get()->GetLogManager()->DebugLog(_("Can't create object output directory:\n") + object_dir);

    // lookup file's type
    const FileType ft = FileTypeOf(pf->relativeFilename);

    bool is_resource = ft == ftResource;
    bool is_header   = ft == ftHeader;

    // allowed resources under all platforms: makes sense when cross-compiling for
    // windows under linux.
    // and anyway, if the user is dumb enough to try to compile resources without
    // having a resource compiler, (s)he deserves the upcoming build error ;)

    wxString compiler_cmd;
    if (!is_header || compiler->GetSwitches().supportsPCH)
    {
        const CompilerTool* tool = compiler->GetCompilerTool(is_resource ? ctCompileResourceCmd : ctCompileObjectCmd, pf->file.GetExt());

        // does it generate other files to compile?
        for (size_t i = 0; i < pf->generatedFiles.size(); ++i)
            AppendArray(GetCompileFileCommand(target, pf->generatedFiles[i]), ret_generated); // recurse

        pfCustomBuild& pcfb = pf->customBuild[compiler->GetID()];
        if (pcfb.useCustomBuildCommand)
            compiler_cmd = pcfb.buildCommand;
        else if (tool)
            compiler_cmd = tool->command;
        else
            compiler_cmd = wxEmptyString;

        wxString source_file;
        if (compiler->GetSwitches().UseFullSourcePaths)
            source_file = UnixFilename(pfd.source_file_absolute_native);
        else
            source_file = pfd.source_file;

#ifdef command_line_generation
        Manager::Get()->GetLogManager()->DebugLog(F(_T("GetCompileFileCommand[1]: compiler_cmd='%s', source_file='%s', object='%s', object_dir='%s'."),
                                                    compiler_cmd.wx_str(), source_file.wx_str(), object.wx_str(), object_dir.wx_str()));
#endif

        // for resource files, use short from if path because if windres bug with spaces-in-paths
        if (is_resource && compiler->GetSwitches().UseFullSourcePaths)
            source_file = pf->file.GetShortPath();

        QuoteStringIfNeeded(source_file);

#ifdef command_line_generation
        Manager::Get()->GetLogManager()->DebugLog(F(_T("GetCompileFileCommand[2]: source_file='%s'."),
                                                    source_file.wx_str()));
#endif

        m_pGenerator->GenerateCommandLine(compiler_cmd,
                                          target,
                                          pf,
                                          source_file,
                                          object,
                                          pfd.object_file_flat,
                                          pfd.dep_file);
    }

    if (!is_header && compiler_cmd.IsEmpty())
    {
        ret.Add(COMPILER_SIMPLE_LOG + _("Skipping file (no compiler program set): ") + pfd.source_file_native );
        return ret;
    }

    switch (compiler->GetSwitches().logging)
    {
        case clogFull:
            ret.Add(COMPILER_SIMPLE_LOG + compiler_cmd);
            break;

        case clogSimple:
            if (is_header)
                ret.Add(COMPILER_SIMPLE_LOG + _("Pre-compiling header: ") + pfd.source_file_native );
            else
                ret.Add(COMPILER_SIMPLE_LOG + _("Compiling: ") + pfd.source_file_native );
            break;

        case clogNone: // fall-through
        default:
            break;
    }

    AddCommandsToArray(compiler_cmd, ret);

    if (is_header)
        ret.Add(COMPILER_WAIT);

    if (ret_generated.GetCount())
    {
        // not only append commands for (any) generated files to be compiled
        // but also insert a "pause" to allow this file to generate its files first
        if (!is_header) // if is_header, the "pause" has already been added
            ret.Add(COMPILER_WAIT);
        AppendArray(ret_generated, ret);
    }

    // if it's a PCH, delete the previously generated PCH to avoid problems
    // (it 'll be recreated anyway)
    if ( (ft == ftHeader) && pf->compile )
    {
        wxString object_abs = (compiler->GetSwitches().UseFlatObjects)
                            ? pfd.object_file_flat_absolute_native
                            : pfd.object_file_absolute_native;

        if ( wxFileExists(object_abs) && !wxRemoveFile(object_abs) )
            Manager::Get()->GetLogManager()->DebugLog(_("Cannot remove old PCH file:\n") + object_abs);
    }

    return ret;
}
bool ClassWizardDlg::DoImpl()
{
    // Create the implementation file
    wxFileName implementationFname(UnixFilename(m_Implementation));
    implementationFname.MakeAbsolute(m_ImplDir);
    DoForceDirectory(implementationFname);

    // Create a new editor/file (probably based on a template setup by the user)
    cbEditor* new_ed = Manager::Get()->GetEditorManager()->New(implementationFname.GetFullPath());
    if (!new_ed)
    {
        cbMessageBox(_T("Class wizard can't continue.\n"
                        "Possibly the implementation file name is invalid.\n"
                        "Please check the entered file name."),
                     _T("Error"), wxICON_ERROR, this);
        return false;
    }

    // Obtain the buffer of the new file and replace any macros that might exist
    wxString buffer = new_ed->GetControl()->GetText();
    Manager::Get()->GetMacrosManager()->ReplaceMacros(buffer);

    buffer << _T("#include ") << m_HeaderInclude << m_EolStr;

    if (m_NameSpaces.GetCount())
    {
        buffer << m_EolStr;
        for (unsigned int i=0; i<m_NameSpaces.GetCount(); ++i)
        {
            buffer << _T("namespace ") << m_NameSpaces[i] << _T(" {") << m_EolStr;
        }
    }

    buffer << m_EolStr;
    buffer << m_Name << _T("::") << m_Name << _T("(") << m_Arguments << _T(")") << m_EolStr;
    buffer << _T("{") << m_EolStr;
    buffer << m_TabStr << _T("//ctor") << m_EolStr;
    buffer << _T("}") << m_EolStr;

    if (m_HasDestructor)
    {
        buffer << m_EolStr;
        buffer << m_Name << _T("::~") << m_Name << _T("()") << m_EolStr;
        buffer << _T("{") << m_EolStr;
        buffer << m_TabStr << _T("//dtor") << m_EolStr;
        buffer << _T("}") << m_EolStr;
    }

    if (m_HasCopyCtor)
    {
        buffer << m_EolStr;
        buffer << m_Name << _T("::") << m_Name << _T("(const ") << m_Name << _T("& other)") << m_EolStr;;
        buffer << _T("{") << m_EolStr;
        buffer << m_TabStr << _T("//copy ctor") << m_EolStr;
        buffer << _T("}") << m_EolStr;
    }

    if (m_HasAssignmentOp)
    {
        buffer << m_EolStr;
        buffer << m_Name << _T("& ") << m_Name << _T("::operator=(const ") << m_Name << _T("& rhs)") << m_EolStr;;
        buffer << _T("{") << m_EolStr;
        buffer << m_TabStr << _T("if (this == &rhs) return *this; // handle self assignment") << m_EolStr;
        buffer << m_TabStr << _T("//assignment operator") << m_EolStr;
        buffer << m_TabStr << _T("return *this;") << m_EolStr;
        buffer << _T("}") << m_EolStr;
    }

    if (m_NameSpaces.GetCount())
    {
        buffer << m_EolStr;
        for (int i=m_NameSpaces.GetCount(); i>0; --i)
        {
            buffer << _T("} // namespace ") << m_NameSpaces[i-1] << m_EolStr;
        }
    }

    new_ed->GetControl()->SetText(buffer);
    if (!new_ed->Save())
    {
        wxString msg;
        msg.Printf(_("Could not save implementation file %s.\nAborting..."), implementationFname.GetFullPath().c_str());
        cbMessageBox(msg, _("Error"), wxICON_ERROR, this);
        return false;
    }

    m_Implementation = implementationFname.GetFullPath();

    return true;
}
bool ClassWizardDlg::DoHeader()
{
    // Create the header file
    wxFileName headerFname(UnixFilename(m_Header));
    headerFname.MakeAbsolute(m_IncludeDir);
    DoForceDirectory(headerFname);

    // Create a new editor/file (probably based on a template setup by the user)
    cbEditor* new_ed = Manager::Get()->GetEditorManager()->New(headerFname.GetFullPath());
    if (!new_ed)
    {
        cbMessageBox(_T("Class wizard can't continue.\n"
                        "Possibly the header file name is invalid.\n"
                        "Please check the entered file name."),
                     _T("Error"), wxICON_ERROR, this);
        return false;
    }

    // Obtain the buffer of the new file and replace any macros that might exist
    wxString buffer = new_ed->GetControl()->GetText();
    Manager::Get()->GetMacrosManager()->ReplaceMacros(buffer);

    // let's start with the header file
    if (m_GuardBlock)
    {
        buffer << _T("#ifndef ") << m_GuardWord << m_EolStr;
        buffer << _T("#define ") << m_GuardWord << m_EolStr;
        buffer << m_EolStr;
    }

    if (!m_AncestorFilename.IsEmpty() && !m_AncestorFilename.IsSameAs(_T("<>")))
    {
        buffer << _T("#include ") << m_AncestorFilename << m_EolStr;
        buffer << m_EolStr;
    }

    for (unsigned int i=0; i<m_NameSpaces.GetCount(); ++i)
    {
        buffer << _T("namespace ") << m_NameSpaces[i] << _T(" {") << m_EolStr;
    }
    buffer << m_EolStr;

    // Begin of class
    buffer << _T("class ") << m_Name;
    if (m_Inherits)
    {
        buffer << _T(" : ") << m_AncestorScope << _T(" ") << m_Ancestor;
    }
    buffer << m_EolStr;
    buffer << _T("{") << m_EolStr;

    // focus: public
    buffer << m_TabStr << _T("public:") << m_EolStr;

    // ctor
    if (m_Documentation)
    {
        buffer << m_TabStr << m_TabStr << _T("/** Default constructor */") << m_EolStr;
    }
    buffer << m_TabStr << m_TabStr << m_Name << _T("(") << m_Arguments << _T(")")
           << (!m_GenerateImplementation ? _T(" {}") : _T(";")) << m_EolStr;

    if (m_HasDestructor)
    {
        if (m_Documentation)
        {
            buffer << m_TabStr << m_TabStr << _T("/** Default destructor */") << m_EolStr;
        }
        buffer << m_TabStr << m_TabStr;
        if (m_VirtualDestructor)
        {
            buffer << _T("virtual ");
        }
        buffer << _T('~') << m_Name << _T("()");
        buffer << (!m_GenerateImplementation ? _T(" {}") : _T(";")) << m_EolStr;
    }

    if (m_HasCopyCtor)
    {
        if (m_Documentation)
        {
            buffer << m_TabStr << m_TabStr
                   << _T("/** Copy constructor") << m_EolStr;
            buffer << m_TabStr << m_TabStr
                   << _T(" *  \\param other Object to copy from") << m_EolStr;
            buffer << m_TabStr << m_TabStr
                   << _T(" */") << m_EolStr;
        }
        buffer << m_TabStr << m_TabStr;
        buffer << m_Name << _T("(const ") << m_Name << _T("& other)");
        buffer << (!m_GenerateImplementation ? _T(" {}") : _T(";")) << m_EolStr;
    }

    if (m_HasAssignmentOp)
    {
        if (m_Documentation)
        {
            buffer << m_TabStr << m_TabStr
                   << _T("/** Assignment operator") << m_EolStr;
            buffer << m_TabStr << m_TabStr
                   << _T(" *  \\param other Object to assign from") << m_EolStr;
            buffer << m_TabStr << m_TabStr
                   << _T(" *  \\return A reference to this") << m_EolStr;
            buffer << m_TabStr << m_TabStr
                   << _T(" */") << m_EolStr;
        }
        buffer << m_TabStr << m_TabStr;
        buffer << m_Name << _T("& ") << _T("operator=(const ") << m_Name << _T("& other)");
        buffer << (!m_GenerateImplementation ? _T(" { return *this; }") : _T(";")) << m_EolStr;
    }
    buffer << m_EolStr;

    bool addnewline = false;
    std::vector<MemberVar>::iterator it = m_MemberVars.begin();
    while( it != m_MemberVars.end() )
    {
        if (!(*it).Get.IsEmpty())
        {
            addnewline = true;
            if (m_Documentation)
            {
                buffer << m_TabStr << m_TabStr
                       << _T("/** Access ") << (*it).Var << m_EolStr;
                buffer << m_TabStr << m_TabStr
                       << _T(" * \\return The current value of ") << (*it).Var << m_EolStr;
                buffer << m_TabStr << m_TabStr
                       << _T(" */") << m_EolStr;
            }
            buffer << m_TabStr << m_TabStr << (*it).Typ << _T(" ") << (*it).Get
                   << _T("() { return ") << (*it).Var << _T("; }") << m_EolStr;
        }
        if (!(*it).Set.IsEmpty())
        {
            addnewline = true;
            if (m_Documentation)
            {
                buffer << m_TabStr << m_TabStr
                       << _T("/** Set ") << (*it).Var << m_EolStr;
                buffer << m_TabStr << m_TabStr
                       << _T(" * \\param val New value to set") << m_EolStr;
                buffer << m_TabStr << m_TabStr
                       << _T(" */") << m_EolStr;
            }
            buffer << m_TabStr << m_TabStr << _T("void ") << (*it).Set << _T("(")
                   << (*it).Typ << _T(" val) { ") << (*it).Var << _T(" = val; }") << m_EolStr;
        }
        ++it;
    }

    if (addnewline)
        buffer << m_EolStr;

    addnewline = false;
    for( it = m_MemberVars.begin(); it != m_MemberVars.end(); ++it )
    {
        if ((*it).Scp == 0)
        {
            addnewline = true;
            buffer << m_TabStr << m_TabStr
                   << (*it).Typ << _T(" ") << (*it).Var << _T(";");

            if (m_Documentation)
                buffer << _T(" //!< Member variable \"") << (*it).Var << _T("\"");

            buffer << m_EolStr;
        }
    }

    if (addnewline)
        buffer << m_EolStr;

    // focus: protected
    buffer << m_TabStr << _T("protected:") << m_EolStr;

    for( it = m_MemberVars.begin(); it != m_MemberVars.end(); ++it )
    {
        if ((*it).Scp == 1)
        {
            buffer << m_TabStr << m_TabStr
                   << (*it).Typ << _T(" ") << (*it).Var << _T(";");

            if (m_Documentation)
                buffer << _T(" //!< Member variable \"") << (*it).Var << _T("\"");

            buffer << m_EolStr;
        }
    }
    buffer << m_EolStr;

    // focus: private
    buffer << m_TabStr << _T("private:") << m_EolStr;

    for( it = m_MemberVars.begin(); it != m_MemberVars.end(); ++it )
    {
        if ((*it).Scp == 2)
        {
            buffer << m_TabStr << m_TabStr
                   << (*it).Typ << _T(" ") << (*it).Var << _T(";");

            if (m_Documentation)
                buffer << _T(" //!< Member variable \"") << (*it).Var << _T("\"");

            buffer << m_EolStr;
        }
    }

    // End of class
    buffer << _T("};") << m_EolStr;

    if (m_NameSpaces.GetCount())
    {
        buffer << m_EolStr;
        for (int i=m_NameSpaces.GetCount(); i>0; --i)
        {
            buffer << _T("} // namespace ") << m_NameSpaces[i-1] << m_EolStr;
        }
    }

    if (m_GuardBlock)
    {
        buffer << m_EolStr;
        buffer << _T("#endif // ") << m_GuardWord << m_EolStr;
    }

    new_ed->GetControl()->SetText(buffer);
    if (!new_ed->Save())
    {
        wxString msg;
        msg.Printf(_("Could not save header file %s.\nAborting..."), headerFname.GetFullPath().c_str());
        cbMessageBox(msg, _("Error"), wxICON_ERROR, this);
        return false;
    }

    m_Header = headerFname.GetFullPath();

    return true;
}
Пример #29
0
wxArrayString DirectCommands::GetTargetLinkCommands(ProjectBuildTarget* target, bool force) const
{
    wxArrayString ret;

    wxString output = target->GetOutputFilename();
    Manager::Get()->GetMacrosManager()->ReplaceMacros(output, target);

    wxFileName out = UnixFilename(output);
    wxString linkfiles;
    wxString FlatLinkFiles;
    wxString resfiles;
    bool IsOpenWatcom = target->GetCompilerID().IsSameAs(_T("ow"));

    time_t outputtime;
    depsTimeStamp(output.mb_str(), &outputtime);
    if (!outputtime)
        force = true;
    wxArrayString fileMissing;
    if ( AreExternalDepsOutdated(target, out.GetFullPath(), &fileMissing) )
        force = true;

    if (!fileMissing.IsEmpty())
    {
        wxString warn;
#ifdef NO_TRANSLATION
        warn.Printf(wxT("WARNING: Target '%s': Unable to resolve %lu external dependenc%s:"),
                    target->GetFullTitle().wx_str(), static_cast<unsigned long>(fileMissing.Count()), wxString(fileMissing.Count() == 1 ? wxT("y") : wxT("ies")).wx_str());
#else
        warn.Printf(_("WARNING: Target '%s': Unable to resolve %lu external dependency/ies:"),
                    target->GetFullTitle().wx_str(), static_cast<unsigned long>(fileMissing.Count()));
#endif // NO_TRANSLATION
        ret.Add(COMPILER_WARNING_LOG + warn);
        for (size_t i = 0; i < fileMissing.Count(); ++i)
            ret.Add(COMPILER_NOTE_LOG + wxString(wxT(' '), 8) + fileMissing[i]);
    }

    Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;

    wxString prependHack; // part of the following hack
    if (target->GetTargetType() == ttStaticLib)
    {
        // QUICK HACK: some linkers (e.g. bcc, dmc) require a - or + in front of
        // object files for static library. What we 'll do here until we redesign
        // the thing, is to accept this symbol as part of the $link_objects macro
        // like this:
        // $+link_objects
        // $-link_objects
        // $-+link_objects
        // $+-link_objects
        //
        // So, we first scan the command for this special case and, if found,
        // set a flag so that the linkfiles array is filled with the correct options
        wxString compilerCmd = compiler ? compiler->GetCommand(ctLinkStaticCmd) : wxString(wxEmptyString);
        wxRegEx re(_T("\\$([-+]+)link_objects"));
        if (re.Matches(compilerCmd))
            prependHack = re.GetMatch(compilerCmd, 1);
    }

    // get all the linkable objects for the target
    MyFilesArray files = GetProjectFilesSortedByWeight(target, false, true);
    if (files.GetCount() == 0)
    {
        if (target->GetTargetType() != ttCommandsOnly)
            ret.Add(COMPILER_SIMPLE_LOG + _("Linking stage skipped (build target has no object files to link)"));
        return ret;
    }
    if (IsOpenWatcom && target->GetTargetType() != ttStaticLib)
        linkfiles << _T("file ");
    bool subseq(false);
    for (unsigned int i = 0; i < files.GetCount(); ++i)
    {
        ProjectFile* pf = files[i];

        // we have to test again for each file if it is to be compiled
        // and we can't check the file for existence because we 're still
        // generating the command lines that will create the files...
        wxString macro = _T("$compiler");
        m_pGenerator->GenerateCommandLine(macro, target, pf, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString);
        if (macro.IsEmpty())
            continue;

        const pfDetails& pfd = pf->GetFileDetails(target);
        wxString Object = (compiler->GetSwitches().UseFlatObjects) ? pfd.object_file_flat
                                                                   : pfd.object_file;

        if (FileTypeOf(pf->relativeFilename) == ftResource)
        {
            if (subseq)
                resfiles << _T(" ");
            // -----------------------------------------
            // Following lines have been modified for OpenWatcom
            if (IsOpenWatcom)
                resfiles << _T("option resource=") << Object;
            else
                resfiles << Object;
            // ------------------------------------------
        }
        else
        {
            // -----------------------------------------
            // Following lines have been modified for OpenWatcom
            if (IsOpenWatcom && target->GetTargetType() == ttStaticLib)
            {
                if (subseq)
                {
                    linkfiles << _T(" ");
                    FlatLinkFiles << _T(" ");
                }
                linkfiles << prependHack << Object; // see QUICK HACK above (prependHack)
                FlatLinkFiles << prependHack << pfd.object_file_flat; // see QUICK HACK above (prependHack)
            }
            else
            {
                if (subseq)
                {
                    linkfiles << compiler->GetSwitches().objectSeparator;
                    FlatLinkFiles << compiler->GetSwitches().objectSeparator;
                }
                linkfiles << prependHack << Object; // see QUICK HACK above (prependHack)
                FlatLinkFiles << prependHack << pfd.object_file_flat; // see QUICK HACK above (prependHack)
            }
            // -----------------------------------------
        }
        subseq = true;

        // timestamp check
        if (!force)
        {
            time_t objtime;
            depsTimeStamp(pfd.object_file_native.mb_str(), &objtime);
            // Honor compiler request to Use Flat Objects
            // (Settings/compiler/otherSettings/advancedOptions/Others/UseFlatObjects)
            if (compiler->GetSwitches().UseFlatObjects)
                depsTimeStamp(pfd.object_file_flat.mb_str(), &objtime);

            if (!objtime)
                force = true;
            if (objtime > outputtime)
                force = true;
        }
    }
    if (IsOpenWatcom)
    {
        linkfiles.Trim();
    }

    if (!force)
        return ret;

    // create output dir
    out.MakeAbsolute(m_pProject->GetBasePath());
    wxString dstname = out.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    Manager::Get()->GetMacrosManager()->ReplaceMacros(dstname, target);
    if (!dstname.IsEmpty() && !CreateDirRecursively(dstname, 0755))
    {
        cbMessageBox(_("Can't create output directory ") + dstname);
    }

    // add actual link command
    wxString kind_of_output;
    CommandType ct = ctCount; // get rid of compiler warning
    switch (target->GetTargetType())
    {
        case ttConsoleOnly:
            ct = ctLinkConsoleExeCmd;
            kind_of_output = _("console executable");
            break;

        case ttExecutable:
            ct = ctLinkExeCmd;
            kind_of_output = _("executable");
            break;

        case ttDynamicLib:
            ct = ctLinkDynamicCmd;
            kind_of_output = _("dynamic library");
            break;

        case ttStaticLib:
            ct = ctLinkStaticCmd;
            kind_of_output = _("static library");
            break;

        case ttNative:
            ct = ctLinkNativeCmd;
            kind_of_output = _("native");
            break;

        case ttCommandsOnly:
            // add target post-build commands
            ret.Clear();
            AppendArray(GetPostBuildCommands(target), ret);
            return ret;
            break;
        default:
            wxString ex;
            ex.Printf(_T("Encountered invalid TargetType (value = %d)"), target->GetTargetType());
            cbThrow(ex);
        break;
    }
    wxString compilerCmd = compiler->GetCommand(ct);
    m_pGenerator->GenerateCommandLine(compilerCmd,
                                      target,
                                      0,
                                      _T(""),
                                      linkfiles,
                                      FlatLinkFiles,
                                      resfiles);
    if (!compilerCmd.IsEmpty())
    {
        switch (compiler->GetSwitches().logging)
        {
            case clogFull:
                ret.Add(COMPILER_SIMPLE_LOG + compilerCmd);
                break;

            case clogSimple: // fall-through
            case clogNone:   // fall-through
            default: // linker always simple log (if not full)
                ret.Add(COMPILER_SIMPLE_LOG + _("Linking ") + kind_of_output + _T(": ") + output);
                break;
        }

        // for an explanation of the following, see GetTargetCompileCommands()
        if (target && ret.GetCount() != 0)
            ret.Add(COMPILER_TARGET_CHANGE + target->GetTitle());

        // the 'true' will make sure all commands will be prepended by
        // COMPILER_WAIT signal
        AddCommandsToArray(compilerCmd, ret, true, true);
    }
    else
        ret.Add(COMPILER_SIMPLE_LOG + _("Skipping linking (no linker program set): ") + output);

    return ret;
}
Пример #30
0
wxArrayString DirectCommands::GetCompileFileCommand(ProjectBuildTarget* target, ProjectFile* pf)
{
    wxArrayString ret;
    wxArrayString retGenerated;

    // is it compilable?
    if (!pf->compile || pf->compilerVar.IsEmpty())
        return ret;

    const pfDetails& pfd = pf->GetFileDetails(target);
    Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;
   // wxString Object = (compiler->GetSwitches().UseFlatObjects)?pfd.object_file_flat:pfd.object_file;
    wxString Object = (target->GetUseFlatObjects())?pfd.object_file_flat:pfd.object_file;



    // lookup file's type
    FileType ft = FileTypeOf(pf->relativeFilename);

    // create output dir
    if (!pfd.object_dir_native.IsEmpty() && !CreateDirRecursively(pfd.object_dir_native, 0755))
    {
        cbMessageBox(_("Can't create object output directory ") + pfd.object_dir_native);
    }

    bool isResource = ft == ftResource;
    bool isHeader = ft == ftHeader;



    // allowed resources under all platforms: makes sense when cross-compiling for
    // windows under linux.
    // and anyway, if the user is dumb enough to try to compile resources without
    // having a resource compiler, (s)he deserves the upcoming build error ;)

//#ifndef __WXMSW__
//    // not supported under non-win32 platforms
//    if (isResource)
//        return ret;
//#endif

    wxString compilerCmd,source_file,tempCompilerCmd(wxEmptyString);
    if (!isHeader || compiler->GetSwitches().supportsPCH)
    {
        const CompilerTool& tool = compiler->GetCompilerTool(isResource ? ctCompileResourceCmd : ctCompileObjectCmd, pf->file.GetExt());

        // does it generate other files to compile?
        for (size_t i = 0; i < pf->generatedFiles.size(); ++i)
        {
            AppendArray(GetCompileFileCommand(target, pf->generatedFiles[i]), retGenerated); // recurse
        }

        pfCustomBuild& pcfb = pf->customBuild[compiler->GetID()];
        compilerCmd = pcfb.useCustomBuildCommand
                        ? pcfb.buildCommand
                        : tool.command;

        if (target->GetUseFullSourcePaths())
        {
            source_file = UnixFilename(pfd.source_file_absolute_native);
            // for resource files, use short from if path because if windres bug with spaces-in-paths
            if (isResource)
                source_file = pf->file.GetShortPath();
        }
        else
            source_file = pfd.source_file;
        QuoteStringIfNeeded(source_file);
        compiler->GenerateCommandLine(compilerCmd,
                                         target,
                                         pf,
                                         source_file,
                                         Object,
                                         pfd.object_file_flat,
                                         pfd.dep_file);
    }



    if (!compilerCmd.IsEmpty()) // my lcy 1
    {
        switch (compiler->GetSwitches().logging)
        {
            case clogFull:
                ret.Add(wxString(COMPILER_SIMPLE_LOG) + compilerCmd);
                break;

            case clogSimple:
                if (isHeader)
                    ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Precompiling header: ") + pfd.source_file_native);
                else
                    ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Compiling: ") + pfd.source_file_native);
                break;

            default:
                break;
        }

        AddCommandsToArray(compilerCmd, ret);
        if(m_pCurrTarget->GetGenerateEachLit())
        AddCommandsToArray(GenerateLitForEachObj(Object,compiler->GetPrograms().OBJDUMP),ret);
        if (isHeader)
            ret.Add(wxString(COMPILER_WAIT));
        if (retGenerated.GetCount())
        {
            // not only append commands for (any) generated files to be compiled
            // but also insert a "pause" to allow this file to generate its files first
            if (!isHeader) // if isHeader, the "pause" has already been added
                ret.Add(wxString(COMPILER_WAIT));
            AppendArray(retGenerated, ret);
        }

        // if it's a PCH, delete the previously generated PCH to avoid problems
        // (it 'll be recreated anyway)
        if (FileTypeOf(pf->relativeFilename) == ftHeader && pf->compile)
        {
            wxString ObjectAbs = (m_pCurrTarget->GetUseFlatObjects())?pfd.object_file_flat_absolute_native:pfd.object_file_absolute_native;
            wxRemoveFile(ObjectAbs);
        }
    }
    else // lcy skip
    {

         ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping file (no compiler program set): ") + pfd.source_file_native);
    }

    return ret;
}