summary refs log tree commit diff stats
path: root/compiler/extccomp.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2016-12-14 01:31:02 +0100
committerAraq <rumpf_a@web.de>2016-12-14 01:31:02 +0100
commit843ae830d3adb8024047f70c0a8757f26556dab7 (patch)
treebcce2c3bd69b65ad07ac4bebc27ae44d1363b0a5 /compiler/extccomp.nim
parent414c2decbecd5dbaf96ddb28132bddbc7d55a2db (diff)
parentaedafb99787d3613c6776bea625d9a43b2b7a8ea (diff)
downloadNim-843ae830d3adb8024047f70c0a8757f26556dab7.tar.gz
Merge branch 'devel' into sighashes
Diffstat (limited to 'compiler/extccomp.nim')
-rw-r--r--compiler/extccomp.nim144
1 files changed, 102 insertions, 42 deletions
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 7707cd31d..1acc98836 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -657,14 +657,57 @@ proc compileCFile(list: TLinkedList, script: var Rope, cmds: var TStringSeq,
       add(script, tnl)
     it = PStrEntry(it.next)
 
+proc getLinkCmd(projectfile, objfiles: string): string =
+  if optGenStaticLib in gGlobalOptions:
+    let name = splitFile(gProjectName).name
+    result = CC[cCompiler].buildLib % ["libfile", (libNameTmpl() % name),
+                                       "objfiles", objfiles]
+  else:
+    var linkerExe = getConfigVar(cCompiler, ".linkerexe")
+    if len(linkerExe) == 0: linkerExe = cCompiler.getLinkerExe
+    if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
+    if noAbsolutePaths(): result = quoteShell(linkerExe)
+    else: result = quoteShell(joinPath(ccompilerpath, linkerExe))
+    let buildgui = if optGenGuiApp in gGlobalOptions: CC[cCompiler].buildGui
+                   else: ""
+    var exefile, builddll: string
+    if optGenDynLib in gGlobalOptions:
+      exefile = platform.OS[targetOS].dllFrmt % splitFile(projectfile).name
+      builddll = CC[cCompiler].buildDll
+    else:
+      exefile = splitFile(projectfile).name & platform.OS[targetOS].exeExt
+      builddll = ""
+    if options.outFile.len > 0:
+      exefile = options.outFile.expandTilde
+      if not exefile.isAbsolute():
+        exefile = getCurrentDir() / exefile
+    if not noAbsolutePaths():
+      if not exefile.isAbsolute():
+        exefile = joinPath(splitFile(projectfile).dir, exefile)
+    when false:
+      if optCDebug in gGlobalOptions:
+        writeDebugInfo(exefile.changeFileExt("ndb"))
+    exefile = quoteShell(exefile)
+    let linkOptions = getLinkOptions() & " " &
+                      getConfigVar(cCompiler, ".options.linker")
+    result = quoteShell(result % ["builddll", builddll,
+        "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
+        "exefile", exefile, "nim", getPrefixDir(), "lib", libpath])
+    result.add ' '
+    addf(result, CC[cCompiler].linkTmpl, ["builddll", builddll,
+        "buildgui", buildgui, "options", linkOptions,
+        "objfiles", objfiles, "exefile", exefile,
+        "nim", quoteShell(getPrefixDir()),
+        "lib", quoteShell(libpath)])
+
 proc callCCompiler*(projectfile: string) =
   var
-    linkCmd, buildgui, builddll: string
+    linkCmd: string
   if gGlobalOptions * {optCompileOnly, optGenScript} == {optCompileOnly}:
     return # speed up that call if only compiling and no script shall be
            # generated
   fileCounter = 0
-  var c = cCompiler
+  #var c = cCompiler
   var script: Rope = nil
   var cmds: TStringSeq = @[]
   var prettyCmds: TStringSeq = @[]
@@ -708,46 +751,7 @@ proc callCCompiler*(projectfile: string) =
           addFileExt(objFile, CC[cCompiler].objExt)))
       it = PStrEntry(it.next)
 
