implemented a new localPassc pragma (#12706)

This commit is contained in:
Andreas Rumpf
2019-11-22 14:20:15 +01:00
committed by GitHub
parent c0eeea4f3c
commit 64e8f050e1
7 changed files with 48 additions and 12 deletions

View File

@@ -79,6 +79,9 @@
generated JavaScript.
- The Nim compiler now supports the ``--asm`` command option for easier
inspection of the produced assembler code.
- The Nim compiler now supports a new pragma called ``.localPassc`` to
pass specific compiler options to the C(++) backend for the C(++) file
that was produced from the current Nim module.
## Bugfixes

View File

@@ -14,7 +14,7 @@
import
ropes, os, strutils, osproc, platform, condsyms, options, msgs,
lineinfos, std / sha1, streams, pathutils, sequtils, times
lineinfos, std / sha1, streams, pathutils, sequtils, times, strtabs
type
TInfoCCProp* = enum # properties of the C compiler:
@@ -471,6 +471,13 @@ proc toObjFile*(conf: ConfigRef; filename: AbsoluteFile): AbsoluteFile =
proc addFileToCompile*(conf: ConfigRef; cf: Cfile) =
conf.toCompile.add(cf)
proc addLocalCompileOption*(conf: ConfigRef; option: string; nimfile: AbsoluteFile) =
let key = completeCfilePath(conf, withPackageName(conf, nimfile)).string
var value = conf.cfileSpecificOptions.getOrDefault(key)
if strutils.find(value, option, 0) < 0:
addOpt(value, option)
conf.cfileSpecificOptions[key] = value
proc resetCompilationLists*(conf: ConfigRef) =
conf.toCompile.setLen 0
## XXX: we must associate these with their originating module
@@ -523,8 +530,10 @@ proc noAbsolutePaths(conf: ConfigRef): bool {.inline.} =
# `optGenMapping` is included here for niminst.
result = conf.globalOptions * {optGenScript, optGenMapping} != {}
proc cFileSpecificOptions(conf: ConfigRef; nimname: string): string =
proc cFileSpecificOptions(conf: ConfigRef; nimname, fullNimFile: string): string =
result = conf.compileOptions
addOpt(result, conf.cfileSpecificOptions.getOrDefault(fullNimFile))
for option in conf.compileOptionsCmd:
if strutils.find(result, option, 0) < 0:
addOpt(result, option)
@@ -545,7 +554,7 @@ proc cFileSpecificOptions(conf: ConfigRef; nimname: string): string =
if existsConfigVar(conf, key): addOpt(result, getConfigVar(conf, key))
proc getCompileOptions(conf: ConfigRef): string =
result = cFileSpecificOptions(conf, "__dummy__")
result = cFileSpecificOptions(conf, "__dummy__", "__dummy__")
proc vccplatform(conf: ConfigRef): string =
# VCC specific but preferable over the config hacks people
@@ -589,7 +598,9 @@ proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string =
proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
isMainFile = false; produceOutput = false): string =
var c = conf.cCompiler
var options = cFileSpecificOptions(conf, cfile.nimname)
# We produce files like module.nim.cpp, so the absolute Nim filename is not
# cfile.name but `cfile.cname.changeFileExt("")`:
var options = cFileSpecificOptions(conf, cfile.nimname, cfile.cname.changeFileExt("").string)
var exe = getConfigVar(conf, c, ".exe")
if exe.len == 0: exe = getCompilerExe(conf, c, cfile.cname)

View File

@@ -239,7 +239,7 @@ type
outFile*: RelativeFile
outDir*: AbsoluteDir
prefixDir*, libpath*, nimcacheDir*: AbsoluteDir
dllOverrides, moduleOverrides*: StringTableRef
dllOverrides, moduleOverrides*, cfileSpecificOptions*: StringTableRef
projectName*: string # holds a name like 'nim'
projectPath*: AbsoluteDir # holds a path like /home/alice/projects/nim/compiler/
projectFull*: AbsoluteFile # projectPath/projectName
@@ -347,6 +347,7 @@ proc newConfigRef*(): ConfigRef =
libpath: AbsoluteDir"", nimcacheDir: AbsoluteDir"",
dllOverrides: newStringTable(modeCaseInsensitive),
moduleOverrides: newStringTable(modeStyleInsensitive),
cfileSpecificOptions: newStringTable(modeCaseSensitive),
projectName: "", # holds a name like 'nim'
projectPath: AbsoluteDir"", # holds a path like /home/alice/projects/nim/compiler/
projectFull: AbsoluteFile"", # projectPath/projectName

