mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-20 16:01:29 +00:00
extccomp: no globals anymore
This commit is contained in:
@@ -477,7 +477,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
|
||||
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
|
||||
var loopBody = t.sons[1]
|
||||
if loopBody.stmtsContainPragma(wComputedGoto) and
|
||||
hasComputedGoto in CC[cCompiler].props:
|
||||
hasComputedGoto in CC[p.config.cCompiler].props:
|
||||
# for closure support weird loop bodies are generated:
|
||||
if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty:
|
||||
loopBody = loopBody.sons[1]
|
||||
@@ -703,7 +703,7 @@ proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
|
||||
var stmtBlock = lastSon(branch)
|
||||
if stmtBlock.stmtsContainPragma(wLinearScanEnd):
|
||||
result = i
|
||||
elif hasSwitchRange notin CC[cCompiler].props:
|
||||
elif hasSwitchRange notin CC[p.config.cCompiler].props:
|
||||
if branch.kind == nkOfBranch and branchHasTooBigRange(branch):
|
||||
result = i
|
||||
|
||||
@@ -711,7 +711,7 @@ proc genCaseRange(p: BProc, branch: PNode) =
|
||||
var length = branch.len
|
||||
for j in 0 .. length-2:
|
||||
if branch[j].kind == nkRange:
|
||||
if hasSwitchRange in CC[cCompiler].props:
|
||||
if hasSwitchRange in CC[p.config.cCompiler].props:
|
||||
lineF(p, cpsStmts, "case $1 ... $2:$n", [
|
||||
genLiteral(p, branch[j][0]),
|
||||
genLiteral(p, branch[j][1])])
|
||||
@@ -751,7 +751,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
|
||||
hasDefault = true
|
||||
exprBlock(p, branch.lastSon, d)
|
||||
lineF(p, cpsStmts, "break;$n", [])
|
||||
if (hasAssume in CC[cCompiler].props) and not hasDefault:
|
||||
if (hasAssume in CC[p.config.cCompiler].props) and not hasDefault:
|
||||
lineF(p, cpsStmts, "default: __assume(0);$n", [])
|
||||
lineF(p, cpsStmts, "}$n", [])
|
||||
if lend != nil: fixLabel(p, lend)
|
||||
@@ -967,7 +967,7 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
|
||||
initLocExpr(p, it, a)
|
||||
res.add($a.rdLoc)
|
||||
|
||||
if isAsmStmt and hasGnuAsm in CC[cCompiler].props:
|
||||
if isAsmStmt and hasGnuAsm in CC[p.config.cCompiler].props:
|
||||
for x in splitLines(res):
|
||||
var j = 0
|
||||
while x[j] in {' ', '\t'}: inc(j)
|
||||
@@ -993,9 +993,9 @@ proc genAsmStmt(p: BProc, t: PNode) =
|
||||
# work:
|
||||
if p.prc == nil:
|
||||
# top level asm statement?
|
||||
addf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s])
|
||||
addf(p.module.s[cfsProcHeaders], CC[p.config.cCompiler].asmStmtFrmt, [s])
|
||||
else:
|
||||
lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s])
|
||||
lineF(p, cpsStmts, CC[p.config.cCompiler].asmStmtFrmt, [s])
|
||||
|
||||
proc determineSection(n: PNode): TCFileSection =
|
||||
result = cfsProcHeaders
|
||||
|
||||
@@ -471,13 +471,13 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
|
||||
if tfPacked notin rectype.flags:
|
||||
add(unionBody, "struct {")
|
||||
else:
|
||||
if hasAttribute in CC[cCompiler].props:
|
||||
if hasAttribute in CC[m.config.cCompiler].props:
|
||||
add(unionBody, "struct __attribute__((__packed__)){" )
|
||||
else:
|
||||
addf(unionBody, "#pragma pack(push, 1)$nstruct{", [])
|
||||
add(unionBody, a)
|
||||
addf(unionBody, "} $1;$n", [sname])
|
||||
if tfPacked in rectype.flags and hasAttribute notin CC[cCompiler].props:
|
||||
if tfPacked in rectype.flags and hasAttribute notin CC[m.config.cCompiler].props:
|
||||
addf(unionBody, "#pragma pack(pop)$n", [])
|
||||
else:
|
||||
add(unionBody, genRecordFieldsAux(m, k, ae, rectype, check))
|
||||
@@ -526,7 +526,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
|
||||
var hasField = false
|
||||
|
||||
if tfPacked in typ.flags:
|
||||
if hasAttribute in CC[cCompiler].props:
|
||||
if hasAttribute in CC[m.config.cCompiler].props:
|
||||
result = structOrUnion(typ) & " __attribute__((__packed__))"
|
||||
else:
|
||||
result = "#pragma pack(push, 1)" & tnl & structOrUnion(typ)
|
||||
@@ -571,7 +571,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
|
||||
else:
|
||||
add(result, desc)
|
||||
add(result, "};" & tnl)
|
||||
if tfPacked in typ.flags and hasAttribute notin CC[cCompiler].props:
|
||||
if tfPacked in typ.flags and hasAttribute notin CC[m.config.cCompiler].props:
|
||||
result.add "#pragma pack(pop)" & tnl
|
||||
|
||||
proc getTupleDesc(m: BModule, typ: PType, name: Rope,
|
||||
|
||||
@@ -756,10 +756,10 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
|
||||
var generatedProc: Rope
|
||||
if sfNoReturn in prc.flags:
|
||||
if hasDeclspec in extccomp.CC[extccomp.cCompiler].props:
|
||||
if hasDeclspec in extccomp.CC[p.config.cCompiler].props:
|
||||
header = "__declspec(noreturn) " & header
|
||||
if sfPure in prc.flags:
|
||||
if hasDeclspec in extccomp.CC[extccomp.cCompiler].props:
|
||||
if hasDeclspec in extccomp.CC[p.config.cCompiler].props:
|
||||
header = "__declspec(naked) " & header
|
||||
generatedProc = ropecg(p.module, "$N$1 {$n$2$3$4}$N$N",
|
||||
header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
|
||||
@@ -803,13 +803,13 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
||||
elif not containsOrIncl(m.declaredProtos, sym.id):
|
||||
var header = genProcHeader(m, sym)
|
||||
if sfNoReturn in sym.flags and hasDeclspec in extccomp.CC[cCompiler].props:
|
||||
if sfNoReturn in sym.flags and hasDeclspec in extccomp.CC[m.config.cCompiler].props:
|
||||
header = "__declspec(noreturn) " & header
|
||||
if sym.typ.callConv != ccInline and requiresExternC(m, sym):
|
||||
header = "extern \"C\" " & header
|
||||
if sfPure in sym.flags and hasAttribute in CC[cCompiler].props:
|
||||
if sfPure in sym.flags and hasAttribute in CC[m.config.cCompiler].props:
|
||||
header.add(" __attribute__((naked))")
|
||||
if sfNoReturn in sym.flags and hasAttribute in CC[cCompiler].props:
|
||||
if sfNoReturn in sym.flags and hasAttribute in CC[m.config.cCompiler].props:
|
||||
header.add(" __attribute__((noreturn))")
|
||||
add(m.s[cfsProcHeaders], ropecg(m, "$1;$n", header))
|
||||
|
||||
@@ -938,7 +938,7 @@ proc getCopyright(conf: ConfigRef; cfile: Cfile): Rope =
|
||||
[rope(VersionAsString),
|
||||
rope(platform.OS[targetOS].name),
|
||||
rope(platform.CPU[targetCPU].name),
|
||||
rope(extccomp.CC[extccomp.cCompiler].name),
|
||||
rope(extccomp.CC[conf.cCompiler].name),
|
||||
rope(getCompileCFileCmd(conf, cfile))]
|
||||
|
||||
proc getFileHeader(conf: ConfigRef; cfile: Cfile): Rope =
|
||||
|
||||
@@ -565,13 +565,13 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
if pass in {passCmd2, passPP}: extccomp.addLinkOptionCmd(conf, arg)
|
||||
of "cincludes":
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: cIncludes.add processPath(conf, arg, info)
|
||||
if pass in {passCmd2, passPP}: conf.cIncludes.add processPath(conf, arg, info)
|
||||
of "clibdir":
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: cLibs.add processPath(conf, arg, info)
|
||||
if pass in {passCmd2, passPP}: conf.cLibs.add processPath(conf, arg, info)
|
||||
of "clib":
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: cLinkedLibs.add processPath(conf, arg, info)
|
||||
if pass in {passCmd2, passPP}: conf.cLinkedLibs.add processPath(conf, arg, info)
|
||||
of "header":
|
||||
if conf != nil: conf.headerFile = arg
|
||||
incl(conf.globalOptions, optGenIndex)
|
||||
|
||||
@@ -16,12 +16,7 @@ import
|
||||
ropes, os, strutils, osproc, platform, condsyms, options, msgs,
|
||||
configuration, std / sha1, streams
|
||||
|
||||
#from debuginfo import writeDebugInfo
|
||||
|
||||
type
|
||||
TSystemCC* = enum
|
||||
ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc,
|
||||
ccTcc, ccPcc, ccUcc, ccIcl, ccIcc
|
||||
TInfoCCProp* = enum # properties of the C compiler:
|
||||
hasSwitchRange, # CC allows ranges in switch statements (GNU C)
|
||||
hasComputedGoto, # CC has computed goto (GNU C extension)
|
||||
@@ -336,38 +331,9 @@ const
|
||||
|
||||
hExt* = ".h"
|
||||
|
||||
var
|
||||
cCompiler* = ccGcc # the used compiler
|
||||
gMixedMode*: bool # true if some module triggered C++ codegen
|
||||
cIncludes*: seq[string] = @[] # directories to search for included files
|
||||
cLibs*: seq[string] = @[] # directories to search for lib files
|
||||
cLinkedLibs*: seq[string] = @[] # libraries to link
|
||||
|
||||
# implementation
|
||||
|
||||
proc libNameTmpl(): string {.inline.} =
|
||||
result = if targetOS == osWindows: "$1.lib" else: "lib$1.a"
|
||||
|
||||
type
|
||||
CfileFlag* {.pure.} = enum
|
||||
Cached, ## no need to recompile this time
|
||||
External ## file was introduced via .compile pragma
|
||||
|
||||
Cfile* = object
|
||||
cname*, obj*: string
|
||||
flags*: set[CFileFlag]
|
||||
CfileList = seq[Cfile]
|
||||
|
||||
var
|
||||
externalToLink: seq[string] = @[] # files to link in addition to the file
|
||||
# we compiled
|
||||
linkOptionsCmd: string = ""
|
||||
compileOptionsCmd: seq[string] = @[]
|
||||
linkOptions: string = ""
|
||||
compileOptions: string = ""
|
||||
ccompilerpath: string = ""
|
||||
toCompile: CfileList = @[]
|
||||
|
||||
proc nameToCC*(name: string): TSystemCC =
|
||||
## Returns the kind of compiler referred to by `name`, or ccNone
|
||||
## if the name doesn't refer to any known compiler.
|
||||
@@ -402,40 +368,40 @@ proc getConfigVar(conf: ConfigRef; c: TSystemCC, suffix: string): string =
|
||||
result = getConfigVar(conf, CC[c].name & fullSuffix)
|
||||
|
||||
proc setCC*(conf: ConfigRef; ccname: string; info: TLineInfo) =
|
||||
cCompiler = nameToCC(ccname)
|
||||
if cCompiler == ccNone:
|
||||
conf.cCompiler = nameToCC(ccname)
|
||||
if conf.cCompiler == ccNone:
|
||||
localError(conf, info, "unknown C compiler: '$1'" % ccname)
|
||||
compileOptions = getConfigVar(conf, cCompiler, ".options.always")
|
||||
linkOptions = ""
|
||||
ccompilerpath = getConfigVar(conf, cCompiler, ".path")
|
||||
conf.compileOptions = getConfigVar(conf, conf.cCompiler, ".options.always")
|
||||
conf.linkOptions = ""
|
||||
conf.ccompilerpath = getConfigVar(conf, conf.cCompiler, ".path")
|
||||
for i in countup(low(CC), high(CC)): undefSymbol(conf.symbols, CC[i].name)
|
||||
defineSymbol(conf.symbols, CC[cCompiler].name)
|
||||
defineSymbol(conf.symbols, CC[conf.cCompiler].name)
|
||||
|
||||
proc addOpt(dest: var string, src: string) =
|
||||
if len(dest) == 0 or dest[len(dest)-1] != ' ': add(dest, " ")
|
||||
add(dest, src)
|
||||
|
||||
proc addLinkOption*(conf: ConfigRef; option: string) =
|
||||
addOpt(linkOptions, option)
|
||||
addOpt(conf.linkOptions, option)
|
||||
|
||||
proc addCompileOption*(conf: ConfigRef; option: string) =
|
||||
if strutils.find(compileOptions, option, 0) < 0:
|
||||
addOpt(compileOptions, option)
|
||||
if strutils.find(conf.compileOptions, option, 0) < 0:
|
||||
addOpt(conf.compileOptions, option)
|
||||
|
||||
proc addLinkOptionCmd*(conf: ConfigRef; option: string) =
|
||||
addOpt(linkOptionsCmd, option)
|
||||
addOpt(conf.linkOptionsCmd, option)
|
||||
|
||||
proc addCompileOptionCmd*(conf: ConfigRef; option: string) =
|
||||
compileOptionsCmd.add(option)
|
||||
conf.compileOptionsCmd.add(option)
|
||||
|
||||
proc initVars*(conf: ConfigRef) =
|
||||
# we need to define the symbol here, because ``CC`` may have never been set!
|
||||
for i in countup(low(CC), high(CC)): undefSymbol(conf.symbols, CC[i].name)
|
||||
defineSymbol(conf.symbols, CC[cCompiler].name)
|
||||
addCompileOption(conf, getConfigVar(conf, cCompiler, ".options.always"))
|
||||
defineSymbol(conf.symbols, CC[conf.cCompiler].name)
|
||||
addCompileOption(conf, getConfigVar(conf, conf.cCompiler, ".options.always"))
|
||||
#addLinkOption(getConfigVar(cCompiler, ".options.linker"))
|
||||
if len(ccompilerpath) == 0:
|
||||
ccompilerpath = getConfigVar(conf, cCompiler, ".path")
|
||||
if len(conf.ccompilerpath) == 0:
|
||||
conf.ccompilerpath = getConfigVar(conf, conf.cCompiler, ".path")
|
||||
|
||||
proc completeCFilePath*(conf: ConfigRef; cfile: string, createSubDir: bool = true): string =
|
||||
result = completeGeneratedFilePath(conf, cfile, createSubDir)
|
||||
@@ -445,21 +411,21 @@ proc toObjFile*(conf: ConfigRef; filename: string): string =
|
||||
#if filename.endsWith(".cpp"):
|
||||
# result = changeFileExt(filename, "cpp." & CC[cCompiler].objExt)
|
||||
#else:
|
||||
result = changeFileExt(filename, CC[cCompiler].objExt)
|
||||
result = changeFileExt(filename, CC[conf.cCompiler].objExt)
|
||||
|
||||
proc addFileToCompile*(conf: ConfigRef; cf: Cfile) =
|
||||
toCompile.add(cf)
|
||||
conf.toCompile.add(cf)
|
||||
|
||||
proc resetCompilationLists*(conf: ConfigRef) =
|
||||
toCompile.setLen 0
|
||||
conf.toCompile.setLen 0
|
||||
## XXX: we must associate these with their originating module
|
||||
# when the module is loaded/unloaded it adds/removes its items
|
||||
# That's because we still need to hash check the external files
|
||||
# Maybe we can do that in checkDep on the other hand?
|
||||
externalToLink.setLen 0
|
||||
conf.externalToLink.setLen 0
|
||||
|
||||
proc addExternalFileToLink*(conf: ConfigRef; filename: string) =
|
||||
externalToLink.insert(filename, 0)
|
||||
conf.externalToLink.insert(filename, 0)
|
||||
|
||||
proc execWithEcho(conf: ConfigRef; cmd: string, msg = hintExecuting): int =
|
||||
rawMessage(conf, msg, cmd)
|
||||
@@ -499,8 +465,8 @@ proc noAbsolutePaths(conf: ConfigRef): bool {.inline.} =
|
||||
result = conf.globalOptions * {optGenScript, optGenMapping} != {}
|
||||
|
||||
proc cFileSpecificOptions(conf: ConfigRef; cfilename: string): string =
|
||||
result = compileOptions
|
||||
for option in compileOptionsCmd:
|
||||
result = conf.compileOptions
|
||||
for option in conf.compileOptionsCmd:
|
||||
if strutils.find(result, option, 0) < 0:
|
||||
addOpt(result, option)
|
||||
|
||||
@@ -508,15 +474,15 @@ proc cFileSpecificOptions(conf: ConfigRef; cfilename: string): string =
|
||||
if optCDebug in conf.globalOptions:
|
||||
let key = trunk & ".debug"
|
||||
if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key))
|
||||
else: addOpt(result, getDebug(conf, cCompiler))
|
||||
else: addOpt(result, getDebug(conf, conf.cCompiler))
|
||||
if optOptimizeSpeed in conf.options:
|
||||
let key = trunk & ".speed"
|
||||
if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key))
|
||||
else: addOpt(result, getOptSpeed(conf, cCompiler))
|
||||
else: addOpt(result, getOptSpeed(conf, conf.cCompiler))
|
||||
elif optOptimizeSize in conf.options:
|
||||
let key = trunk & ".size"
|
||||
if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key))
|
||||
else: addOpt(result, getOptSize(conf, cCompiler))
|
||||
else: addOpt(result, getOptSize(conf, conf.cCompiler))
|
||||
let key = trunk & ".always"
|
||||
if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key))
|
||||
|
||||
@@ -524,11 +490,11 @@ proc getCompileOptions(conf: ConfigRef): string =
|
||||
result = cFileSpecificOptions(conf, "__dummy__")
|
||||
|
||||
proc getLinkOptions(conf: ConfigRef): string =
|
||||
result = linkOptions & " " & linkOptionsCmd & " "
|
||||
for linkedLib in items(cLinkedLibs):
|
||||
result.add(CC[cCompiler].linkLibCmd % linkedLib.quoteShell)
|
||||
for libDir in items(cLibs):
|
||||
result.add(join([CC[cCompiler].linkDirCmd, libDir.quoteShell]))
|
||||
result = conf.linkOptions & " " & conf.linkOptionsCmd & " "
|
||||
for linkedLib in items(conf.cLinkedLibs):
|
||||
result.add(CC[conf.cCompiler].linkLibCmd % linkedLib.quoteShell)
|
||||
for libDir in items(conf.cLibs):
|
||||
result.add(join([CC[conf.cCompiler].linkDirCmd, libDir.quoteShell]))
|
||||
|
||||
proc needsExeExt(conf: ConfigRef): bool {.inline.} =
|
||||
result = (optGenScript in conf.globalOptions and targetOS == osWindows) or
|
||||
@@ -546,11 +512,11 @@ 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 gMixedMode and conf.cmd != cmdCompileToCpp: CC[compiler].cppCompiler
|
||||
elif optMixedMode in conf.globalOptions and conf.cmd != cmdCompileToCpp: CC[compiler].cppCompiler
|
||||
else: getCompilerExe(conf, compiler, "")
|
||||
|
||||
proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string =
|
||||
var c = cCompiler
|
||||
var c = conf.cCompiler
|
||||
var options = cFileSpecificOptions(conf, cfile.cname)
|
||||
var exe = getConfigVar(conf, c, ".exe")
|
||||
if exe.len == 0: exe = getCompilerExe(conf, c, cfile.cname)
|
||||
@@ -565,10 +531,10 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string =
|
||||
# compute include paths:
|
||||
includeCmd = CC[c].includeCmd & quoteShell(conf.libpath)
|
||||
|
||||
for includeDir in items(cIncludes):
|
||||
for includeDir in items(conf.cIncludes):
|
||||
includeCmd.add(join([CC[c].includeCmd, includeDir.quoteShell]))
|
||||
|
||||
compilePattern = joinPath(ccompilerpath, exe)
|
||||
compilePattern = joinPath(conf.ccompilerpath, exe)
|
||||
else:
|
||||
includeCmd = ""
|
||||
compilePattern = getCompilerExe(conf, c, cfile.cname)
|
||||
@@ -606,7 +572,7 @@ proc footprint(conf: ConfigRef; cfile: Cfile): SecureHash =
|
||||
$secureHashFile(cfile.cname) &
|
||||
platform.OS[targetOS].name &
|
||||
platform.CPU[targetCPU].name &
|
||||
extccomp.CC[extccomp.cCompiler].name &
|
||||
extccomp.CC[conf.cCompiler].name &
|
||||
getCompileCFileCmd(conf, cfile))
|
||||
|
||||
proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool =
|
||||
@@ -630,7 +596,7 @@ proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool =
|
||||
proc addExternalFileToCompile*(conf: ConfigRef; c: var Cfile) =
|
||||
if optForceFullMake notin conf.globalOptions and not externalFileChanged(conf, c):
|
||||
c.flags.incl CfileFlag.Cached
|
||||
toCompile.add(c)
|
||||
conf.toCompile.add(c)
|
||||
|
||||
proc addExternalFileToCompile*(conf: ConfigRef; filename: string) =
|
||||
var c = Cfile(cname: filename,
|
||||
@@ -661,21 +627,21 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string =
|
||||
libname = getCurrentDir() / libname
|
||||
else:
|
||||
libname = (libNameTmpl() % splitFile(conf.projectName).name)
|
||||
result = CC[cCompiler].buildLib % ["libfile", libname,
|
||||
result = CC[conf.cCompiler].buildLib % ["libfile", libname,
|
||||
"objfiles", objfiles]
|
||||
else:
|
||||
var linkerExe = getConfigVar(conf, cCompiler, ".linkerexe")
|
||||
if len(linkerExe) == 0: linkerExe = getLinkerExe(conf, cCompiler)
|
||||
var linkerExe = getConfigVar(conf, conf.cCompiler, ".linkerexe")
|
||||
if len(linkerExe) == 0: linkerExe = getLinkerExe(conf, conf.cCompiler)
|
||||
# bug #6452: We must not use ``quoteShell`` here for ``linkerExe``
|
||||
if needsExeExt(conf): linkerExe = addFileExt(linkerExe, "exe")
|
||||
if noAbsolutePaths(conf): result = linkerExe
|
||||
else: result = joinPath(ccompilerpath, linkerExe)
|
||||
let buildgui = if optGenGuiApp in conf.globalOptions: CC[cCompiler].buildGui
|
||||
else: result = joinPath(conf.cCompilerpath, linkerExe)
|
||||
let buildgui = if optGenGuiApp in conf.globalOptions: CC[conf.cCompiler].buildGui
|
||||
else: ""
|
||||
var exefile, builddll: string
|
||||
if optGenDynLib in conf.globalOptions:
|
||||
exefile = platform.OS[targetOS].dllFrmt % splitFile(projectfile).name
|
||||
builddll = CC[cCompiler].buildDll
|
||||
builddll = CC[conf.cCompiler].buildDll
|
||||
else:
|
||||
exefile = splitFile(projectfile).name & platform.OS[targetOS].exeExt
|
||||
builddll = ""
|
||||
@@ -691,10 +657,10 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string =
|
||||
writeDebugInfo(exefile.changeFileExt("ndb"))
|
||||
exefile = quoteShell(exefile)
|
||||
let linkOptions = getLinkOptions(conf) & " " &
|
||||
getConfigVar(conf, cCompiler, ".options.linker")
|
||||
var linkTmpl = getConfigVar(conf, cCompiler, ".linkTmpl")
|
||||
getConfigVar(conf, conf.cCompiler, ".options.linker")
|
||||
var linkTmpl = getConfigVar(conf, conf.cCompiler, ".linkTmpl")
|
||||
if linkTmpl.len == 0:
|
||||
linkTmpl = CC[cCompiler].linkTmpl
|
||||
linkTmpl = CC[conf.cCompiler].linkTmpl
|
||||
result = quoteShell(result % ["builddll", builddll,
|
||||
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
|
||||
"exefile", exefile, "nim", getPrefixDir(conf), "lib", conf.libpath])
|
||||
@@ -766,18 +732,18 @@ proc callCCompiler*(conf: ConfigRef; projectfile: string) =
|
||||
var prettyCmds: TStringSeq = @[]
|
||||
let prettyCb = proc (idx: int) =
|
||||
echo prettyCmds[idx]
|
||||
compileCFile(conf, toCompile, script, cmds, prettyCmds)
|
||||
compileCFile(conf, conf.toCompile, script, cmds, prettyCmds)
|
||||
if optCompileOnly notin conf.globalOptions:
|
||||
execCmdsInParallel(conf, cmds, prettyCb)
|
||||
if optNoLinking notin conf.globalOptions:
|
||||
# call the linker:
|
||||
var objfiles = ""
|
||||
for it in externalToLink:
|
||||
for it in conf.externalToLink:
|
||||
let objFile = if noAbsolutePaths(conf): it.extractFilename else: it
|
||||
add(objfiles, ' ')
|
||||
add(objfiles, quoteShell(
|
||||
addFileExt(objFile, CC[cCompiler].objExt)))
|
||||
for x in toCompile:
|
||||
addFileExt(objFile, CC[conf.cCompiler].objExt)))
|
||||
for x in conf.toCompile:
|
||||
let objFile = if noAbsolutePaths(conf): x.obj.extractFilename else: x.obj
|
||||
add(objfiles, ' ')
|
||||
add(objfiles, quoteShell(objFile))
|
||||
@@ -824,7 +790,7 @@ proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) =
|
||||
for it in llist:
|
||||
let objfile = if noAbsolutePaths(conf): it.extractFilename
|
||||
else: it
|
||||
let objstr = addFileExt(objfile, CC[cCompiler].objExt)
|
||||
let objstr = addFileExt(objfile, CC[conf.cCompiler].objExt)
|
||||
add(objfiles, ' ')
|
||||
add(objfiles, objstr)
|
||||
if pastStart: lit ",\L"
|
||||
@@ -848,11 +814,11 @@ proc writeJsonBuildInstructions*(conf: ConfigRef; projectfile: string) =
|
||||
var f: File
|
||||
if open(f, jsonFile, fmWrite):
|
||||
lit "{\"compile\":[\L"
|
||||
cfiles(conf, f, buf, toCompile, false)
|
||||
cfiles(conf, f, buf, conf.toCompile, false)
|
||||
lit "],\L\"link\":[\L"
|
||||
var objfiles = ""
|
||||
# XXX add every file here that is to link
|
||||
linkfiles(conf, f, buf, objfiles, toCompile, externalToLink)
|
||||
linkfiles(conf, f, buf, objfiles, conf.toCompile, conf.externalToLink)
|
||||
|
||||
lit "],\L\"linkcmd\": "
|
||||
str getLinkCmd(conf, projectfile, objfiles)
|
||||
@@ -894,13 +860,13 @@ proc genMappingFiles(conf: ConfigRef; list: CFileList): Rope =
|
||||
proc writeMapping*(conf: ConfigRef; symbolMapping: Rope) =
|
||||
if optGenMapping notin conf.globalOptions: return
|
||||
var code = rope("[C_Files]\n")
|
||||
add(code, genMappingFiles(conf, toCompile))
|
||||
add(code, genMappingFiles(conf, conf.toCompile))
|
||||
add(code, "\n[C_Compiler]\nFlags=")
|
||||
add(code, strutils.escape(getCompileOptions(conf)))
|
||||
|
||||
add(code, "\n[Linker]\nFlags=")
|
||||
add(code, strutils.escape(getLinkOptions(conf) & " " &
|
||||
getConfigVar(conf, cCompiler, ".options.linker")))
|
||||
getConfigVar(conf, conf.cCompiler, ".options.linker")))
|
||||
|
||||
add(code, "\n[Environment]\nlibpath=")
|
||||
add(code, strutils.escape(conf.libpath))
|
||||
|
||||
@@ -73,6 +73,7 @@ type # please make sure we have under 32 options
|
||||
optNoCppExceptions # use C exception handling even with CPP
|
||||
optExcessiveStackTrace # fully qualified module filenames
|
||||
optWholeProject # for 'doc2': output any dependency
|
||||
optMixedMode # true if some module triggered C++ codegen
|
||||
optListFullPaths
|
||||
optNoNimblePath
|
||||
optDynlibOverrideAll
|
||||
@@ -121,6 +122,19 @@ type
|
||||
SymbolFilesOption* = enum
|
||||
disabledSf, enabledSf, writeOnlySf, readOnlySf, v2Sf
|
||||
|
||||
TSystemCC* = enum
|
||||
ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc,
|
||||
ccTcc, ccPcc, ccUcc, ccIcl, ccIcc
|
||||
|
||||
CfileFlag* {.pure.} = enum
|
||||
Cached, ## no need to recompile this time
|
||||
External ## file was introduced via .compile pragma
|
||||
|
||||
Cfile* = object
|
||||
cname*, obj*: string
|
||||
flags*: set[CFileFlag]
|
||||
CfileList* = seq[Cfile]
|
||||
|
||||
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
||||
linesCompiled*: int # all lines that have been compiled
|
||||
options*: TOptions
|
||||
@@ -142,6 +156,7 @@ type
|
||||
helpWritten*: bool
|
||||
ideCmd*: IdeCmd
|
||||
oldNewlines*: bool
|
||||
cCompiler*: TSystemCC
|
||||
enableNotes*: TNoteKinds
|
||||
disableNotes*: TNoteKinds
|
||||
foreignPackageNotes*: TNoteKinds
|
||||
@@ -173,6 +188,20 @@ type
|
||||
docSeeSrcUrl*: string # if empty, no seeSrc will be generated. \
|
||||
# The string uses the formatting variables `path` and `line`.
|
||||
|
||||
# the used compiler
|
||||
cIncludes*: seq[string] # directories to search for included files
|
||||
cLibs*: seq[string] # directories to search for lib files
|
||||
cLinkedLibs*: seq[string] # libraries to link
|
||||
|
||||
externalToLink*: seq[string] # files to link in addition to the file
|
||||
# we compiled
|
||||
linkOptionsCmd*: string
|
||||
compileOptionsCmd*: seq[string]
|
||||
linkOptions*: string
|
||||
compileOptions*: string
|
||||
ccompilerpath*: string
|
||||
toCompile*: CfileList
|
||||
|
||||
const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel}
|
||||
|
||||
const
|
||||
@@ -195,6 +224,7 @@ template newPackageCache*(): untyped =
|
||||
proc newConfigRef*(): ConfigRef =
|
||||
result = ConfigRef(
|
||||
selectedGC: gcRefc,
|
||||
cCompiler: ccGcc,
|
||||
verbosity: 1,
|
||||
options: DefaultOptions,
|
||||
globalOptions: DefaultGlobalOptions,
|
||||
@@ -221,7 +251,18 @@ proc newConfigRef*(): ConfigRef =
|
||||
keepComments: true, # whether the parser needs to keep comments
|
||||
implicitImports: @[], # modules that are to be implicitly imported
|
||||
implicitIncludes: @[], # modules that are to be implicitly included
|
||||
docSeeSrcUrl: ""
|
||||
docSeeSrcUrl: "",
|
||||
cIncludes: @[], # directories to search for included files
|
||||
cLibs: @[], # directories to search for lib files
|
||||
cLinkedLibs: @[], # libraries to link
|
||||
|
||||
externalToLink: @[],
|
||||
linkOptionsCmd: "",
|
||||
compileOptionsCmd: @[],
|
||||
linkOptions: "",
|
||||
compileOptions: "",
|
||||
ccompilerpath: "",
|
||||
toCompile: @[]
|
||||
)
|
||||
# enable colors by default on terminals
|
||||
if terminal.isatty(stderr):
|
||||
|
||||
@@ -143,7 +143,7 @@ proc processImportCpp(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
if c.config.cmd == cmdCompileToC:
|
||||
let m = s.getModule()
|
||||
incl(m.flags, sfCompileToCpp)
|
||||
extccomp.gMixedMode = true
|
||||
incl c.config.globalOptions, optMixedMode
|
||||
|
||||
proc processImportObjC(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
setExternName(c, s, extname, info)
|
||||
@@ -444,7 +444,7 @@ proc processCompile(c: PContext, n: PNode) =
|
||||
extccomp.addExternalFileToCompile(c.config, found)
|
||||
|
||||
proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
|
||||
let found = relativeFile(c, n, CC[cCompiler].objExt)
|
||||
let found = relativeFile(c, n, CC[c.config.cCompiler].objExt)
|
||||
case feature
|
||||
of linkNormal: extccomp.addExternalFileToLink(c.config, found)
|
||||
of linkSys:
|
||||
|
||||
Reference in New Issue
Block a user