-    if optGenStaticLib in gGlobalOptions:
-      let name = splitFile(gProjectName).name
-      linkCmd = CC[c].buildLib % ["libfile", (libNameTmpl() % name),
-                                  "objfiles", objfiles]
-    else:
-      var linkerExe = getConfigVar(c, ".linkerexe")
-      if len(linkerExe) == 0: linkerExe = c.getLinkerExe
-      if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
-      if noAbsolutePaths(): linkCmd = quoteShell(linkerExe)
-      else: linkCmd = quoteShell(joinPath(ccompilerpath, linkerExe))
-      if optGenGuiApp in gGlobalOptions: buildgui = CC[c].buildGui
-      else: buildgui = ""
-      var exefile: string
-      if optGenDynLib in gGlobalOptions:
-        exefile = platform.OS[targetOS].dllFrmt % splitFile(projectfile).name
-        builddll = CC[c].buildDll
-      else:
-        exefile = splitFile(projectfile).name & platform.OS[targetOS].exeExt
-        builddll = ""
-      if options.outFile.len > 0:
-        exefile = options.outFile.expandTilde
-        if not exefile.isAbsolute():
-          exefile = getCurrentDir() / exefile
-      if not noAbsolutePaths():
-        if not exefile.isAbsolute():
-          exefile = joinPath(splitFile(projectfile).dir, exefile)
-      #if optCDebug in gGlobalOptions:
-      #  writeDebugInfo(exefile.changeFileExt("ndb"))
-      exefile = quoteShell(exefile)
-      let linkOptions = getLinkOptions() & " " &
-                        getConfigVar(cCompiler, ".options.linker")
-      linkCmd = quoteShell(linkCmd % ["builddll", builddll,
-          "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
-          "exefile", exefile, "nim", getPrefixDir(), "lib", libpath])
-      linkCmd.add ' '
-      addf(linkCmd, CC[c].linkTmpl, ["builddll", builddll,
-          "buildgui", buildgui, "options", linkOptions,
-          "objfiles", objfiles, "exefile", exefile,
-          "nim", quoteShell(getPrefixDir()),
-          "lib", quoteShell(libpath)])
+    linkCmd = getLinkCmd(projectfile, objfiles)
     if optCompileOnly notin gGlobalOptions:
       execExternalProgram(linkCmd,
         if optListCmd in gGlobalOptions or gVerbosity > 1: hintExecuting else: hintLinking)
@@ -758,6 +762,62 @@ proc callCCompiler*(projectfile: string) =
     add(script, tnl)
     generateScript(projectfile, script)
 
+from json import escapeJson
+
+proc writeJsonBuildInstructions*(projectfile: string) =
+  template lit(x: untyped) = f.write x
+  template str(x: untyped) =
+    buf.setLen 0
+    escapeJson(x, buf)
+    f.write buf
+
+  proc cfiles(f: File; buf: var string; list: TLinkedList, isExternal: bool) =
+    var it = PStrEntry(list.head)
+    while it != nil:
+      let compileCmd = getCompileCFileCmd(it.data, isExternal)
+      lit "["
+      str it.data
+      lit ", "
+      str compileCmd
+      it = PStrEntry(it.next)
+      if it == nil:
+        lit "]\L"
+      else:
+        lit "],\L"
+
+  proc linkfiles(f: File; buf, objfiles: var string; toLink: TLinkedList) =
+    var it = PStrEntry(toLink.head)
+    while it != nil:
+      let objfile = addFileExt(it.data, CC[cCompiler].objExt)
+      str objfile
+      add(objfiles, ' ')
+      add(objfiles, quoteShell(objfile))
+      it = PStrEntry(it.next)
+      if it == nil:
+        lit "\L"
+      else:
+        lit ",\L"
+
+  var buf = newStringOfCap(50)
+
+  let file = projectfile.splitFile.name
+  let jsonFile = toGeneratedFile(file, "json")
+
+  var f: File
+  if open(f, jsonFile, fmWrite):
+    lit "{\"compile\":[\L"
+    cfiles(f, buf, toCompile, false)
+    lit "],\L\"extcompile\":[\L"
+    cfiles(f, buf, externalToCompile, true)
+    lit "],\L\"link\":[\L"
+    var objfiles = ""
+    linkfiles(f, buf, objfiles, toLink)
+
+    lit "],\L\"linkcmd\": "
+    str getLinkCmd(projectfile, objfiles)
+    lit "\L}\L"
+    close(f)
+
 proc genMappingFiles(list: TLinkedList): Rope =
   var it = PStrEntry(list.head)
   while it != nil: