summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/extccomp.nim4
-rw-r--r--compiler/options.nim1
-rw-r--r--compiler/pragmas.nim30
-rw-r--r--compiler/rodimpl.nim5
-rw-r--r--doc/manual.rst8
-rw-r--r--tests/pragmas/cfunction.c4
-rw-r--r--tests/pragmas/tcompile_pragma.nim9
7 files changed, 49 insertions, 12 deletions
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 79b4ba637..11b001f9d 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -554,6 +554,10 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
       ospNeedsPIC in platform.OS[conf.target.targetOS].props:
     options.add(' ' & CC[c].pic)
 
+  if cfile.customArgs != "":
+    options.add ' '
+    options.add cfile.customArgs
+
   var compilePattern: string
   # compute include paths:
   var includeCmd = CC[c].includeCmd & quoteShell(conf.libpath)
diff --git a/compiler/options.nim b/compiler/options.nim
index 40d86a01d..6054eb3a5 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -198,6 +198,7 @@ type
     nimname*: string
     cname*, obj*: AbsoluteFile
     flags*: set[CfileFlag]
+    customArgs*: string
   CfileList* = seq[Cfile]
 
   Suggest* = ref object
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index fe8cd3cfe..4d5240e3c 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -93,11 +93,10 @@ proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode =
 proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords;
             isStatement: bool = false)
 
-proc recordPragma(c: PContext; n: PNode; key, val: string; val2 = "") =
+proc recordPragma(c: PContext; n: PNode; args: varargs[string]) =
   var recorded = newNodeI(nkCommentStmt, n.info)
-  recorded.add newStrNode(key, n.info)
-  recorded.add newStrNode(val, n.info)
-  if val2.len > 0: recorded.add newStrNode(val2, n.info)
+  for i in 0..args.high:
+    recorded.add newStrNode(args[i], n.info)
   c.graph.recordStmt(c.graph, c.module, recorded)
 
 const
@@ -491,11 +490,12 @@ proc relativeFile(c: PContext; n: PNode; ext=""): AbsoluteFile =
       if result.isEmpty: result = AbsoluteFile s
 
 proc processCompile(c: PContext, n: PNode) =
-  proc docompile(c: PContext; it: PNode; src, dest: AbsoluteFile) =
+  proc docompile(c: PContext; it: PNode; src, dest: AbsoluteFile; customArgs: string) =
     var cf = Cfile(nimname: splitFile(src).name,
-                   cname: src, obj: dest, flags: {CfileFlag.External})
+                   cname: src, obj: dest, flags: {CfileFlag.External},
+                   customArgs: customArgs)
     extccomp.addExternalFileToCompile(c.config, cf)
-    recordPragma(c, it, "compile", src.string, dest.string)
+    recordPragma(c, it, "compile", src.string, dest.string, customArgs)
 
   proc getStrLit(c: PContext, n: PNode; i: int): string =
     n[i] = c.semConstExpr(c, n[i])
@@ -513,9 +513,19 @@ proc processCompile(c: PContext, n: PNode) =
     var found = parentDir(toFullPath(c.config, n.info)) / s
     for f in os.walkFiles(found):
       let obj = completeCfilePath(c.config, AbsoluteFile(dest % extractFilename(f)))
-      docompile(c, it, AbsoluteFile f, obj)
+      docompile(c, it, AbsoluteFile f, obj, "")
   else:
-    let s = expectStrLit(c, n)
+    var s = ""
+    var customArgs = ""
+    if n.kind in nkCallKinds:
+      s = getStrLit(c, n, 1)
+      if n.len <= 3:
+        customArgs = getStrLit(c, n, 2)
+      else:
+        localError(c.config, n.info, "'.compile' pragma takes up 2 arguments")
+    else:
+      s = expectStrLit(c, n)
+
     var found = AbsoluteFile(parentDir(toFullPath(c.config, n.info)) / s)
     if not fileExists(found):
       if isAbsolute(s): found = AbsoluteFile s
@@ -523,7 +533,7 @@ proc processCompile(c: PContext, n: PNode) =
         found = findFile(c.config, s)
         if found.isEmpty: found = AbsoluteFile s
     let obj = toObjFile(c.config, completeCfilePath(c.config, found, false))
-    docompile(c, it, found, obj)
+    docompile(c, it, found, obj, customArgs)
 
 proc processLink(c: PContext, n: PNode) =
   let found = relativeFile(c, n, CC[c.config.cCompiler].objExt)
diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim
index 52b4d1f85..e50ab66de 100644
--- a/compiler/rodimpl.nim
+++ b/compiler/rodimpl.nim
@@ -838,11 +838,12 @@ proc replay(g: ModuleGraph; module: PSym; n: PNode) =
       of "warning": message(g.config, n.info, warnUser, n[1].strVal)
       of "error": localError(g.config, n.info, errUser, n[1].strVal)
       of "compile":
-        internalAssert g.config, n.len == 3 and n[2].kind == nkStrLit
+        internalAssert g.config, n.len == 4 and n[2].kind == nkStrLit
         let cname = AbsoluteFile n[1].strVal
         var cf = Cfile(nimname: splitFile(cname).name, cname: cname,
                        obj: AbsoluteFile n[2].strVal,
-                       flags: {CfileFlag.External})
+                       flags: {CfileFlag.External},
+                       customArgs: n[3].strVal)
         extccomp.addExternalFileToCompile(g.config, cf)
       of "link":
         extccomp.addExternalFileToLink(g.config, AbsoluteFile n[1].strVal)
diff --git a/doc/manual.rst b/doc/manual.rst
index 494a009cb..7258e7775 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -6622,6 +6622,14 @@ with the project:
 has changed. One can use the ``-f`` command line option to force recompilation
 of the file.
 
+Since 1.4 the `compile` pragma is also available with this syntax:
+
+.. code-block:: Nim
+  {.compile("myfile.cpp", "--custom flags here").}
+
+As can be seen in the example, this new variant allows for custom flags
+that are passed to the C compiler when the file is recompiled.
+
 
 Link pragma
 -----------
diff --git a/tests/pragmas/cfunction.c b/tests/pragmas/cfunction.c
new file mode 100644
index 000000000..bf49d6a29
--- /dev/null
+++ b/tests/pragmas/cfunction.c
@@ -0,0 +1,4 @@
+
+int cfunction(void) {
+  return NUMBER_HERE;
+}
diff --git a/tests/pragmas/tcompile_pragma.nim b/tests/pragmas/tcompile_pragma.nim
new file mode 100644
index 000000000..4e09a7501
--- /dev/null
+++ b/tests/pragmas/tcompile_pragma.nim
@@ -0,0 +1,9 @@
+discard """
+  output: '''34'''
+"""
+
+{.compile("cfunction.c", "-DNUMBER_HERE=34").}
+
+proc cfunction(): cint {.importc.}
+
+echo cfunction()