#include "cmdline.h" extern char STSbuf[256]; static int OutputTextData(File *file, SInt16 stage, OSType maccreator, OSType mactype) { int ret = 0; SInt32 size; if (file->textdata) { size = GetHandleSize(file->textdata); if (stage != CmdLineStageMask_Dp || optsCmdLine.toDisk & CmdLineStageMask_Dp) { if (!(file->writeToDisk & stage)) { ret = ShowHandle(file->textdata, size, 0); } else { if (optsCmdLine.verbose) CLReport(15, OS_SpecToStringRelative(&file->outfss, NULL, STSbuf, sizeof(STSbuf))); ret = WriteHandleToFile(&file->outfss, file->textdata, size, maccreator, mactype); file->wroteToDisk |= stage; } } else { if (optsCompiler.outMakefile[0]) { ret = AppendHandleToFile(&clState.makefileSpec, file->textdata, size, maccreator, mactype); } else { ret = ShowHandle(file->textdata, size, 0); } } DisposeHandle(file->textdata); file->textdata = NULL; } return ret; } static int fstrcat(char *file, const char *add, SInt32 length) { if (strlen(file) + strlen(add) >= length) { return 0; } else { strcat(file, add); return 1; } } static void extstrcat(char *file, const char *ext) { if (!fstrcat(file, ext, 64)) strcpy(file + 63 - strlen(ext), ext); } int GetOutputFile(File *file, SInt16 stage) { int err; char tempoutfilename[256]; char *targetoutfilename; Boolean specifiedName; const char *ext; const CWObjectFlags *cof; char tmpname[256]; char *env; char *extptr; char *fnptr; char text[64]; char *inname; OSPathSpec tmppath; if (optsCmdLine.toDisk & stage) file->writeToDisk |= stage; if (file->outfileowner == stage) { targetoutfilename = file->outfilename; specifiedName = file->outfilename[0] && !(file->tempOnDisk & stage); if (specifiedName) { file->writeToDisk |= stage; file->tempOnDisk &= ~stage; } } else { targetoutfilename = tempoutfilename; specifiedName = 0; } if (!(stage & (optsCmdLine.toDisk | file->writeToDisk | file->tempOnDisk))) { if ((stage == CmdLineStageMask_Cg) && (optsCmdLine.stages & CmdLineStageMask_Ds) && (optsCmdLine.state == OptsCmdLineState_2) && optsCompiler.keepObjects) file->writeToDisk |= stage; else file->tempOnDisk |= stage; } if (!specifiedName && (stage & (optsCmdLine.toDisk | file->writeToDisk | file->tempOnDisk))) { cof = Plugin_CL_GetObjectFlags(file->compiler); if (stage == CmdLineStageMask_Pp) { ext = optsCompiler.ppFileExt[0] ? optsCompiler.ppFileExt : cof->ppFileExt; } else if (stage == CmdLineStageMask_Ds) { ext = optsCompiler.disFileExt[0] ? optsCompiler.disFileExt : cof->disFileExt; } else if (stage == CmdLineStageMask_Dp) { ext = optsCompiler.depFileExt[0] ? optsCompiler.depFileExt : cof->depFileExt; } else if (stage == CmdLineStageMask_Cg) { ext = optsCompiler.objFileExt[0] ? optsCompiler.objFileExt : cof->objFileExt; if (!(file->objectflags & 0x80000000) && !specifiedName) ext = NULL; } else { ext = NULL; } if (ext && ext[0]) { if (ext[0] != '.') { snprintf(text, sizeof(text), ".%s", ext); } else { strncpy(text, ext, sizeof(text) - 1); text[sizeof(text) - 1] = 0; } if ((file->tempOnDisk & stage) && !(optsCmdLine.stages & CmdLineStageMask_Dp)) { env = getenv("TEMP"); if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) env = getenv("TMP"); if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) env = getenv("TMPDIR"); if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) env = "/tmp"; if (!env || !env[0] || OS_MakePathSpec(NULL, env, &tmppath)) env = "."; snprintf(tmpname, sizeof(tmpname), "%s%c%s", env, OS_PATHSEP, OS_GetFileNamePtr(file->srcfilename)); inname = tmpname; } else if (!optsCompiler.relPathInOutputDir) { inname = OS_GetFileNamePtr(file->srcfilename); } else { inname = file->srcfilename; } fnptr = OS_GetFileNamePtr(inname); extptr = strrchr(fnptr, '.'); if (!extptr || ext[0] == '.') extptr = fnptr + strlen(fnptr); if (extptr - fnptr + strlen(text) >= sizeof(text)) extptr = &fnptr[sizeof(text) - 1] - strlen(text); snprintf(targetoutfilename, 256, "%.*s%s", extptr - inname, inname, text); } else { *targetoutfilename = 0; file->writeToDisk &= ~stage; file->tempOnDisk &= ~stage; } } if (stage & (file->writeToDisk | file->tempOnDisk)) { err = OS_MakeSpecWithPath(&gTarg->outputDirectory, targetoutfilename, !optsCompiler.relPathInOutputDir, &file->outfss); if (!err) { if (OS_EqualSpec(&file->srcfss, &file->outfss)) { if (specifiedName) { CLReportError(102, targetoutfilename); file->writeToDisk &= ~stage; file->tempOnDisk &= ~stage; return 0; } file->writeToDisk &= ~stage; file->tempOnDisk &= ~stage; } } else { CLReportOSError(9, err, targetoutfilename, OS_PathSpecToString(&gTarg->outputDirectory, STSbuf, sizeof(STSbuf))); } return err == 0; } return 1; } static int SyntaxCheckFile(File *file) { return SendCompilerRequest(file->compiler, file, 0) != 0; } static int PreprocessFile(File *file) { const CWObjectFlags *cof; if (!(file->dropinflags & kCanpreprocess)) { CLReportWarning(53, Plugin_GetDropInName(file->compiler), file->srcfilename); return 1; } if (!SendCompilerRequest(file->compiler, file, 1)) return 0; if (!GetOutputFile(file, CmdLineStageMask_Pp)) return 0; if (file->textdata) { cof = Plugin_CL_GetObjectFlags(file->compiler); return OutputTextData( file, CmdLineStageMask_Pp, optsCompiler.ppFileCreator ? optsCompiler.ppFileCreator : cof->ppFileCreator, optsCompiler.ppFileType ? optsCompiler.ppFileType : cof->ppFileType); } CLReportError(96, "preprocessing", file->srcfilename); return 0; } static int DependencyMapFile(File *file, Boolean compileifnecessary) { OSHandle mf; const CWObjectFlags *cof; cof = Plugin_CL_GetObjectFlags(file->compiler); if (!(optsCmdLine.stages & (CmdLineStageMask_Pp | CmdLineStageMask_Cg)) && compileifnecessary) { if (!SendCompilerRequest(file->compiler, file, CmdLineStageMask_Dp)) return 0; } if (!GetOutputFile(file, CmdLineStageMask_Cg)) return 0; Deps_ListDependencies(&gTarg->incls, file, &mf); file->textdata = OS_CreateMacHandle(&mf); if (!GetOutputFile(file, CmdLineStageMask_Dp)) return 0; if (OutputTextData( file, CmdLineStageMask_Dp, optsCompiler.depFileCreator ? optsCompiler.depFileCreator : cof->depFileCreator, optsCompiler.depFileType ? optsCompiler.depFileType : cof->depFileType)) { return 1; } else { return 0; } } static int RecordBrowseInfo(File *file) { const CWObjectFlags *cof; if (!file->recordbrowseinfo) return 1; if (!file->browsedata) { CLReportError(101, Plugin_GetDropInName(file->compiler), OS_SpecToStringRelative(&file->srcfss, NULL, STSbuf, sizeof(STSbuf))); return 0; } if ((optsCmdLine.toDisk & CmdLineStageMask_Cg) && optsCompiler.browserEnabled) { cof = Plugin_CL_GetObjectFlags(file->compiler); if (!WriteBrowseData(file, optsCompiler.brsFileCreator ? optsCompiler.brsFileCreator : cof->brsFileCreator, optsCompiler.brsFileType ? optsCompiler.brsFileType : cof->brsFileType)) return 0; } return 1; } static int RecordObjectData(File *file) { const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); if (!file->objectdata) return 1; if (!WriteObjectFile(file, optsCompiler.objFileCreator ? optsCompiler.objFileCreator : cof->objFileCreator, optsCompiler.objFileType ? optsCompiler.objFileType : cof->objFileType)) return 0; return 1; } int StoreObjectFile(File *file) { if (file->wroteToDisk & CmdLineStageMask_Cg) return 1; if (!file->objectdata && !file->browsedata) return 1; if (GetOutputFile(file, CmdLineStageMask_Cg)) { if (!((file->writeToDisk | file->tempOnDisk) & CmdLineStageMask_Cg)) return 1; if (!RecordBrowseInfo(file) || !RecordObjectData(file)) return 0; file->wroteToDisk |= CmdLineStageMask_Cg; return 1; } return 0; } static int CompileFile(File *file) { int ret = 1; if (!(file->dropinflags & kCanprecompile) && ((optsCompiler.forcePrecompile == 1) || (file->mappingflags & kPrecompile))) { CLReportWarning(54, Plugin_GetDropInName(file->compiler), file->srcfilename); return 1; } if (optsCompiler.browserEnabled) { SInt16 id; int ret; char fullpath[256]; memset(file->browseoptions, 1, sizeof(file->browseoptions)); OS_SpecToString(&file->srcfss, fullpath, sizeof(fullpath)); ret = Browser_SearchAndAddFile(&clState.browseTableHandle, fullpath, &id); if (!ret) return 0; file->recordbrowseinfo = ret < 0; file->browseFileID = id; if (optsCmdLine.verbose > 1) CLReport(22, file->srcfilename, file->browseFileID); } else { memset(file->browseoptions, 0, sizeof(file->browseoptions)); file->recordbrowseinfo = 0; file->recordbrowseinfo = 0; file->browseFileID = 0; } if (!SendCompilerRequest(file->compiler, file, 2)) { ret = 0; } else { if ((!file->hasobjectcode || !file->objectdata) && (file->dropinflags & kGeneratescode) && (file->objectUsage & 2)) { CLReportError(96, "compiling", file->srcfilename); ret = 0; } else if (optsCmdLine.state == OptsCmdLineState_2 && !StoreObjectFile(file)) { ret = 0; } } return ret; } static int DisassembleWithLinker(File *file, Plugin *linker, SInt32 linkerDropinFlags) { char filename[256]; int ret; if (file->writeToDisk & CmdLineStageMask_Ds) { OS_SpecToString(&file->outfss, filename, sizeof(filename)); ret = ExecuteLinker(linker, linkerDropinFlags, file, (optsCmdLine.toDisk & CmdLineStageMask_Ds) ? NULL : filename, NULL); file->wroteToDisk |= CmdLineStageMask_Ds; return ret; } return ExecuteLinker(linker, linkerDropinFlags, file, NULL, NULL); } static int DisassembleFile(File *file) { Plugin *disasm; if (!file->hasobjectcode && !file->hasresources) { CLReportError(56, file->srcfilename); return 0; } if (!GetOutputFile(file, CmdLineStageMask_Ds)) return 0; if (file->dropinflags & kCandisassemble) { if (!SendDisassemblerRequest(file->compiler, file)) return 0; if (file->textdata) { const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); return OutputTextData( file, CmdLineStageMask_Ds, optsCompiler.disFileCreator ? optsCompiler.disFileCreator : cof->disFileCreator, optsCompiler.disFileType ? optsCompiler.disFileType : cof->disFileType); } CLReportError(96, "disassembling", file->srcfilename); return 0; } else { if ((gTarg->linkerDropinFlags & dropInExecutableTool) && !(gTarg->linkerDropinFlags & cantDisassemble)) return DisassembleWithLinker(file, gTarg->linker, gTarg->linkerDropinFlags); if ((gTarg->preLinkerDropinFlags & dropInExecutableTool) && !(gTarg->preLinkerDropinFlags & cantDisassemble)) return DisassembleWithLinker(file, gTarg->preLinker, gTarg->preLinkerDropinFlags); if (gTarg->linker && !(gTarg->linkerDropinFlags & cantDisassemble)) { if (SendDisassemblerRequest(gTarg->linker, file)) { if (file->textdata && GetHandleSize(file->textdata) > 0) { const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); return OutputTextData( file, CmdLineStageMask_Ds, optsCompiler.disFileCreator ? optsCompiler.disFileCreator : cof->disFileCreator, optsCompiler.disFileType ? optsCompiler.disFileType : cof->disFileType); } CLReportError(96, "disassembling", file->srcfilename); } return 0; } if (gTarg->preLinker && !(gTarg->preLinkerDropinFlags & cantDisassemble)) { if (SendDisassemblerRequest(gTarg->preLinker, file)) { if (file->textdata && GetHandleSize(file->textdata) > 0) { const CWObjectFlags *cof = Plugin_CL_GetObjectFlags(file->compiler); return OutputTextData( file, CmdLineStageMask_Ds, optsCompiler.disFileCreator ? optsCompiler.disFileCreator : cof->disFileCreator, optsCompiler.disFileType ? optsCompiler.disFileType : cof->disFileType); } CLReportError(96, "disassembling", file->srcfilename); } return 0; } if (gTarg->linker) CLReportError(58, Plugin_GetDropInName(gTarg->linker), Plugin_GetDropInName(file->compiler), file->srcfilename); else CLReportError(57, Plugin_GetDropInName(file->compiler), file->srcfilename); return 0; } } static int CompileEntry(File *file, Boolean *compiled) { UInt32 beginWork; UInt32 endWork; struct BuildInfo *tinfo = &gTarg->info; *compiled = 0; if (optsCmdLine.dryRun) { *compiled = 1; return 1; } if (!(file->sourceUsage & 1)) { if (file->mappingflags & kRsrcfile) *compiled = 1; return 1; } #line 835 OPTION_ASSERT(file->compiler); *compiled = 1; beginWork = OS_GetMilliseconds(); Browser_Initialize(&clState.browseTableHandle); Deps_ChangeSpecialAccessPath(&file->srcfss, 1); if ((optsCmdLine.stages == 0) && !SyntaxCheckFile(file)) return 0; if ((optsCmdLine.stages & CmdLineStageMask_Pp) && !PreprocessFile(file)) return 0; if ((optsCmdLine.stages & (CmdLineStageMask_Cg | CmdLineStageMask_Ds)) && !CompileFile(file)) return 0; if ((optsCmdLine.stages & CmdLineStageMask_Dp) && !DependencyMapFile(file, 1)) return 0; if ((optsCmdLine.stages & CmdLineStageMask_Ds) && !DisassembleFile(file)) return 0; if (optsCmdLine.verbose && (optsCmdLine.stages & CmdLineStageMask_Cg)) { const char *cun; const char *dun; const char *uun; CLReport(25, file->compiledlines); tinfo->linesCompiled += file->compiledlines; cun = dun = uun = "bytes"; CLReport(26, file->codesize, cun, file->idatasize, dun, file->udatasize, uun); } tinfo->codeSize += file->codesize; tinfo->iDataSize += file->idatasize; tinfo->uDataSize += file->udatasize; Browser_Terminate(&clState.browseTableHandle); endWork = OS_GetMilliseconds(); if (optsCmdLine.timeWorking) { if (optsCmdLine.verbose) CLReport(24, (endWork - beginWork) / 1000.0, "compile", "", "", ""); else CLReport(24, (endWork - beginWork) / 1000.0, "compile", "'", file->srcfilename, "'"); } return 1; } static void DumpFileAndPathInfo(void) { int i; int n; CLReport(84, "Framework search paths ([d] = default, [r] = recursive)"); n = Paths_Count(&FrameworkPaths); if (!n) { CLReport(85, "(none)", ""); } else { for (i = 0; i < n; i++) { Path *path = Paths_GetPath(&FrameworkPaths, i); #line 961 OPTION_ASSERT(path != NULL); CLReport(85, OS_PathSpecToString(path->spec, STSbuf, sizeof(STSbuf)), ((path->flags & 2) && path->recursive) ? " [d] [r]" : (path->flags & 2) ? " [d]" : path->recursive ? " [r]" : "" ); if (path->recursive && optsCmdLine.verbose > 2) { UInt16 j; for (j = 0; j < Paths_Count(path->recursive); j++) { Path *sub = Paths_GetPath(path->recursive, j); #line 976 OPTION_ASSERT(sub); CLReport(85, "\t", OS_PathSpecToString(sub->spec, STSbuf, sizeof(STSbuf))); } } } } n = Frameworks_GetCount(); if (Frameworks_GetCount()) { CLReport(84, "Included frameworks"); for (i = 0; i < n; i++) { char version[80]; Paths_FWInfo *info = Frameworks_GetInfo(i); #line 993 OPTION_ASSERT(info); version[0] = 0; strcpy(version, "\t("); if (!info->version.s[0]) { strcat(version, "Current)"); } else { strncat(version, info->version.s, sizeof(version) - 4); strcat(version, ")"); } CLReport(85, info->name.s, version); } } if (clState.plugintype == CWDROPINCOMPILERTYPE) CLReport(84, "User include search paths ([d] = default, [r] = recursive)"); else CLReport(84, "Library search paths ([d] = default, [r] = recursive)"); if (!Paths_Count(&gTarg->userPaths) && clState.plugintype == CWDROPINCOMPILERTYPE) { CLReport(85, "(none)", ""); } else { for (i = 0; i < Paths_Count(&gTarg->userPaths); i++) { Path *path = Paths_GetPath(&gTarg->userPaths, i); #line 1024 OPTION_ASSERT(path != NULL); CLReport(85, OS_PathSpecToString(path->spec, STSbuf, sizeof(STSbuf)), ((path->flags & 2) && path->recursive) ? " [d] [r]" : (path->flags & 2) ? " [d]" : path->recursive ? " [r]" : "" ); if (path->recursive && optsCmdLine.verbose > 2) { UInt16 j; for (j = 0; j < Paths_Count(path->recursive); j++) { Path *sub = Paths_GetPath(path->recursive, j); #line 1039 OPTION_ASSERT(sub); CLReport(85, "\t", OS_PathSpecToString(sub->spec, STSbuf, sizeof(STSbuf))); } } } } if (clState.plugintype == CWDROPINCOMPILERTYPE) CLReport(84, "System include search paths ([d] = default, [r] = recursive)"); if (!Paths_Count(&gTarg->sysPaths)) CLReport(85, "(none)", ""); for (i = 0; i < Paths_Count(&gTarg->sysPaths); i++) { Path *path = Paths_GetPath(&gTarg->sysPaths, i); #line 1054 OPTION_ASSERT(path != NULL); CLReport(85, OS_PathSpecToString(path->spec, STSbuf, sizeof(STSbuf)), ((path->flags & 2) && path->recursive) ? " [d] [r]" : (path->flags & 2) ? " [d]" : path->recursive ? " [r]" : "" ); if (path->recursive && optsCmdLine.verbose > 2) { UInt16 j; for (j = 0; j < Paths_Count(path->recursive); j++) { Path *sub = Paths_GetPath(path->recursive, j); #line 1069 OPTION_ASSERT(sub); CLReport(85, "\t", OS_PathSpecToString(sub->spec, STSbuf, sizeof(STSbuf))); } } } if (clState.plugintype == CWDROPINCOMPILERTYPE) CLReport(84, "Files in project (relative to CWD)"); else CLReport(84, "Link order for project (relative to CWD)"); for (i = 0; i < Files_Count(&gTarg->files); i++) { File *file = Files_GetFile(&gTarg->files, i); if (!VFiles_Find(gTarg->virtualFiles, file->srcfilename)) CLReport(85, OS_SpecToStringRelative(&file->srcfss, NULL, STSbuf, sizeof(STSbuf)), ""); else CLReport(85, file->srcfilename, "\t(virtual file)"); } } int CompileFilesInProject(void) { struct BuildInfo *tinfo; SInt32 index; SInt32 startTime; SInt32 endTime; int ignored; int compiled; Boolean failed; failed = 0; startTime = OS_GetMilliseconds(); InitializeIncludeCache(); if (optsCmdLine.verbose > 1) DumpFileAndPathInfo(); if (!SendTargetInfoRequest(gTarg, gTarg->linker, gTarg->linkerDropinFlags)) return Result_Failed; ignored = 0; compiled = 0; for (index = 0; index < Files_Count(&gTarg->files); index++) { int ret; File *file; Boolean wascompiled; file = Files_GetFile(&gTarg->files, index); if (!file->outfileowner) file->outfileowner = CmdLineStageMask_Cg; ret = CompileEntry(file, &wascompiled); if (ret) { if (wascompiled) compiled++; if (!wascompiled) ignored++; if (CheckForUserBreak()) return Result_Cancelled; } if (!ret) { if (optsCompiler.noFail) { failed = 1; clState.countWarnings = 0; clState.countErrors = 0; clState.withholdWarnings = 0; clState.withholdErrors = 0; } else { return CheckForUserBreak() ? Result_Cancelled : Result_Failed; } } } if (optsCmdLine.stages & CmdLineStageMask_Dp) { for (index = 0; index < Files_Count(&gTarg->pchs); index++) { int ret; File *file; file = Files_GetFile(&gTarg->pchs, index); ret = DependencyMapFile(file, 0); if (!ret) { if (optsCompiler.noFail) { failed = 1; clState.countWarnings = 0; clState.countErrors = 0; clState.withholdWarnings = 0; clState.withholdErrors = 0; } else { return CheckForUserBreak() ? Result_Cancelled : Result_Failed; } } } } CleanupIncludeCache(); tinfo = &gTarg->info; if (optsCmdLine.verbose && compiled > 1) { const char *cun; const char *dun; const char *uun; cun = dun = uun = "bytes"; CLReport(27, tinfo->codeSize, cun, tinfo->iDataSize, dun, tinfo->uDataSize, uun); } endTime = OS_GetMilliseconds(); if (optsCmdLine.timeWorking) CLReport(24, (endTime - startTime) / 1000.0, "compile", "", "", "project"); if (ignored > 0 && compiled == 0 && (gTarg->preLinker || gTarg->linker)) CLReportError(29); if (failed) return Result_Failed; return CheckForUserBreak() ? Result_Cancelled : Result_Success; } static int PostLinkFilesInProject(void) { SInt32 index; SInt32 startTime; SInt32 endTime; File *file; FSSpec fss; startTime = OS_GetMilliseconds(); for (index = 0; index < Files_Count(&gTarg->files); index++) { file = Files_GetFile(&gTarg->files, index); OS_OSSpec_To_FSSpec(&file->srcfss, &fss); gTarg->targetinfo->outfile = fss; gTarg->targetinfo->runfile = fss; gTarg->targetinfo->symfile = fss; if (!SendLinkerRequest(gTarg->postLinker, gTarg->postLinkerDropinFlags, gTarg->targetinfo)) { return CheckForUserBreak() ? Result_Cancelled : Result_Failed; } else { if (CheckForUserBreak()) return Result_Cancelled; } } endTime = OS_GetMilliseconds(); if (optsCmdLine.timeWorking) CLReport(24, (endTime - startTime) / 1000.0, "compile", "", "", "project"); return CheckForUserBreak() ? Result_Cancelled : Result_Success; } int LinkProject(void) { SInt32 startTime; SInt32 endTime; startTime = OS_GetMilliseconds(); if (!SendTargetInfoRequest(gTarg, gTarg->linker, gTarg->linkerDropinFlags)) return Result_Failed; if (!SetupTemporaries()) return Result_Failed; if (gTarg->preLinker && optsLinker.callPreLinker && optsCmdLine.state == OptsCmdLineState_3) { SInt32 subStart; SInt32 subEnd; subStart = OS_GetMilliseconds(); if (gTarg->preLinkerDropinFlags & dropInExecutableTool) { if (!ExecuteLinker(gTarg->preLinker, gTarg->preLinkerDropinFlags, NULL, NULL, NULL)) return Result_Failed; } else if (!optsCmdLine.dryRun) { if (!SendLinkerRequest(gTarg->preLinker, gTarg->preLinkerDropinFlags, gTarg->targetinfo)) return CheckForUserBreak() ? Result_Cancelled : Result_Failed; } subEnd = OS_GetMilliseconds(); if (optsCmdLine.timeWorking) CLReport(24, (subEnd - subStart) / 1000.0, "prelink project", "", "", ""); } if (gTarg->linker && optsLinker.callLinker && optsCmdLine.state == OptsCmdLineState_3) { SInt32 subStart; SInt32 subEnd; subStart = OS_GetMilliseconds(); if (gTarg->linkerDropinFlags & dropInExecutableTool) { if (!ExecuteLinker(gTarg->linker, gTarg->linkerDropinFlags, NULL, NULL, NULL)) return Result_Failed; } else if (!optsCmdLine.dryRun) { if (!SendLinkerRequest(gTarg->linker, gTarg->linkerDropinFlags, gTarg->targetinfo)) return CheckForUserBreak() ? Result_Cancelled : Result_Failed; } subEnd = OS_GetMilliseconds(); if (optsCmdLine.timeWorking) CLReport(24, (subEnd - subStart) / 1000.0, "link project", "", "", ""); } if (gTarg->postLinker && optsLinker.callPostLinker && optsCmdLine.state == OptsCmdLineState_3) { SInt32 subStart; SInt32 subEnd; FSSpec fss; OSSpec outfile; subStart = OS_GetMilliseconds(); if (gTarg->postLinkerDropinFlags & dropInExecutableTool) { if (!ExecuteLinker(gTarg->postLinker, gTarg->postLinkerDropinFlags, NULL, NULL, NULL)) return Result_Failed; } else if (!optsCmdLine.dryRun) { if (!SendTargetInfoRequest(gTarg, gTarg->linker, gTarg->linkerDropinFlags)) return Result_Failed; if (gTarg->targetinfo->outputType == linkOutputFile) fss = gTarg->targetinfo->outfile; if (gTarg->targetinfo->outputType != linkOutputNone) { if (!SendLinkerRequest(gTarg->postLinker, gTarg->postLinkerDropinFlags, gTarg->targetinfo)) return CheckForUserBreak() ? Result_Cancelled : Result_Failed; if (!SendTargetInfoRequest(gTarg, gTarg->postLinker, gTarg->postLinkerDropinFlags)) return Result_Failed; } } subEnd = OS_GetMilliseconds(); if (optsCmdLine.timeWorking) CLReport(24, (subEnd - subStart) / 1000.0, "postlink project", "", "", ""); if (!optsLinker.keepLinkerOutput && gTarg->targetinfo->outputType == linkOutputFile) { if (optsCmdLine.verbose > 1) { OS_FSSpec_To_OSSpec(&fss, &outfile); CLReport(19, OS_SpecToString(&outfile, STSbuf, sizeof(STSbuf))); } FSpDelete(&fss); } } if (!DeleteTemporaries()) return Result_Failed; endTime = OS_GetMilliseconds(); if (optsCmdLine.timeWorking) CLReport(24, (endTime - startTime) / 1000.0, "finish link stage", "", "", ""); return Result_Success; }