summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-07-08 23:33:45 +0200
committerAraq <rumpf_a@web.de>2012-07-08 23:33:45 +0200
commitf0dd96fa58478f732009def25f527d67d87e464c (patch)
tree4445c7663570fc351853451f6f68b0de3c4bf6cc
parentbb82e305081f65af828a0b88a455ee352bac8157 (diff)
downloadNim-f0dd96fa58478f732009def25f527d67d87e464c.tar.gz
cross-compilation improvements
-rwxr-xr-xcompiler/commands.nim2
-rwxr-xr-xcompiler/extccomp.nim49
-rwxr-xr-xconfig/nimrod.cfg4
-rwxr-xr-xdoc/nimrodc.txt15
-rwxr-xr-xinstall.sh4
5 files changed, 54 insertions, 20 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim
index cec0bbe6b..508106cca 100755
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -386,7 +386,6 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
       if theOS == osNone: LocalError(info, errUnknownOS, arg)
       elif theOS != platform.hostOS: 
         setTarget(theOS, targetCPU)
-        incl(gGlobalOptions, optCompileOnly)
         condsyms.InitDefines()
   of "cpu": 
     expectArg(switch, arg, pass, info)
@@ -395,7 +394,6 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
       if cpu == cpuNone: LocalError(info, errUnknownCPU, arg)
       elif cpu != platform.hostCPU: 
         setTarget(targetOS, cpu)
-        incl(gGlobalOptions, optCompileOnly)
         condsyms.InitDefines()
   of "run", "r": 
     expectNoArg(switch, arg, pass, info)
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 1f3def384..298d5b212 100755
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -326,12 +326,27 @@ proc NameToCC*(name: string): TSystemCC =
       return i
   result = ccNone
 
+proc getConfigVar(c: TSystemCC, suffix: string): string =
+  # use ``cpu.os.cc`` for cross compilation, unless ``--compileOnly`` is given
+  # for niminst support
+  if (platform.hostOS != targetOS or platform.hostCPU != targetCPU) and
+      optCompileOnly notin gGlobalOptions:
+    let fullCCname = platform.cpu[targetCPU].name & '.' & 
+                     platform.os[targetOS].name & '.' & 
+                     CC[c].name & suffix
+    result = getConfigVar(fullCCname)
+    if result.len == 0:
+      # not overriden for this cross compilation setting?
+      result = getConfigVar(CC[c].name & suffix)
+  else:
+    result = getConfigVar(CC[c].name & suffix)
+
 proc setCC*(ccname: string) = 
   ccompiler = nameToCC(ccname)
   if ccompiler == ccNone: rawMessage(errUnknownCcompiler, ccname)
-  compileOptions = getConfigVar(CC[ccompiler].name & ".options.always")
-  linkOptions = getConfigVar(CC[ccompiler].name & ".options.linker")
-  ccompilerpath = getConfigVar(CC[ccompiler].name & ".path")
+  compileOptions = getConfigVar(ccompiler, ".options.always")
+  linkOptions = getConfigVar(ccompiler, ".options.linker")
+  ccompilerpath = getConfigVar(ccompiler, ".path")
   for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name)
   defineSymbol(CC[ccompiler].name)
 
@@ -352,10 +367,10 @@ proc initVars*() =
   defineSymbol(CC[ccompiler].name)
   if gCmd == cmdCompileToCpp: cExt = ".cpp"
   elif gCmd == cmdCompileToOC: cExt = ".m"
-  addCompileOption(getConfigVar(CC[ccompiler].name & ".options.always"))
-  addLinkOption(getConfigVar(CC[ccompiler].name & ".options.linker"))
-  if len(ccompilerPath) == 0: 
-    ccompilerpath = getConfigVar(CC[ccompiler].name & ".path")
+  addCompileOption(getConfigVar(ccompiler, ".options.always"))
+  addLinkOption(getConfigVar(ccompiler, ".options.linker"))
+  if len(ccompilerPath) == 0:
+    ccompilerpath = getConfigVar(ccompiler, ".path")
 
 proc completeCFilePath*(cfile: string, createSubDir: bool = true): string = 
   result = completeGeneratedFilePath(cfile, createSubDir)
