diff options
Diffstat (limited to 'compiler/extccomp.nim')
-rw-r--r-- | compiler/extccomp.nim | 113 |
1 files changed, 56 insertions, 57 deletions
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 16b0d614d..69698ae09 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -14,7 +14,7 @@ import ropes, os, strutils, osproc, platform, condsyms, options, msgs, - lineinfos, std / sha1, streams + lineinfos, std / sha1, streams, pathutils type TInfoCCProp* = enum # properties of the C compiler: @@ -429,12 +429,13 @@ proc initVars*(conf: ConfigRef) = if len(conf.ccompilerpath) == 0: conf.ccompilerpath = getConfigVar(conf, conf.cCompiler, ".path") -proc completeCFilePath*(conf: ConfigRef; cfile: string, createSubDir: bool = true): string = +proc completeCFilePath*(conf: ConfigRef; cfile: AbsoluteFile, + createSubDir: bool = true): AbsoluteFile = result = completeGeneratedFilePath(conf, cfile, createSubDir) -proc toObjFile*(conf: ConfigRef; filename: string): string = +proc toObjFile*(conf: ConfigRef; filename: AbsoluteFile): AbsoluteFile = # Object file for compilation - result = filename & "." & CC[conf.cCompiler].objExt + result = AbsoluteFile(filename.string & "." & CC[conf.cCompiler].objExt) proc addFileToCompile*(conf: ConfigRef; cf: Cfile) = conf.toCompile.add(cf) @@ -447,8 +448,8 @@ proc resetCompilationLists*(conf: ConfigRef) = # Maybe we can do that in checkDep on the other hand? conf.externalToLink.setLen 0 -proc addExternalFileToLink*(conf: ConfigRef; filename: string) = - conf.externalToLink.insert(filename, 0) +proc addExternalFileToLink*(conf: ConfigRef; filename: AbsoluteFile) = + conf.externalToLink.insert(filename.string, 0) proc execWithEcho(conf: ConfigRef; cmd: string, msg = hintExecuting): int = rawMessage(conf, msg, cmd) @@ -459,14 +460,15 @@ proc execExternalProgram*(conf: ConfigRef; cmd: string, msg = hintExecuting) = rawMessage(conf, errGenerated, "execution of an external program failed: '$1'" % cmd) -proc generateScript(conf: ConfigRef; projectFile: string, script: Rope) = - let (dir, name, ext) = splitFile(projectFile) - let filename = getNimcacheDir(conf) / addFileExt("compile_" & name, - platform.OS[conf.target.targetOS].scriptExt) +proc generateScript(conf: ConfigRef; projectFile: AbsoluteFile, script: Rope) = + let (_, name, _) = splitFile(projectFile) + let filename = getNimcacheDir(conf) / RelativeFile(addFileExt("compile_" & name, + platform.OS[conf.target.targetOS].scriptExt)) if writeRope(script, filename): - copyFile(conf.libpath / "nimbase.h", getNimcacheDir(conf) / "nimbase.h") + copyFile(conf.libpath / RelativeFile"nimbase.h", + getNimcacheDir(conf) / RelativeFile"nimbase.h") else: - rawMessage(conf, errGenerated, "could not write to file: " & filename) + rawMessage(conf, errGenerated, "could not write to file: " & filename.string) proc getOptSpeed(conf: ConfigRef; c: TSystemCC): string = result = getConfigVar(conf, c, ".options.speed") @@ -490,7 +492,7 @@ proc noAbsolutePaths(conf: ConfigRef): bool {.inline.} = # `optGenMapping` is included here for niminst. result = conf.globalOptions * {optGenScript, optGenMapping} != {} -proc cFileSpecificOptions(conf: ConfigRef; cfilename: string): string = +proc cFileSpecificOptions(conf: ConfigRef; cfilename: AbsoluteFile): string = result = conf.compileOptions for option in conf.compileOptionsCmd: if strutils.find(result, option, 0) < 0: @@ -513,7 +515,7 @@ proc cFileSpecificOptions(conf: ConfigRef; cfilename: string): string = if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key)) proc getCompileOptions(conf: ConfigRef): string = - result = cFileSpecificOptions(conf, "__dummy__") + result = cFileSpecificOptions(conf, AbsoluteFile"__dummy__") proc getLinkOptions(conf: ConfigRef): string = result = conf.linkOptions & " " & conf.linkOptionsCmd & " " @@ -526,8 +528,8 @@ proc needsExeExt(conf: ConfigRef): bool {.inline.} = result = (optGenScript in conf.globalOptions and conf.target.targetOS == osWindows) or (conf.target.hostOS == osWindows) -proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: string): string = - result = if conf.cmd == cmdCompileToCpp and not cfile.endsWith(".c"): +proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: AbsoluteFile): string = + result = if conf.cmd == cmdCompileToCpp and not cfile.string.endsWith(".c"): CC[compiler].cppCompiler else: CC[compiler].compilerExe @@ -539,7 +541,7 @@ proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: string): string proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string = result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe elif optMixedMode in conf.globalOptions and conf.cmd != cmdCompileToCpp: CC[compiler].cppCompiler - else: getCompilerExe(conf, compiler, "") + else: getCompilerExe(conf, compiler, AbsoluteFile"") proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string = var c = conf.cCompiler @@ -565,43 +567,42 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string = includeCmd = "" compilePattern = getCompilerExe(conf, c, cfile.cname) - var cf = if noAbsolutePaths(conf): extractFilename(cfile.cname) + var cf = if noAbsolutePaths(conf): AbsoluteFile extractFilename(cfile.cname.string) else: cfile.cname var objfile = - if cfile.obj.len == 0: + if cfile.obj.isEmpty: if not cfile.flags.contains(CfileFlag.External) or noAbsolutePaths(conf): - toObjFile(conf, cf) + toObjFile(conf, cf).string else: - completeCFilePath(conf, toObjFile(conf, cf)) + completeCFilePath(conf, toObjFile(conf, cf)).string elif noAbsolutePaths(conf): - extractFilename(cfile.obj) + extractFilename(cfile.obj.string) else: - cfile.obj + cfile.obj.string # D files are required by nintendo switch libs for # compilation. They are basically a list of all includes. let dfile = objfile.changeFileExt(".d").quoteShell() objfile = quoteShell(objfile) - cf = quoteShell(cf) + let cfsh = quoteShell(cf) result = quoteShell(compilePattern % [ "dfile", dfile, - "file", cf, "objfile", objfile, "options", options, - "include", includeCmd, "nim", getPrefixDir(conf), - "nim", getPrefixDir(conf), "lib", conf.libpath]) + "file", cfsh, "objfile", objfile, "options", options, + "include", includeCmd, "nim", getPrefixDir(conf).string, + "lib", conf.libpath.string]) add(result, ' ') addf(result, CC[c].compileTmpl, [ "dfile", dfile, - "file", cf, "objfile", objfile, + "file", cfsh, "objfile", objfile, "options", options, "include", includeCmd, "nim", quoteShell(getPrefixDir(conf)), - "nim", quoteShell(getPrefixDir(conf)), "lib", quoteShell(conf.libpath)]) proc footprint(conf: ConfigRef; cfile: Cfile): SecureHash = result = secureHash( - $secureHashFile(cfile.cname) & + $secureHashFile(cfile.cname.string) & platform.OS[conf.target.targetOS].name & platform.CPU[conf.target.targetCPU].name & extccomp.CC[conf.cCompiler].name & @@ -614,14 +615,14 @@ proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool = var hashFile = toGeneratedFile(conf, conf.withPackageName(cfile.cname), "sha1") var currentHash = footprint(conf, cfile) var f: File - if open(f, hashFile, fmRead): + if open(f, hashFile.string, fmRead): let oldHash = parseSecureHash(f.readLine()) close(f) result = oldHash != currentHash else: result = true if result: - if open(f, hashFile, fmWrite): + if open(f, hashFile.string, fmWrite): f.writeLine($currentHash) close(f) @@ -630,7 +631,7 @@ proc addExternalFileToCompile*(conf: ConfigRef; c: var Cfile) = c.flags.incl CfileFlag.Cached conf.toCompile.add(c) -proc addExternalFileToCompile*(conf: ConfigRef; filename: string) = +proc addExternalFileToCompile*(conf: ConfigRef; filename: AbsoluteFile) = var c = Cfile(cname: filename, obj: toObjFile(conf, completeCFilePath(conf, filename, false)), flags: {CfileFlag.External}) @@ -650,11 +651,11 @@ proc compileCFile(conf: ConfigRef; list: CFileList, script: var Rope, cmds: var add(script, compileCmd) add(script, "\n") -proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = +proc getLinkCmd(conf: ConfigRef; projectfile: AbsoluteFile, objfiles: string): string = if optGenStaticLib in conf.globalOptions: var libname: string - if conf.outFile.len > 0: - libname = conf.outFile.expandTilde + if not conf.outFile.isEmpty: + libname = conf.outFile.string.expandTilde if not libname.isAbsolute(): libname = getCurrentDir() / libname else: @@ -679,13 +680,13 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = else: exefile = splitFile(projectfile).name & platform.OS[conf.target.targetOS].exeExt builddll = "" - if conf.outFile.len > 0: - exefile = conf.outFile.expandTilde + if not conf.outFile.isEmpty: + exefile = conf.outFile.string.expandTilde if not exefile.isAbsolute(): exefile = getCurrentDir() / exefile if not noAbsolutePaths(conf): if not exefile.isAbsolute(): - exefile = joinPath(splitFile(projectfile).dir, exefile) + exefile = string(splitFile(projectfile).dir / RelativeFile(exefile)) when false: if optCDebug in conf.globalOptions: writeDebugInfo(exefile.changeFileExt("ndb")) @@ -693,7 +694,7 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = # Map files are required by Nintendo Switch compilation. They are a list # of all function calls in the library and where they come from. - let mapfile = quoteShell(getNimcacheDir(conf) / splitFile(projectFile).name & ".map") + let mapfile = quoteShell(getNimcacheDir(conf) / RelativeFile(splitFile(projectFile).name & ".map")) let linkOptions = getLinkOptions(conf) & " " & getConfigVar(conf, conf.cCompiler, ".options.linker") @@ -703,7 +704,7 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = result = quoteShell(result % ["builddll", builddll, "mapfile", mapfile, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, - "exefile", exefile, "nim", getPrefixDir(conf), "lib", conf.libpath]) + "exefile", exefile, "nim", getPrefixDir(conf).string, "lib", conf.libpath.string]) result.add ' ' addf(result, linkTmpl, ["builddll", builddll, "mapfile", mapfile, @@ -761,7 +762,7 @@ proc execCmdsInParallel(conf: ConfigRef; cmds: seq[string]; prettyCb: proc (idx: rawMessage(conf, errGenerated, "execution of an external program failed: '$1'" % cmds.join()) -proc callCCompiler*(conf: ConfigRef; projectfile: string) = +proc callCCompiler*(conf: ConfigRef; projectfile: AbsoluteFile) = var linkCmd: string if conf.globalOptions * {optCompileOnly, optGenScript} == {optCompileOnly}: @@ -787,7 +788,7 @@ proc callCCompiler*(conf: ConfigRef; projectfile: string) = add(objfiles, quoteShell( addFileExt(objFile, CC[conf.cCompiler].objExt))) for x in conf.toCompile: - let objFile = if noAbsolutePaths(conf): x.obj.extractFilename else: x.obj + let objFile = if noAbsolutePaths(conf): x.obj.extractFilename else: x.obj.string add(objfiles, ' ') add(objfiles, quoteShell(objFile)) @@ -804,7 +805,7 @@ proc callCCompiler*(conf: ConfigRef; projectfile: string) = #from json import escapeJson import json -proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = +proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: AbsoluteFile) = template lit(x: untyped) = f.write x template str(x: untyped) = when compiles(escapeJson(x, buf)): @@ -821,7 +822,7 @@ proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = let compileCmd = getCompileCFileCmd(conf, it) if pastStart: lit "],\L" lit "[" - str it.cname + str it.cname.string lit ", " str compileCmd pastStart = true @@ -851,11 +852,10 @@ proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = var buf = newStringOfCap(50) - let file = projectfile.splitFile.name - let jsonFile = toGeneratedFile(conf, file, "json") + let jsonFile = toGeneratedFile(conf, projectfile, "json") var f: File - if open(f, jsonFile, fmWrite): + if open(f, jsonFile.string, fmWrite): lit "{\"compile\":[\L" cfiles(conf, f, buf, conf.toCompile, false) lit "],\L\"link\":[\L" @@ -868,11 +868,10 @@ proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = lit "\L}\L" close(f) -proc runJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = - let file = projectfile.splitFile.name - let jsonFile = toGeneratedFile(conf, file, "json") +proc runJsonBuildInstructions*(conf: ConfigRef; projectfile: AbsoluteFile) = + let jsonFile = toGeneratedFile(conf, projectfile, "json") try: - let data = json.parseFile(jsonFile) + let data = json.parseFile(jsonFile.string) let toCompile = data["compile"] doAssert toCompile.kind == JArray var cmds: TStringSeq = @[] @@ -896,11 +895,11 @@ proc runJsonBuildInstructions*(conf: ConfigRef; projectfile: string) = except: when declared(echo): echo getCurrentException().getStackTrace() - quit "error evaluating JSON file: " & jsonFile + quit "error evaluating JSON file: " & jsonFile.string proc genMappingFiles(conf: ConfigRef; list: CFileList): Rope = for it in list: - addf(result, "--file:r\"$1\"$N", [rope(it.cname)]) + addf(result, "--file:r\"$1\"$N", [rope(it.cname.string)]) proc writeMapping*(conf: ConfigRef; symbolMapping: Rope) = if optGenMapping notin conf.globalOptions: return @@ -914,9 +913,9 @@ proc writeMapping*(conf: ConfigRef; symbolMapping: Rope) = getConfigVar(conf, conf.cCompiler, ".options.linker"))) add(code, "\n[Environment]\nlibpath=") - add(code, strutils.escape(conf.libpath)) + add(code, strutils.escape(conf.libpath.string)) addf(code, "\n[Symbols]$n$1", [symbolMapping]) - let filename = joinPath(conf.projectPath, "mapping.txt") + let filename = conf.projectPath / RelativeFile"mapping.txt" if not writeRope(code, filename): - rawMessage(conf, errGenerated, "could not write to file: " & filename) + rawMessage(conf, errGenerated, "could not write to file: " & filename.string) |