diff options
-rw-r--r-- | changelog.md | 3 | ||||
-rw-r--r-- | compiler/extccomp.nim | 19 | ||||
-rw-r--r-- | compiler/options.nim | 3 | ||||
-rw-r--r-- | compiler/pragmas.nim | 7 | ||||
-rw-r--r-- | compiler/rodimpl.nim | 2 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 5 | ||||
-rw-r--r-- | doc/manual.rst | 21 |
7 files changed, 48 insertions, 12 deletions
diff --git a/changelog.md b/changelog.md index 5b2509663..6320ec158 100644 --- a/changelog.md +++ b/changelog.md @@ -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 diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 5c63f246b..42020822c 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, 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) diff --git a/compiler/options.nim b/compiler/options.nim index 2da73ec85..8cfd2f2fb 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -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 diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index e43004bf8..ad58c0bd8 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -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 diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim index 94fd792bf..188a32dc4 100644 --- a/compiler/rodimpl.nim +++ b/compiler/rodimpl.nim @@ -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": diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index fa18d4f7f..f2946ffa2 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -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] diff --git a/doc/manual.rst b/doc/manual.rst index 82487a385..50d3a9baa 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -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 ------------ |