tccgen.nim 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. import
  10. os, strutils, options, msgs, tinyc, lineinfos, sequtils
  11. const tinyPrefix = "dist/nim-tinyc-archive".unixToNativePath
  12. const nimRoot = currentSourcePath.parentDir.parentDir
  13. const tinycRoot = nimRoot / tinyPrefix
  14. when not dirExists(tinycRoot):
  15. static: doAssert false, $(tinycRoot, "requires: ./koch installdeps tinyc")
  16. {.compile: tinycRoot / "tinyc/libtcc.c".}
  17. var
  18. gConf: ConfigRef # ugly but can be cleaned up if this is revived
  19. proc tinyCErrorHandler(closure: pointer, msg: cstring) {.cdecl.} =
  20. rawMessage(gConf, errGenerated, $msg)
  21. proc initTinyCState: PccState =
  22. result = openCCState()
  23. setErrorFunc(result, nil, tinyCErrorHandler)
  24. var
  25. gTinyC = initTinyCState()
  26. libIncluded = false
  27. proc addFile(filename: string) =
  28. if addFile(gTinyC, filename) != 0'i32:
  29. rawMessage(gConf, errCannotOpenFile, filename)
  30. proc setupEnvironment =
  31. when defined(amd64):
  32. defineSymbol(gTinyC, "__x86_64__", nil)
  33. elif defined(i386):
  34. defineSymbol(gTinyC, "__i386__", nil)
  35. when defined(linux):
  36. defineSymbol(gTinyC, "__linux__", nil)
  37. defineSymbol(gTinyC, "__linux", nil)
  38. var nimDir = getPrefixDir(gConf).string
  39. var tinycRoot = nimDir / tinyPrefix
  40. let libpath = nimDir / "lib"
  41. addIncludePath(gTinyC, cstring(libpath))
  42. when defined(windows):
  43. addSysincludePath(gTinyC, cstring(tinycRoot / "tinyc/win32/include"))
  44. addSysincludePath(gTinyC, cstring(tinycRoot / "tinyc/include"))
  45. when defined(windows):
  46. defineSymbol(gTinyC, "_WIN32", nil)
  47. # we need Mingw's headers too:
  48. var gccbin = getConfigVar("gcc.path") % ["nim", tinycRoot]
  49. addSysincludePath(gTinyC, cstring(gccbin /../ "include"))
  50. #addFile(tinycRoot / r"tinyc\win32\wincrt1.o")
  51. addFile(tinycRoot / r"tinyc\win32\alloca86.o")
  52. addFile(tinycRoot / r"tinyc\win32\chkstk.o")
  53. #addFile(tinycRoot / r"tinyc\win32\crt1.o")
  54. #addFile(tinycRoot / r"tinyc\win32\dllcrt1.o")
  55. #addFile(tinycRoot / r"tinyc\win32\dllmain.o")
  56. addFile(tinycRoot / r"tinyc\win32\libtcc1.o")
  57. #addFile(tinycRoot / r"tinyc\win32\lib\crt1.c")
  58. #addFile(tinycRoot / r"tinyc\lib\libtcc1.c")
  59. else:
  60. addSysincludePath(gTinyC, "/usr/include")
  61. when defined(amd64):
  62. addSysincludePath(gTinyC, "/usr/include/x86_64-linux-gnu")
  63. proc compileCCode*(ccode: string, conf: ConfigRef) =
  64. gConf = conf
  65. if not libIncluded:
  66. libIncluded = true
  67. setupEnvironment()
  68. discard compileString(gTinyC, ccode)
  69. proc run*(conf: ConfigRef, args: string) =
  70. doAssert gConf == conf
  71. var s = @[cstring(conf.projectName)] & map(split(args), proc(x: string): cstring = cstring(x))
  72. var err = tinyc.run(gTinyC, cint(s.len), cast[cstringArray](addr(s[0]))) != 0'i32
  73. closeCCState(gTinyC)
  74. if err: rawMessage(conf, errUnknown, "")