View File

@@ -46,7 +46,7 @@ const
wWarnings, wHints,
wLineDir, wStackTrace, wLineTrace, wOptimization, wHint, wWarning, wError,
wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop,
wPassl, wPassc,
wPassl, wPassc, wLocalPassc,
wDeadCodeElimUnused, # deprecated, always on
wDeprecated,
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
@@ -998,6 +998,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
let s = expectStrLit(c, it)
extccomp.addCompileOption(c.config, s)
recordPragma(c, it, "passc", s)
of wLocalPassc:
assert sym != nil and sym.kind == skModule
let s = expectStrLit(c, it)
extccomp.addLocalCompileOption(c.config, s, toFullPathConsiderDirty(c.config, sym.info.fileIndex))
recordPragma(c, it, "localpassl", s)
of wPush:
processPush(c, n, i + 1)
result = true

View File

@@ -851,6 +851,8 @@ proc replay(g: ModuleGraph; module: PSym; n: PNode) =
extccomp.addLinkOption(g.config, n[1].strVal)
of "passc":
extccomp.addCompileOption(g.config, n[1].strVal)
of "localpassc":
extccomp.addLocalCompileOption(g.config, n[1].strVal, toFullPathConsiderDirty(g.config, module.info.fileIndex))
of "cppdefine":
options.cppDefine(g.config, n[1].strVal)
of "inc":

View File

@@ -58,7 +58,7 @@ type
wSafecode, wPackage, wNoForward, wReorder, wNoRewrite, wNoDestroy,
wPragma,
wCompileTime, wNoInit,
wPassc, wPassl, wBorrow, wDiscardable,
wPassc, wPassl, wLocalPassc, wBorrow, wDiscardable,
wFieldChecks,
wSubsChar, wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto,
wInjectStmt, wExperimental,
@@ -146,7 +146,7 @@ const
"safecode", "package", "noforward", "reorder", "norewrite", "nodestroy",
"pragma",
"compiletime", "noinit",
"passc", "passl", "borrow", "discardable", "fieldchecks",
"passc", "passl", "localpassc", "borrow", "discardable", "fieldchecks",
"subschar", "acyclic", "shallow", "unroll", "linearscanend",
"computedgoto", "injectstmt", "experimental",
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
@@ -209,4 +209,5 @@ proc canonPragmaSpelling*(w: TSpecialWord): string =
of wImplicitStatic: "implicitStatic"
of wCodegenDecl: "codegenDecl"
of wLiftLocals: "liftLocals"
of wLocalPassc: "localPassc"
else: specialWords[w]

View File

@@ -6560,18 +6560,31 @@ The ``link`` pragma can be used to link an additional file with the project:
PassC pragma
------------
The ``passC`` pragma can be used to pass additional parameters to the C
compiler like you would using the commandline switch ``--passC``:
The ``passc`` pragma can be used to pass additional parameters to the C
compiler like you would using the commandline switch ``--passc``:
.. code-block:: Nim
{.passC: "-Wall -Werror".}
{.passc: "-Wall -Werror".}
Note that you can use ``gorge`` from the `system module <system.html>`_ to
embed parameters from an external command that will be executed
during semantic analysis:
.. code-block:: Nim
{.passC: gorge("pkg-config --cflags sdl").}
{.passc: gorge("pkg-config --cflags sdl").}
LocalPassc pragma
-----------------
The ``localPassc`` pragma can be used to pass additional parameters to the C
compiler, but only for the C/C++ file that is produced from the Nim module
the pragma resides in:
.. code-block:: Nim
# Module A.nim
# Produces: A.nim.cpp
{.localPassc: "-Wall -Werror".} # Passed when compiling A.nim.cpp
PassL pragma
------------