Beispiel #1
0
wxArrayString DirectCommands::GetPostBuildCommands(ProjectBuildTarget* target)
{
    Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;
    wxArrayString buildcmds = target ? target->GetCommandsAfterBuild() : m_pProject->GetCommandsAfterBuild();

    if (!buildcmds.IsEmpty())
    {
        wxString title = target ? target->GetTitle() : m_pProject->GetTitle();
        wxArrayString tmp;
        for (size_t i = 0; i < buildcmds.GetCount(); ++i)
        {
            if(target)
                compiler->GenerateCommandLine(buildcmds[i], target, 0, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString);
            else
                compiler->GenerateCommandLine(buildcmds[i], m_pProject->GetCurrentlyCompilingTarget(), 0, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString);

            tmp.Add(wxString(COMPILER_WAIT)); // all commands should wait for queue to empty first
            tmp.Add(wxString(COMPILER_SIMPLE_LOG) + buildcmds[i]);
            tmp.Add(buildcmds[i]);
        }
        buildcmds = tmp;

        if (target)
            buildcmds.Insert(wxString(COMPILER_SIMPLE_LOG) + _("Running target post-build steps"), 0);
        else
            buildcmds.Insert(wxString(COMPILER_SIMPLE_LOG) + _("Running project post-build steps"), 0);

        if(m_doYield)
            Manager::Yield();
    }
    return buildcmds;
}
Beispiel #2
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;
}
Beispiel #3
0
/// This is to be used *only* for files not belonging to a project!!!
wxArrayString DirectCommands::GetCompileSingleFileCommand(const wxString& filename)
{
    wxArrayString ret;

    // lookup file's type
    FileType ft = FileTypeOf(filename);

    // is it compilable?
    if (ft != ftSource)
        return ret;

    wxFileName fname(filename);
    fname.SetExt(m_pCompiler->GetSwitches().objectExtension);
    wxString o_filename = fname.GetFullPath();
    wxString srcExt = fname.GetExt();
//    if(m_pCompiler->GetName().Matches(_T("dsp")))  /// 2012-8-27 lcy
//        fname.SetExt(FileFilters::DSP563_EXT);
//    else if(m_pCompiler->GetName().Matches(_T("mc")))
//        fname.SetExt(FileFilters::OR32_EXT);
//    else
    fname.SetExt(FileFilters::EXECUTABLE_EXT);
    wxString exe_filename = fname.GetFullPath();

    wxString s_filename = filename;
    QuoteStringIfNeeded(s_filename);
    QuoteStringIfNeeded(o_filename);

    Compiler* compiler = CompilerFactory::GetDefaultCompiler();
    wxString compilerCmd = compiler->GetCommand(ctCompileObjectCmd, srcExt);
    compiler->GenerateCommandLine(compilerCmd,
                                     0,
                                     0,
                                     s_filename,
                                     o_filename,
                                     o_filename,
                                     wxEmptyString);
    wxString linkerCmd = compiler->GetCommand(ctLinkConsoleExeCmd, fname.GetExt());
    compiler->GenerateCommandLine(linkerCmd,
                                     0,
                                     0,
                                     wxEmptyString,
                                     o_filename,
                                     o_filename,
                                     wxEmptyString);

//    wxString asmCmd = compiler->GetCommand(ctCompileAsmCmd, _T("asm"));  /// 2012-8-27 lcy
//    compiler->GenerateCommandLine(asmCmd,
//                                     0,
//                                     0,
//                                     wxEmptyString,
//                                     o_filename,
//                                     o_filename,
//                                     wxEmptyString);


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

            case clogSimple:
                ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Compiling: ") + filename);
                break;

            default:
                break;
        }
        AddCommandsToArray(compilerCmd, ret);
    }
    else
        ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping file (no compiler program set): ") + filename);

    if (!linkerCmd.IsEmpty())
    {
        switch (m_pCompiler->GetSwitches().logging)
        {
            case clogFull:
                ret.Add(wxString(COMPILER_SIMPLE_LOG) + linkerCmd);
                break;

            default:
                ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking console executable: ") + exe_filename);
                break;
        }
        AddCommandsToArray(linkerCmd, ret, true);
    }
    else
        ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping linking (no linker program set): ") + exe_filename);

//  if (!asmCmd.IsEmpty())
//    {
//        switch (m_pCompiler->GetSwitches().logging)
//        {
//            case clogFull:
//                ret.Add(wxString(COMPILER_SIMPLE_LOG) + asmCmd);
//                break;
//
//            default:
//                ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Linking console executable: ") + exe_filename);
//                break;
//        }
//        AddCommandsToArray(asmCmd, ret, true);
//    }
//    else
//        ret.Add(wxString(COMPILER_SIMPLE_LOG) + _("Skipping linking (no linker program set): ") + exe_filename);
    return ret;
}
Beispiel #4
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;
}