@@ -408,18 +423,18 @@ proc generateScript(projectFile: string, script: PRope) =
                                      platform.os[targetOS].scriptExt))
 
 proc getOptSpeed(c: TSystemCC): string = 
-  result = getConfigVar(cc[c].name & ".options.speed")
-  if result == "": 
+  result = getConfigVar(c, ".options.speed")
+  if result == "":
     result = cc[c].optSpeed   # use default settings from this file
 
 proc getDebug(c: TSystemCC): string = 
-  result = getConfigVar(cc[c].name & ".options.debug")
-  if result == "": 
+  result = getConfigVar(c, ".options.debug")
+  if result == "":
     result = cc[c].debug      # use default settings from this file
 
 proc getOptSize(c: TSystemCC): string = 
-  result = getConfigVar(cc[c].name & ".options.size")
-  if result == "": 
+  result = getConfigVar(c, ".options.size")
+  if result == "":
     result = cc[c].optSize    # use default settings from this file
 
 proc noAbsolutePaths: bool {.inline.} =
@@ -469,9 +484,9 @@ proc getLinkOptions: string =
 proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = 
   var c = ccompiler
   var options = CFileSpecificOptions(cfilename)
-  var exe = cc[c].compilerExe
-  var key = cc[c].name & ".exe"
-  if existsConfigVar(key): exe = getConfigVar(key)
+  var exe = getConfigVar(c, ".exe")
+  if exe.len == 0: exe = cc[c].compilerExe
+  
   if targetOS == osWindows: exe = addFileExt(exe, "exe")
   if optGenDynLib in gGlobalOptions and
       ospNeedsPIC in platform.OS[targetOS].props: 
@@ -561,7 +576,7 @@ proc CallCCompiler*(projectfile: string) =
                                   "objfiles", objfiles]
       if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
     else:
-      var linkerExe = getConfigVar(cc[c].name & ".linkerexe")
+      var linkerExe = getConfigVar(c, ".linkerexe")
       if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
       if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe")
       if noAbsolutePaths(): linkCmd = quoteIfContainsWhite(linkerExe)
diff --git a/config/nimrod.cfg b/config/nimrod.cfg
index deb996ca2..947054ab4 100755
--- a/config/nimrod.cfg
+++ b/config/nimrod.cfg
@@ -9,6 +9,10 @@
 
 cc = gcc
 
+# example of how to setup a cross-compiler:
+arm.linux.gcc.exe = "arm-linux-gcc"
+arm.linux.gcc.linkerexe = "arm-linux-gcc"
+
 @if nim: 
   # use the old fixed library for bootstrapping with Nim:
   lib = "nimlib"
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index b131acca1..0b740025a 100755
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -103,7 +103,20 @@ To `cross compile`:idx:, use for example::
   nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim

 

 Then move the C code and the compile script ``compile_myproject.sh`` to your 

-Linux i386 machine and run the script.

+Linux i386 machine and run the script.
+
+Another way is to make Nimrod invoke a cross compiler toolchain::
+  
+  nimrod c --cpu:arm --os:linux myproject.nim

+  
+For cross compilation, the compiler invokes a C compiler named 
+like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration 
+system is used to provide meaningful defaults. For example for ``ARM`` your
+configuration file should contain something like::
+
+  arm.linux.gcc.path = "/usr/bin"
+  arm.linux.gcc.exe = "arm-linux-gcc"
+  arm.linux.gcc.linkerexe = "arm-linux-gcc"
 

 

 DLL generation

diff --git a/install.sh b/install.sh
index c83300293..db73cdd87 100755
--- a/install.sh
+++ b/install.sh
@@ -199,6 +199,10 @@ if [ $# -eq 1 ] ; then
     cp doc/manual.html $docdir/manual.html
     chmod 644 $docdir/manual.html
   fi
+  if [ -f doc/nimrodc.html ]; then
+    cp doc/nimrodc.html $docdir/nimrodc.html
+    chmod 644 $docdir/nimrodc.html
+  fi
   if [ -f doc/mytest.cfg ]; then
     cp doc/mytest.cfg $docdir/mytest.cfg
     chmod 644 $docdir/mytest.cfg