cross-compilation improvements

This commit is contained in:
Araq 2012-07-08 23:33:45 +02:00
commit f0dd96fa58
5 changed files with 54 additions and 20 deletions

View file

@ -386,7 +386,6 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
if theOS == osNone: LocalError(info, errUnknownOS, arg) if theOS == osNone: LocalError(info, errUnknownOS, arg)
elif theOS != platform.hostOS: elif theOS != platform.hostOS:
setTarget(theOS, targetCPU) setTarget(theOS, targetCPU)
incl(gGlobalOptions, optCompileOnly)
condsyms.InitDefines() condsyms.InitDefines()
of "cpu": of "cpu":
expectArg(switch, arg, pass, info) 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) if cpu == cpuNone: LocalError(info, errUnknownCPU, arg)
elif cpu != platform.hostCPU: elif cpu != platform.hostCPU:
setTarget(targetOS, cpu) setTarget(targetOS, cpu)
incl(gGlobalOptions, optCompileOnly)
condsyms.InitDefines() condsyms.InitDefines()
of "run", "r": of "run", "r":
expectNoArg(switch, arg, pass, info) expectNoArg(switch, arg, pass, info)

View file

@ -326,12 +326,27 @@ proc NameToCC*(name: string): TSystemCC =
return i return i
result = ccNone 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) = proc setCC*(ccname: string) =
ccompiler = nameToCC(ccname) ccompiler = nameToCC(ccname)
if ccompiler == ccNone: rawMessage(errUnknownCcompiler, ccname) if ccompiler == ccNone: rawMessage(errUnknownCcompiler, ccname)
compileOptions = getConfigVar(CC[ccompiler].name & ".options.always") compileOptions = getConfigVar(ccompiler, ".options.always")
linkOptions = getConfigVar(CC[ccompiler].name & ".options.linker") linkOptions = getConfigVar(ccompiler, ".options.linker")
ccompilerpath = getConfigVar(CC[ccompiler].name & ".path") ccompilerpath = getConfigVar(ccompiler, ".path")
for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name) for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name)
defineSymbol(CC[ccompiler].name) defineSymbol(CC[ccompiler].name)
@ -352,10 +367,10 @@ proc initVars*() =
defineSymbol(CC[ccompiler].name) defineSymbol(CC[ccompiler].name)
if gCmd == cmdCompileToCpp: cExt = ".cpp" if gCmd == cmdCompileToCpp: cExt = ".cpp"
elif gCmd == cmdCompileToOC: cExt = ".m" elif gCmd == cmdCompileToOC: cExt = ".m"
addCompileOption(getConfigVar(CC[ccompiler].name & ".options.always")) addCompileOption(getConfigVar(ccompiler, ".options.always"))
addLinkOption(getConfigVar(CC[ccompiler].name & ".options.linker")) addLinkOption(getConfigVar(ccompiler, ".options.linker"))
if len(ccompilerPath) == 0: if len(ccompilerPath) == 0:
ccompilerpath = getConfigVar(CC[ccompiler].name & ".path") ccompilerpath = getConfigVar(ccompiler, ".path")
proc completeCFilePath*(cfile: string, createSubDir: bool = true): string = proc completeCFilePath*(cfile: string, createSubDir: bool = true): string =
result = completeGeneratedFilePath(cfile, createSubDir) result = completeGeneratedFilePath(cfile, createSubDir)
@ -408,18 +423,18 @@ proc generateScript(projectFile: string, script: PRope) =
platform.os[targetOS].scriptExt)) platform.os[targetOS].scriptExt))
proc getOptSpeed(c: TSystemCC): string = proc getOptSpeed(c: TSystemCC): string =
result = getConfigVar(cc[c].name & ".options.speed") result = getConfigVar(c, ".options.speed")
if result == "": if result == "":
result = cc[c].optSpeed # use default settings from this file result = cc[c].optSpeed # use default settings from this file
proc getDebug(c: TSystemCC): string = proc getDebug(c: TSystemCC): string =
result = getConfigVar(cc[c].name & ".options.debug") result = getConfigVar(c, ".options.debug")
if result == "": if result == "":
result = cc[c].debug # use default settings from this file result = cc[c].debug # use default settings from this file
proc getOptSize(c: TSystemCC): string = proc getOptSize(c: TSystemCC): string =
result = getConfigVar(cc[c].name & ".options.size") result = getConfigVar(c, ".options.size")
if result == "": if result == "":
result = cc[c].optSize # use default settings from this file result = cc[c].optSize # use default settings from this file
proc noAbsolutePaths: bool {.inline.} = proc noAbsolutePaths: bool {.inline.} =
@ -469,9 +484,9 @@ proc getLinkOptions: string =
proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
var c = ccompiler var c = ccompiler
var options = CFileSpecificOptions(cfilename) var options = CFileSpecificOptions(cfilename)
var exe = cc[c].compilerExe var exe = getConfigVar(c, ".exe")
var key = cc[c].name & ".exe" if exe.len == 0: exe = cc[c].compilerExe
if existsConfigVar(key): exe = getConfigVar(key)
if targetOS == osWindows: exe = addFileExt(exe, "exe") if targetOS == osWindows: exe = addFileExt(exe, "exe")
if optGenDynLib in gGlobalOptions and if optGenDynLib in gGlobalOptions and
ospNeedsPIC in platform.OS[targetOS].props: ospNeedsPIC in platform.OS[targetOS].props:
@ -561,7 +576,7 @@ proc CallCCompiler*(projectfile: string) =
"objfiles", objfiles] "objfiles", objfiles]
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd) if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
else: else:
var linkerExe = getConfigVar(cc[c].name & ".linkerexe") var linkerExe = getConfigVar(c, ".linkerexe")
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe") if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe")
if noAbsolutePaths(): linkCmd = quoteIfContainsWhite(linkerExe) if noAbsolutePaths(): linkCmd = quoteIfContainsWhite(linkerExe)

View file

@ -9,6 +9,10 @@
cc = gcc 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: @if nim:
# use the old fixed library for bootstrapping with Nim: # use the old fixed library for bootstrapping with Nim:
lib = "nimlib" lib = "nimlib"

View file

@ -103,7 +103,20 @@ To `cross compile`:idx:, use for example::
nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim 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 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 DLL generation

View file

@ -199,6 +199,10 @@ if [ $# -eq 1 ] ; then
cp doc/manual.html $docdir/manual.html cp doc/manual.html $docdir/manual.html
chmod 644 $docdir/manual.html chmod 644 $docdir/manual.html
fi 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 if [ -f doc/mytest.cfg ]; then
cp doc/mytest.cfg $docdir/mytest.cfg cp doc/mytest.cfg $docdir/mytest.cfg
chmod 644 $docdir/mytest.cfg chmod 644 $docdir/mytest.cfg