mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 11:54:11 +00:00
New algorithm for locating and loading nimrod config files.
Some new options added to the compiler (see news.txt for details)
This commit is contained in:
@@ -244,6 +244,10 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||
of "out", "o":
|
||||
expectArg(switch, arg, pass, info)
|
||||
options.outFile = arg
|
||||
of "mainmodule", "m":
|
||||
expectArg(switch, arg, pass, info)
|
||||
projectName = arg
|
||||
projectFullPath = projectPath/projectName
|
||||
of "define", "d":
|
||||
expectArg(switch, arg, pass, info)
|
||||
DefineSymbol(arg)
|
||||
@@ -333,15 +337,24 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||
of "app":
|
||||
expectArg(switch, arg, pass, info)
|
||||
case arg.normalize
|
||||
of "gui":
|
||||
of "gui":
|
||||
incl(gGlobalOptions, optGenGuiApp)
|
||||
defineSymbol("executable")
|
||||
defineSymbol("guiapp")
|
||||
of "console":
|
||||
of "console":
|
||||
excl(gGlobalOptions, optGenGuiApp)
|
||||
of "lib":
|
||||
defineSymbol("executable")
|
||||
defineSymbol("consoleapp")
|
||||
of "lib":
|
||||
incl(gGlobalOptions, optGenDynLib)
|
||||
excl(gGlobalOptions, optGenGuiApp)
|
||||
defineSymbol("library")
|
||||
defineSymbol("dll")
|
||||
of "staticlib":
|
||||
incl(gGlobalOptions, optGenStaticLib)
|
||||
excl(gGlobalOptions, optGenGuiApp)
|
||||
defineSymbol("library")
|
||||
defineSymbol("staticlib")
|
||||
else: LocalError(info, errGuiConsoleOrLibExpectedButXFound, arg)
|
||||
of "passc", "t":
|
||||
expectArg(switch, arg, pass, info)
|
||||
@@ -349,12 +362,24 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||
of "passl", "l":
|
||||
expectArg(switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: extccomp.addLinkOption(arg)
|
||||
of "cincludes":
|
||||
expectArg(switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: cIncludes.add arg
|
||||
of "clibdir":
|
||||
expectArg(switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: cLibs.add arg
|
||||
of "clib":
|
||||
expectArg(switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: cLinkedLibs.add arg
|
||||
of "index":
|
||||
expectArg(switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: gIndexFile = arg
|
||||
of "import":
|
||||
of "import":
|
||||
expectArg(switch, arg, pass, info)
|
||||
options.addImplicitMod(arg)
|
||||
if pass in {passCmd2, passPP}: implicitImports.add arg
|
||||
of "include":
|
||||
expectArg(switch, arg, pass, info)
|
||||
if pass in {passCmd2, passPP}: implicitIncludes.add arg
|
||||
of "listcmd":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
incl(gGlobalOptions, optListCmd)
|
||||
@@ -405,6 +430,9 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||
of "skipprojcfg":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
incl(gGlobalOptions, optSkipProjConfigFile)
|
||||
of "skipusercfg":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
incl(gGlobalOptions, optSkipUserConfigFile)
|
||||
of "genscript":
|
||||
expectNoArg(switch, arg, pass, info)
|
||||
incl(gGlobalOptions, optGenScript)
|
||||
|
||||
@@ -15,9 +15,9 @@ import
|
||||
ast, astalgo, strutils, hashes, options, nversion, msgs, os, ropes, idents,
|
||||
wordrecg, math, syntaxes, renderer, lexer, rst, times, highlite
|
||||
|
||||
proc CommandDoc*(filename: string)
|
||||
proc CommandRst2Html*(filename: string)
|
||||
proc CommandRst2TeX*(filename: string)
|
||||
proc CommandDoc*()
|
||||
proc CommandRst2Html*()
|
||||
proc CommandRst2TeX*()
|
||||
# implementation
|
||||
|
||||
type
|
||||
@@ -870,14 +870,14 @@ proc writeOutput(d: PDoc, filename, outExt: string) =
|
||||
else:
|
||||
writeRope(content, getOutFile(filename, outExt))
|
||||
|
||||
proc CommandDoc(filename: string) =
|
||||
var ast = parseFile(addFileExt(filename, nimExt))
|
||||
proc CommandDoc =
|
||||
var ast = parseFile(addFileExt(projectFullPath, nimExt))
|
||||
if ast == nil: return
|
||||
var d = newDocumentor(filename)
|
||||
var d = newDocumentor(projectFullPath)
|
||||
initIndexFile(d)
|
||||
d.hasToc = true
|
||||
generateDoc(d, ast)
|
||||
writeOutput(d, filename, HtmlExt)
|
||||
writeOutput(d, projectFullPath, HtmlExt)
|
||||
generateIndex(d)
|
||||
|
||||
proc CommandRstAux(filename, outExt: string) =
|
||||
@@ -889,9 +889,10 @@ proc CommandRstAux(filename, outExt: string) =
|
||||
writeOutput(d, filename, outExt)
|
||||
generateIndex(d)
|
||||
|
||||
proc CommandRst2Html(filename: string) =
|
||||
CommandRstAux(filename, HtmlExt)
|
||||
proc CommandRst2Html =
|
||||
CommandRstAux(projectFullPath, HtmlExt)
|
||||
|
||||
proc CommandRst2TeX(filename: string) =
|
||||
proc CommandRst2TeX =
|
||||
splitter = "\\-"
|
||||
CommandRstAux(filename, TexExt)
|
||||
CommandRstAux(projectFullPath, TexExt)
|
||||
|
||||
|
||||
@@ -32,223 +32,290 @@ type
|
||||
compileTmpl: string, # the compile command template
|
||||
buildGui: string, # command to build a GUI application
|
||||
buildDll: string, # command to build a shared library
|
||||
buildLib: string, # command to build a static library
|
||||
linkerExe: string, # the linker's executable
|
||||
linkTmpl: string, # command to link files to produce an exe
|
||||
includeCmd: string, # command to add an include dir
|
||||
linkDirCmd: string, # command to add a lib dir
|
||||
linkLibCmd: string, # command to link an external library
|
||||
debug: string, # flags for debug build
|
||||
pic: string, # command for position independent code
|
||||
# used on some platforms
|
||||
asmStmtFrmt: string, # format of ASM statement
|
||||
props: TInfoCCProps] # properties of the C compiler
|
||||
|
||||
|
||||
# Configuration settings for various compilers.
|
||||
# When adding new compilers, the cmake sources could be a good reference:
|
||||
# http://cmake.org/gitweb?p=cmake.git;a=tree;f=Modules/Platform;
|
||||
|
||||
template compiler(name: expr, settings: stmt):stmt =
|
||||
proc name: TInfoCC {.compileTime.} = settings
|
||||
|
||||
compiler gcc:
|
||||
result = (
|
||||
name: "gcc",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 -ffast-math ",
|
||||
optSize: " -Os -ffast-math ",
|
||||
compilerExe: "gcc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: " -mwindows",
|
||||
buildDll: " -shared",
|
||||
buildLib: "ar rcs $libfile $objfiles",
|
||||
linkerExe: "gcc",
|
||||
linkTmpl: "$buildgui $builddll -o $exefile $objfiles $options",
|
||||
includeCmd: " -I",
|
||||
linkDirCmd: " -L",
|
||||
linkLibCmd: " -l$1",
|
||||
debug: "",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp})
|
||||
|
||||
compiler gpp:
|
||||
result = gcc()
|
||||
|
||||
result.name = "gpp"
|
||||
result.compilerExe = "g++"
|
||||
result.linkerExe = "g++"
|
||||
|
||||
result.debug.add " -g " # XXX: Why is this default for g++, but not for gcc?
|
||||
|
||||
result.buildDll = " -mdll" # XXX: Hmm, I'm keeping this from the previos version,
|
||||
# but my gcc doesn't even have such an option (is this mingw?)
|
||||
|
||||
compiler llvmGcc:
|
||||
result = gcc()
|
||||
|
||||
result.name = "llvm_gcc"
|
||||
result.compilerExe = "llvm-gcc"
|
||||
result.buildLib = "llvm-ar rcs $libfile $objfiles"
|
||||
result.linkerExe = "llvm-gcc"
|
||||
|
||||
compiler clang:
|
||||
result = llvmGcc()
|
||||
|
||||
result.name = "clang"
|
||||
result.compilerExe = "clang"
|
||||
result.linkerExe = "clang"
|
||||
|
||||
compiler vcc:
|
||||
result = (
|
||||
name: "vcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " /Ogityb2 /G7 /arch:SSE2 ",
|
||||
optSize: " /O1 /G7 ",
|
||||
compilerExe: "cl",
|
||||
compileTmpl: "/c $options $include /Fo$objfile $file",
|
||||
buildGui: " /link /SUBSYSTEM:WINDOWS ",
|
||||
buildDll: " /LD",
|
||||
buildLib: "lib /OUT:$libfile $objfiles",
|
||||
linkerExe: "cl",
|
||||
linkTmpl: "$options $builddll /Fe$exefile $objfiles $buildgui",
|
||||
includeCmd: " /I",
|
||||
linkDirCmd: " /LIBPATH:",
|
||||
linkLibCmd: " $1.lib",
|
||||
debug: " /GZ /Zi ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp, hasAssume})
|
||||
|
||||
compiler icc:
|
||||
# Intel compilers try to imitate the native ones (gcc and msvc)
|
||||
when defined(windows):
|
||||
result = vcc()
|
||||
else:
|
||||
result = gcc()
|
||||
|
||||
result.name = "icc"
|
||||
result.compilerExe = "icc"
|
||||
result.linkerExe = "icc"
|
||||
|
||||
compiler lcc:
|
||||
result = (
|
||||
name: "lcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -O -p6 ",
|
||||
optSize: " -O -p6 ",
|
||||
compilerExe: "lcc",
|
||||
compileTmpl: "$options $include -Fo$objfile $file",
|
||||
buildGui: " -subsystem windows",
|
||||
buildDll: " -dll",
|
||||
buildLib: "", # XXX: not supported yet
|
||||
linkerExe: "lcclnk",
|
||||
linkTmpl: "$options $buildgui $builddll -O $exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
linkDirCmd: "", # XXX: not supported yet
|
||||
linkLibCmd: "", # XXX: not supported yet
|
||||
debug: " -g5 ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "_asm{$n$1$n}$n",
|
||||
props: {})
|
||||
|
||||
compiler bcc:
|
||||
result = (
|
||||
name: "bcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -O2 -6 ",
|
||||
optSize: " -O1 -6 ",
|
||||
compilerExe: "bcc32",
|
||||
compileTmpl: "-c $options $include -o$objfile $file",
|
||||
buildGui: " -tW",
|
||||
buildDll: " -tWD",
|
||||
buildLib: "", # XXX: not supported yet
|
||||
linkerExe: "bcc32",
|
||||
linkTmpl: "$options $buildgui $builddll -e$exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
linkDirCmd: "", # XXX: not supported yet
|
||||
linkLibCmd: "", # XXX: not supported yet
|
||||
debug: "",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp})
|
||||
|
||||
compiler dmc:
|
||||
result = (
|
||||
name: "dmc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -ff -o -6 ",
|
||||
optSize: " -ff -o -6 ",
|
||||
compilerExe: "dmc",
|
||||
compileTmpl: "-c $options $include -o$objfile $file",
|
||||
buildGui: " -L/exet:nt/su:windows",
|
||||
buildDll: " -WD",
|
||||
buildLib: "", # XXX: not supported yet
|
||||
linkerExe: "dmc",
|
||||
linkTmpl: "$options $buildgui $builddll -o$exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
linkDirCmd: "", # XXX: not supported yet
|
||||
linkLibCmd: "", # XXX: not supported yet
|
||||
debug: " -g ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp})
|
||||
|
||||
compiler wcc:
|
||||
result = (
|
||||
name: "wcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -ox -on -6 -d0 -fp6 -zW ",
|
||||
optSize: "",
|
||||
compilerExe: "wcl386",
|
||||
compileTmpl: "-c $options $include -fo=$objfile $file",
|
||||
buildGui: " -bw",
|
||||
buildDll: " -bd",
|
||||
buildLib: "", # XXX: not supported yet
|
||||
linkerExe: "wcl386",
|
||||
linkTmpl: "$options $buildgui $builddll -fe=$exefile $objfiles ",
|
||||
includeCmd: " -i=",
|
||||
linkDirCmd: "", # XXX: not supported yet
|
||||
linkLibCmd: "", # XXX: not supported yet
|
||||
debug: " -d2 ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp})
|
||||
|
||||
compiler tcc:
|
||||
result = (
|
||||
name: "tcc",
|
||||
objExt: "o",
|
||||
optSpeed: "",
|
||||
optSize: "",
|
||||
compilerExe: "tcc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: "UNAVAILABLE!",
|
||||
buildDll: " -shared",
|
||||
buildLib: "", # XXX: not supported yet
|
||||
linkerExe: "tcc",
|
||||
linkTmpl: "-o $exefile $options $buildgui $builddll $objfiles",
|
||||
includeCmd: " -I",
|
||||
linkDirCmd: "", # XXX: not supported yet
|
||||
linkLibCmd: "", # XXX: not supported yet
|
||||
debug: " -g ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasSwitchRange, hasComputedGoto})
|
||||
|
||||
compiler pcc:
|
||||
# Pelles C
|
||||
result = (
|
||||
name: "pcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -Ox ",
|
||||
optSize: " -Os ",
|
||||
compilerExe: "cc",
|
||||
compileTmpl: "-c $options $include -Fo$objfile $file",
|
||||
buildGui: " -SUBSYSTEM:WINDOWS",
|
||||
buildDll: " -DLL",
|
||||
buildLib: "", # XXX: not supported yet
|
||||
linkerExe: "cc",
|
||||
linkTmpl: "$options $buildgui $builddll -OUT:$exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
linkDirCmd: "", # XXX: not supported yet
|
||||
linkLibCmd: "", # XXX: not supported yet
|
||||
debug: " -Zi ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {})
|
||||
|
||||
compiler ucc:
|
||||
result = (
|
||||
name: "ucc",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 ",
|
||||
optSize: " -O1 ",
|
||||
compilerExe: "cc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: "",
|
||||
buildDll: " -shared ",
|
||||
buildLib: "", # XXX: not supported yet
|
||||
linkerExe: "cc",
|
||||
linkTmpl: "-o $exefile $buildgui $builddll $objfiles $options",
|
||||
includeCmd: " -I",
|
||||
linkDirCmd: "", # XXX: not supported yet
|
||||
linkLibCmd: "", # XXX: not supported yet
|
||||
debug: "",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {})
|
||||
|
||||
const
|
||||
CC*: array[succ(low(TSystemCC))..high(TSystemCC), TInfoCC] = [
|
||||
(name: "gcc",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 -ffast-math ",
|
||||
optSize: " -Os -ffast-math ",
|
||||
compilerExe: "gcc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: " -mwindows",
|
||||
buildDll: " -shared",
|
||||
linkerExe: "gcc",
|
||||
linkTmpl: "$buildgui $builddll -o $exefile $objfiles $options",
|
||||
includeCmd: " -I",
|
||||
debug: "",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp}),
|
||||
(name: "llvm_gcc",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 -ffast-math ",
|
||||
optSize: " -Os -ffast-math ",
|
||||
compilerExe: "llvm-gcc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: " -mwindows",
|
||||
buildDll: " -shared",
|
||||
linkerExe: "llvm-gcc",
|
||||
linkTmpl: "$buildgui $builddll -o $exefile $objfiles $options",
|
||||
includeCmd: " -I",
|
||||
debug: "",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp}),
|
||||
(name: "clang",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 -ffast-math ",
|
||||
optSize: " -Os -ffast-math ",
|
||||
compilerExe: "clang",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: " -mwindows",
|
||||
buildDll: " -shared",
|
||||
linkerExe: "clang",
|
||||
linkTmpl: "$buildgui $builddll -o $exefile $objfiles $options",
|
||||
includeCmd: " -I",
|
||||
debug: "",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp}),
|
||||
(name: "lcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -O -p6 ",
|
||||
optSize: " -O -p6 ",
|
||||
compilerExe: "lcc",
|
||||
compileTmpl: "$options $include -Fo$objfile $file",
|
||||
buildGui: " -subsystem windows",
|
||||
buildDll: " -dll",
|
||||
linkerExe: "lcclnk",
|
||||
linkTmpl: "$options $buildgui $builddll -O $exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: " -g5 ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "_asm{$n$1$n}$n",
|
||||
props: {}),
|
||||
(name: "bcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -O2 -6 ",
|
||||
optSize: " -O1 -6 ",
|
||||
compilerExe: "bcc32",
|
||||
compileTmpl: "-c $options $include -o$objfile $file",
|
||||
buildGui: " -tW",
|
||||
buildDll: " -tWD",
|
||||
linkerExe: "bcc32",
|
||||
linkTmpl: "$options $buildgui $builddll -e$exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: "",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp}),
|
||||
(name: "dmc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -ff -o -6 ",
|
||||
optSize: " -ff -o -6 ",
|
||||
compilerExe: "dmc",
|
||||
compileTmpl: "-c $options $include -o$objfile $file",
|
||||
buildGui: " -L/exet:nt/su:windows",
|
||||
buildDll: " -WD",
|
||||
linkerExe: "dmc",
|
||||
linkTmpl: "$options $buildgui $builddll -o$exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: " -g ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp}),
|
||||
(name: "wcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " -ox -on -6 -d0 -fp6 -zW ",
|
||||
optSize: "",
|
||||
compilerExe: "wcl386",
|
||||
compileTmpl: "-c $options $include -fo=$objfile $file",
|
||||
buildGui: " -bw",
|
||||
buildDll: " -bd",
|
||||
linkerExe: "wcl386",
|
||||
linkTmpl: "$options $buildgui $builddll -fe=$exefile $objfiles ",
|
||||
includeCmd: " -i=",
|
||||
debug: " -d2 ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp}),
|
||||
(name: "vcc",
|
||||
objExt: "obj",
|
||||
optSpeed: " /Ogityb2 /G7 /arch:SSE2 ",
|
||||
optSize: " /O1 /G7 ",
|
||||
compilerExe: "cl",
|
||||
compileTmpl: "/c $options $include /Fo$objfile $file",
|
||||
buildGui: " /link /SUBSYSTEM:WINDOWS ",
|
||||
buildDll: " /LD",
|
||||
linkerExe: "cl",
|
||||
linkTmpl: "$options $builddll /Fe$exefile $objfiles $buildgui",
|
||||
includeCmd: " /I",
|
||||
debug: " /GZ /Zi ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasCpp, hasAssume}),
|
||||
(name: "tcc",
|
||||
objExt: "o",
|
||||
optSpeed: "",
|
||||
optSize: "",
|
||||
compilerExe: "tcc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: "UNAVAILABLE!",
|
||||
buildDll: " -shared",
|
||||
linkerExe: "tcc",
|
||||
linkTmpl: "-o $exefile $options $buildgui $builddll $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: " -g ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {hasSwitchRange, hasComputedGoto}),
|
||||
(name: "pcc", # Pelles C
|
||||
objExt: "obj",
|
||||
optSpeed: " -Ox ",
|
||||
optSize: " -Os ",
|
||||
compilerExe: "cc",
|
||||
compileTmpl: "-c $options $include -Fo$objfile $file",
|
||||
buildGui: " -SUBSYSTEM:WINDOWS",
|
||||
buildDll: " -DLL",
|
||||
linkerExe: "cc",
|
||||
linkTmpl: "$options $buildgui $builddll -OUT:$exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: " -Zi ",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {}),
|
||||
(name: "ucc",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 ",
|
||||
optSize: " -O1 ",
|
||||
compilerExe: "cc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: "",
|
||||
buildDll: " -shared ",
|
||||
linkerExe: "cc",
|
||||
linkTmpl: "-o $exefile $buildgui $builddll $objfiles $options",
|
||||
includeCmd: " -I",
|
||||
debug: "",
|
||||
pic: "",
|
||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||
props: {}),
|
||||
(name: "icc",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 ",
|
||||
optSize: " -Os ",
|
||||
compilerExe: "icc",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: " -mwindows",
|
||||
buildDll: " -mdll",
|
||||
linkerExe: "icc",
|
||||
linkTmpl: "$options $buildgui $builddll -o $exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: "",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp}),
|
||||
(name: "gpp",
|
||||
objExt: "o",
|
||||
optSpeed: " -O3 -ffast-math ",
|
||||
optSize: " -Os -ffast-math ",
|
||||
compilerExe: "g++",
|
||||
compileTmpl: "-c $options $include -o $objfile $file",
|
||||
buildGui: " -mwindows",
|
||||
buildDll: " -mdll",
|
||||
linkerExe: "g++",
|
||||
linkTmpl: "$buildgui $builddll -o $exefile $objfiles $options",
|
||||
includeCmd: " -I",
|
||||
debug: " -g ",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp})]
|
||||
|
||||
var ccompiler*: TSystemCC = ccGcc # the used compiler
|
||||
gcc(),
|
||||
llvmGcc(),
|
||||
clang(),
|
||||
lcc(),
|
||||
bcc(),
|
||||
dmc(),
|
||||
wcc(),
|
||||
vcc(),
|
||||
tcc(),
|
||||
pcc(),
|
||||
ucc(),
|
||||
icc(),
|
||||
gpp() ]
|
||||
|
||||
const
|
||||
hExt* = "h"
|
||||
|
||||
var cExt*: string = "c" # extension of generated C/C++ files
|
||||
# (can be changed to .cpp later)
|
||||
var
|
||||
cCompiler* = ccGcc # the used compiler
|
||||
|
||||
cExt* = "c" # extension of generated C/C++ files
|
||||
# (can be changed to .cpp later)
|
||||
|
||||
cIncludes*: seq[string] = @[] # list of directories to search for included files
|
||||
cLibs*: seq[string] = @[] # list of directories to search for lib files
|
||||
cLinkedLibs*: seq[string] = @[] # list of libraries to link
|
||||
|
||||
# implementation
|
||||
|
||||
when defined(windows):
|
||||
var libNameTmpl = "$1.lib"
|
||||
else:
|
||||
var libNameTmpl = "lib$1.a"
|
||||
|
||||
var
|
||||
toLink, toCompile, externalToCompile: TLinkedList
|
||||
linkOptions: string = ""
|
||||
@@ -363,6 +430,11 @@ const
|
||||
|
||||
var fileCounter: int
|
||||
|
||||
proc add(s: var string, many: openarray[string]) =
|
||||
# XXX: is there something like C++'s reserve?
|
||||
# We can use it here to avoid multiple reallocations
|
||||
for x in items(many): s.add x
|
||||
|
||||
proc getCompileCFileCmd*(cfilename: string, isExternal: bool = false): string =
|
||||
var
|
||||
cfile, objfile, options, includeCmd, compilePattern, key, trunk, exe: string
|
||||
@@ -396,6 +468,10 @@ proc getCompileCFileCmd*(cfilename: string, isExternal: bool = false): string =
|
||||
includeCmd = cc[c].includeCmd # this is more complex than needed, but
|
||||
# a workaround of a FPC bug...
|
||||
add(includeCmd, quoteIfContainsWhite(libpath))
|
||||
|
||||
for includeDir in items(cIncludes):
|
||||
includeCmd.add cc[c].includeCmd, includeDir.quoteIfContainsWhite
|
||||
|
||||
compilePattern = JoinPath(ccompilerpath, exe)
|
||||
else:
|
||||
includeCmd = ""
|
||||
@@ -453,47 +529,57 @@ proc CallCCompiler*(projectfile: string) =
|
||||
res = execProcesses(cmds, {poUseShell, poParentStreams},
|
||||
gNumberOfProcessors)
|
||||
if res != 0: rawMessage(errExecutionOfProgramFailed, [])
|
||||
if optNoLinking notin gGlobalOptions:
|
||||
if optNoLinking notin gGlobalOptions:
|
||||
# call the linker:
|
||||
var linkerExe = getConfigVar(cc[c].name & ".linkerexe")
|
||||
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
||||
if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe")
|
||||
if (platform.hostOS != targetOS): linkCmd = quoteIfContainsWhite(linkerExe)
|
||||
else: linkCmd = quoteIfContainsWhite(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 targetOS == platform.hostOS:
|
||||
exefile = joinPath(splitFile(projectFile).dir, exefile)
|
||||
exefile = quoteIfContainsWhite(exefile)
|
||||
var it = PStrEntry(toLink.head)
|
||||
var objfiles = ""
|
||||
while it != nil:
|
||||
while it != nil:
|
||||
add(objfiles, ' ')
|
||||
if targetOS == platform.hostOS:
|
||||
if targetOS == platform.hostOS:
|
||||
add(objfiles, quoteIfContainsWhite(addFileExt(it.data, cc[ccompiler].objExt)))
|
||||
else:
|
||||
else:
|
||||
add(objfiles, quoteIfContainsWhite(addFileExt(it.data, cc[ccompiler].objExt)))
|
||||
it = PStrEntry(it.next)
|
||||
linkCmd = quoteIfContainsWhite(linkCmd % ["builddll", builddll,
|
||||
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
|
||||
"exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath])
|
||||
add(linkCmd, ' ')
|
||||
addf(linkCmd, cc[c].linkTmpl, ["builddll", builddll,
|
||||
"buildgui", buildgui, "options", linkOptions,
|
||||
"objfiles", objfiles, "exefile", exefile,
|
||||
"nimrod", quoteIfContainsWhite(getPrefixDir()),
|
||||
"lib", quoteIfContainsWhite(libpath)])
|
||||
if not (optCompileOnly in gGlobalOptions): execExternalProgram(linkCmd)
|
||||
else:
|
||||
|
||||
if optGenStaticLib in gGlobalOptions:
|
||||
linkcmd = cc[c].buildLib % ["libfile", (libNameTmpl % projectName), "objfiles", objfiles]
|
||||
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
||||
else:
|
||||
var linkerExe = getConfigVar(cc[c].name & ".linkerexe")
|
||||
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
||||
if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe")
|
||||
if (platform.hostOS != targetOS): linkCmd = quoteIfContainsWhite(linkerExe)
|
||||
else: linkCmd = quoteIfContainsWhite(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 targetOS == platform.hostOS:
|
||||
exefile = joinPath(splitFile(projectFile).dir, exefile)
|
||||
exefile = quoteIfContainsWhite(exefile)
|
||||
for linkedLib in items(cLinkedLibs):
|
||||
linkOptions.add(cc[c].linkLibCmd % linkedLib.quoteIfContainsWhite)
|
||||
for libDir in items(cLibs):
|
||||
linkOptions.add cc[c].linkDirCmd, libDir.quoteIfContainsWhite
|
||||
|
||||
linkCmd = quoteIfContainsWhite(linkCmd % ["builddll", builddll,
|
||||
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
|
||||
"exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath])
|
||||
linkCmd.add ' '
|
||||
addf(linkCmd, cc[c].linkTmpl, ["builddll", builddll,
|
||||
"buildgui", buildgui, "options", linkOptions,
|
||||
"objfiles", objfiles, "exefile", exefile,
|
||||
"nimrod", quoteIfContainsWhite(getPrefixDir()),
|
||||
"lib", quoteIfContainsWhite(libpath)])
|
||||
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
||||
else:
|
||||
linkCmd = ""
|
||||
if optGenScript in gGlobalOptions:
|
||||
if optGenScript in gGlobalOptions:
|
||||
app(script, linkCmd)
|
||||
app(script, tnl)
|
||||
generateScript(projectFile, script)
|
||||
|
||||
@@ -23,7 +23,7 @@ const
|
||||
when has_LLVM_Backend:
|
||||
import llvmgen
|
||||
|
||||
proc MainCommand*(cmd, filename: string)
|
||||
proc MainCommand*()
|
||||
|
||||
# ------------------ module handling -----------------------------------------
|
||||
|
||||
@@ -68,7 +68,7 @@ proc importModule(filename: string): PSym =
|
||||
elif sfSystemModule in result.flags:
|
||||
LocalError(result.info, errAttemptToRedefine, result.Name.s)
|
||||
|
||||
proc CompileModule(filename: string, flags: TSymFlags): PSym =
|
||||
proc CompileModule(filename: string, flags: TSymFlags): PSym =
|
||||
var rd: PRodReader = nil
|
||||
var f = addFileExt(filename, nimExt)
|
||||
result = newModule(filename)
|
||||
@@ -81,57 +81,56 @@ proc CompileModule(filename: string, flags: TSymFlags): PSym =
|
||||
result.id = getID()
|
||||
processModule(result, f, nil, rd)
|
||||
|
||||
proc CompileProject(filename: string) =
|
||||
discard CompileModule(options.libpath / addFileExt("system", nimExt),
|
||||
{sfSystemModule})
|
||||
discard CompileModule(addFileExt(filename, nimExt), {sfMainModule})
|
||||
proc CompileProject(projectFile = projectFullPath) =
|
||||
discard CompileModule(options.libpath / "system", {sfSystemModule})
|
||||
discard CompileModule(projectFile, {sfMainModule})
|
||||
|
||||
proc semanticPasses() =
|
||||
proc semanticPasses =
|
||||
registerPass(verbosePass())
|
||||
registerPass(sem.semPass())
|
||||
registerPass(transf.transfPass())
|
||||
|
||||
proc CommandGenDepend(filename: string) =
|
||||
proc CommandGenDepend =
|
||||
semanticPasses()
|
||||
registerPass(genDependPass())
|
||||
registerPass(cleanupPass())
|
||||
compileProject(filename)
|
||||
generateDot(filename)
|
||||
execExternalProgram("dot -Tpng -o" & changeFileExt(filename, "png") & ' ' &
|
||||
changeFileExt(filename, "dot"))
|
||||
compileProject()
|
||||
generateDot(projectFullPath)
|
||||
execExternalProgram("dot -Tpng -o" & changeFileExt(projectFullPath, "png") & ' ' &
|
||||
changeFileExt(projectFullPath, "dot"))
|
||||
|
||||
proc CommandCheck(filename: string) =
|
||||
proc CommandCheck =
|
||||
msgs.gErrorMax = high(int) # do not stop after first error
|
||||
semanticPasses() # use an empty backend for semantic checking only
|
||||
registerPass(rodwrite.rodwritePass())
|
||||
compileProject(filename)
|
||||
compileProject(mainCommandArg())
|
||||
|
||||
proc CommandCompileToC(filename: string) =
|
||||
proc CommandCompileToC =
|
||||
semanticPasses()
|
||||
registerPass(cgen.cgenPass())
|
||||
registerPass(rodwrite.rodwritePass())
|
||||
#registerPass(cleanupPass())
|
||||
compileProject(filename)
|
||||
compileProject()
|
||||
if gCmd != cmdRun:
|
||||
extccomp.CallCCompiler(changeFileExt(filename, ""))
|
||||
extccomp.CallCCompiler(changeFileExt(projectFullPath, ""))
|
||||
|
||||
when has_LLVM_Backend:
|
||||
proc CommandCompileToLLVM(filename: string) =
|
||||
proc CommandCompileToLLVM =
|
||||
semanticPasses()
|
||||
registerPass(llvmgen.llvmgenPass())
|
||||
registerPass(rodwrite.rodwritePass())
|
||||
#registerPass(cleanupPass())
|
||||
compileProject(filename)
|
||||
compileProject()
|
||||
|
||||
proc CommandCompileToEcmaScript(filename: string) =
|
||||
proc CommandCompileToEcmaScript =
|
||||
incl(gGlobalOptions, optSafeCode)
|
||||
setTarget(osEcmaScript, cpuEcmaScript)
|
||||
initDefines()
|
||||
semanticPasses()
|
||||
registerPass(ecmasgenPass())
|
||||
compileProject(filename)
|
||||
compileProject()
|
||||
|
||||
proc CommandInteractive() =
|
||||
proc CommandInteractive =
|
||||
msgs.gErrorMax = high(int) # do not stop after first error
|
||||
incl(gGlobalOptions, optSafeCode)
|
||||
#setTarget(osNimrodVM, cpuNimrodVM)
|
||||
@@ -140,20 +139,22 @@ proc CommandInteractive() =
|
||||
registerPass(verbosePass())
|
||||
registerPass(sem.semPass())
|
||||
registerPass(evals.evalPass()) # load system module:
|
||||
discard CompileModule(options.libpath / addFileExt("system", nimExt),
|
||||
{sfSystemModule})
|
||||
var m = newModule("stdin")
|
||||
m.id = getID()
|
||||
incl(m.flags, sfMainModule)
|
||||
processModule(m, "stdin", LLStreamOpenStdIn(), nil)
|
||||
discard CompileModule(options.libpath /"system", {sfSystemModule})
|
||||
if commandArgs.len > 0:
|
||||
discard CompileModule(mainCommandArg(), {})
|
||||
else:
|
||||
var m = newModule("stdin")
|
||||
m.id = getID()
|
||||
incl(m.flags, sfMainModule)
|
||||
processModule(m, "stdin", LLStreamOpenStdIn(), nil)
|
||||
|
||||
proc CommandPretty(filename: string) =
|
||||
var module = parseFile(addFileExt(filename, NimExt))
|
||||
proc CommandPretty =
|
||||
var module = parseFile(addFileExt(mainCommandArg(), NimExt))
|
||||
if module != nil:
|
||||
renderModule(module, getOutFile(filename, "pretty." & NimExt))
|
||||
renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt))
|
||||
|
||||
proc CommandScan(filename: string) =
|
||||
var f = addFileExt(filename, nimExt)
|
||||
proc CommandScan =
|
||||
var f = addFileExt(mainCommandArg(), nimExt)
|
||||
var stream = LLStreamOpen(f, fmRead)
|
||||
if stream != nil:
|
||||
var
|
||||
@@ -169,107 +170,107 @@ proc CommandScan(filename: string) =
|
||||
else:
|
||||
rawMessage(errCannotOpenFile, f)
|
||||
|
||||
proc CommandSuggest(filename: string) =
|
||||
proc CommandSuggest =
|
||||
msgs.gErrorMax = high(int) # do not stop after first error
|
||||
semanticPasses()
|
||||
registerPass(rodwrite.rodwritePass())
|
||||
compileProject(filename)
|
||||
compileProject()
|
||||
|
||||
proc WantFile(filename: string) =
|
||||
if filename.len == 0:
|
||||
proc wantMainModule =
|
||||
if projectFullPath.len == 0:
|
||||
Fatal(newLineInfo("command line", 1, 1), errCommandExpectsFilename)
|
||||
|
||||
proc MainCommand(cmd, filename: string) =
|
||||
proc MainCommand =
|
||||
appendStr(searchPaths, options.libpath)
|
||||
if filename.len != 0:
|
||||
# current path is always looked first for modules
|
||||
prependStr(searchPaths, splitFile(filename).dir)
|
||||
if projectFullPath.len != 0:
|
||||
# current path is dalways looked first for modules
|
||||
prependStr(searchPaths, projectPath)
|
||||
setID(100)
|
||||
passes.gIncludeFile = syntaxes.parseFile
|
||||
passes.gImportModule = importModule
|
||||
case cmd.normalize
|
||||
case command.normalize
|
||||
of "c", "cc", "compile", "compiletoc":
|
||||
# compile means compileToC currently
|
||||
gCmd = cmdCompileToC
|
||||
wantFile(filename)
|
||||
CommandCompileToC(filename)
|
||||
wantMainModule()
|
||||
CommandCompileToC()
|
||||
of "cpp", "compiletocpp":
|
||||
extccomp.cExt = ".cpp"
|
||||
gCmd = cmdCompileToCpp
|
||||
wantFile(filename)
|
||||
wantMainModule()
|
||||
DefineSymbol("cpp")
|
||||
CommandCompileToC(filename)
|
||||
CommandCompileToC()
|
||||
of "objc", "compiletooc":
|
||||
extccomp.cExt = ".m"
|
||||
gCmd = cmdCompileToOC
|
||||
wantFile(filename)
|
||||
wantMainModule()
|
||||
DefineSymbol("objc")
|
||||
CommandCompileToC(filename)
|
||||
CommandCompileToC()
|
||||
of "run":
|
||||
gCmd = cmdRun
|
||||
wantFile(filename)
|
||||
wantMainModule()
|
||||
when hasTinyCBackend:
|
||||
extccomp.setCC("tcc")
|
||||
CommandCompileToC(filename)
|
||||
CommandCompileToC()
|
||||
else:
|
||||
rawMessage(errInvalidCommandX, cmd)
|
||||
rawMessage(errInvalidCommandX, command)
|
||||
of "js", "compiletoecmascript":
|
||||
gCmd = cmdCompileToEcmaScript
|
||||
wantFile(filename)
|
||||
CommandCompileToEcmaScript(filename)
|
||||
wantMainModule()
|
||||
CommandCompileToEcmaScript()
|
||||
of "compiletollvm":
|
||||
gCmd = cmdCompileToLLVM
|
||||
wantFile(filename)
|
||||
wantMainModule()
|
||||
when has_LLVM_Backend:
|
||||
CommandCompileToLLVM(filename)
|
||||
CommandCompileToLLVM()
|
||||
else:
|
||||
rawMessage(errInvalidCommandX, cmd)
|
||||
rawMessage(errInvalidCommandX, command)
|
||||
of "pretty":
|
||||
gCmd = cmdPretty
|
||||
wantFile(filename)
|
||||
CommandPretty(filename)
|
||||
wantMainModule()
|
||||
CommandPretty()
|
||||
of "doc":
|
||||
gCmd = cmdDoc
|
||||
LoadSpecialConfig(DocConfig)
|
||||
wantFile(filename)
|
||||
CommandDoc(filename)
|
||||
LoadConfigs(DocConfig)
|
||||
wantMainModule()
|
||||
CommandDoc()
|
||||
of "rst2html":
|
||||
gCmd = cmdRst2html
|
||||
LoadSpecialConfig(DocConfig)
|
||||
wantFile(filename)
|
||||
CommandRst2Html(filename)
|
||||
LoadConfigs(DocConfig)
|
||||
wantMainModule()
|
||||
CommandRst2Html()
|
||||
of "rst2tex":
|
||||
gCmd = cmdRst2tex
|
||||
LoadSpecialConfig(DocTexConfig)
|
||||
wantFile(filename)
|
||||
CommandRst2TeX(filename)
|
||||
LoadConfigs(DocTexConfig)
|
||||
wantMainModule()
|
||||
CommandRst2TeX()
|
||||
of "gendepend":
|
||||
gCmd = cmdGenDepend
|
||||
wantFile(filename)
|
||||
CommandGenDepend(filename)
|
||||
wantMainModule()
|
||||
CommandGenDepend()
|
||||
of "dump":
|
||||
gCmd = cmdDump
|
||||
condsyms.ListSymbols()
|
||||
for it in iterSearchPath(): MsgWriteln(it)
|
||||
of "check":
|
||||
gCmd = cmdCheck
|
||||
wantFile(filename)
|
||||
CommandCheck(filename)
|
||||
wantMainModule()
|
||||
CommandCheck()
|
||||
of "parse":
|
||||
gCmd = cmdParse
|
||||
wantFile(filename)
|
||||
discard parseFile(addFileExt(filename, nimExt))
|
||||
wantMainModule()
|
||||
discard parseFile(addFileExt(projectFullPath, nimExt))
|
||||
of "scan":
|
||||
gCmd = cmdScan
|
||||
wantFile(filename)
|
||||
CommandScan(filename)
|
||||
wantMainModule()
|
||||
CommandScan()
|
||||
MsgWriteln("Beware: Indentation tokens depend on the parser\'s state!")
|
||||
of "i":
|
||||
gCmd = cmdInteractive
|
||||
CommandInteractive()
|
||||
of "idetools":
|
||||
gCmd = cmdIdeTools
|
||||
wantFile(filename)
|
||||
CommandSuggest(filename)
|
||||
else: rawMessage(errInvalidCommandX, cmd)
|
||||
wantMainModule()
|
||||
CommandSuggest()
|
||||
else: rawMessage(errInvalidCommandX, command)
|
||||
|
||||
|
||||
@@ -377,7 +377,7 @@ const
|
||||
warnMax* = pred(hintSuccess)
|
||||
hintMin* = hintSuccess
|
||||
hintMax* = high(TMsgKind)
|
||||
|
||||
|
||||
type
|
||||
TNoteKind* = range[warnMin..hintMax] # "notes" are warnings or hints
|
||||
TNoteKinds* = set[TNoteKind]
|
||||
@@ -392,6 +392,7 @@ type
|
||||
|
||||
ERecoverableError* = object of EInvalidValue
|
||||
|
||||
proc newLineInfo*(filename: string, line, col: int): TLineInfo
|
||||
proc raiseRecoverableError*() {.noinline, noreturn.} =
|
||||
raise newException(ERecoverableError, "")
|
||||
|
||||
@@ -401,7 +402,7 @@ var
|
||||
gHintCounter*: int = 0
|
||||
gWarnCounter*: int = 0
|
||||
gErrorMax*: int = 1 # stop after gErrorMax errors
|
||||
|
||||
|
||||
# this format is understood by many text editors: it is the same that
|
||||
# Borland and Freepascal use
|
||||
const
|
||||
@@ -420,6 +421,7 @@ proc UnknownLineInfo*(): TLineInfo =
|
||||
var
|
||||
filenames: seq[tuple[filename: string, fullpath: string]] = @[]
|
||||
msgContext: seq[TLineInfo] = @[]
|
||||
gCmdLineInfo* = newLineInfo("command line", -1, -1)
|
||||
|
||||
proc pushInfoContext*(info: TLineInfo) =
|
||||
msgContext.add(info)
|
||||
|
||||
@@ -204,21 +204,17 @@ proc readConfigFile(filename: string) =
|
||||
if len(condStack) > 0: lexMessage(L, errTokenExpected, "@end")
|
||||
closeLexer(L)
|
||||
if gVerbosity >= 1: rawMessage(hintConf, filename)
|
||||
|
||||
proc getConfigPath(filename: string): string =
|
||||
# try local configuration file:
|
||||
result = joinPath(getConfigDir(), filename)
|
||||
if not ExistsFile(result):
|
||||
# try standard configuration file (installation did not distribute files
|
||||
# the UNIX way)
|
||||
result = joinPath([getPrefixDir(), "config", filename])
|
||||
if not ExistsFile(result): result = "/etc/" & filename
|
||||
|
||||
proc LoadSpecialConfig*(configfilename: string) =
|
||||
if optSkipConfigFile notin gGlobalOptions:
|
||||
readConfigFile(getConfigPath(configfilename))
|
||||
|
||||
proc LoadConfig*(project: string) =
|
||||
proc getUserConfigPath(filename: string): string =
|
||||
result = joinPath(getConfigDir(), filename)
|
||||
|
||||
proc getSystemConfigPath(filename: string): string =
|
||||
# try standard configuration file (installation did not distribute files
|
||||
# the UNIX way)
|
||||
result = joinPath([getPrefixDir(), "config", filename])
|
||||
if not ExistsFile(result): result = "/etc/" & filename
|
||||
|
||||
proc LoadConfigs*(cfg = "nimrod.cfg") =
|
||||
# set default value (can be overwritten):
|
||||
if libpath == "":
|
||||
# choose default libpath:
|
||||
@@ -226,8 +222,14 @@ proc LoadConfig*(project: string) =
|
||||
if (prefix == "/usr"): libpath = "/usr/lib/nimrod"
|
||||
elif (prefix == "/usr/local"): libpath = "/usr/local/lib/nimrod"
|
||||
else: libpath = joinPath(prefix, "lib")
|
||||
LoadSpecialConfig("nimrod.cfg") # read project config file:
|
||||
if optSkipProjConfigFile notin gGlobalOptions and project != "":
|
||||
var conffile = changeFileExt(project, "cfg")
|
||||
if existsFile(conffile): readConfigFile(conffile)
|
||||
|
||||
|
||||
if optSkipConfigFile notin gGlobalOptions:
|
||||
readConfigFile getSystemConfigPath(cfg)
|
||||
|
||||
if optSkipUserConfigFile notin gGlobalOptions:
|
||||
readConfigFile getUserConfigPath(cfg)
|
||||
|
||||
if optSkipProjConfigFile notin gGlobalOptions and projectPath != "":
|
||||
for dir in parentDirs(projectPath, fromRoot = true):
|
||||
readConfigFile(dir/cfg)
|
||||
|
||||
|
||||
@@ -20,9 +20,8 @@ when hasTinyCBackend:
|
||||
var
|
||||
arguments: string = "" # the arguments to be passed to the program that
|
||||
# should be run
|
||||
cmdLineInfo: TLineInfo
|
||||
|
||||
proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
||||
proc ProcessCmdLine(pass: TCmdLinePass) =
|
||||
var p = parseopt.initOptParser()
|
||||
while true:
|
||||
parseopt.next(p)
|
||||
@@ -35,15 +34,19 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
||||
if bracketLe >= 0:
|
||||
var key = substr(p.key, 0, bracketLe - 1)
|
||||
var val = substr(p.key, bracketLe + 1) & ':' & p.val
|
||||
ProcessSwitch(key, val, pass, cmdLineInfo)
|
||||
ProcessSwitch(key, val, pass, gCmdLineInfo)
|
||||
else:
|
||||
ProcessSwitch(p.key, p.val, pass, cmdLineInfo)
|
||||
ProcessSwitch(p.key, p.val, pass, gCmdLineInfo)
|
||||
of cmdArgument:
|
||||
if command == "":
|
||||
command = p.key
|
||||
elif filename == "":
|
||||
filename = unixToNativePath(p.key) # BUGFIX for portable build scripts
|
||||
break
|
||||
if pass == passCmd1:
|
||||
if options.command == "":
|
||||
options.command = p.key
|
||||
else:
|
||||
options.commandArgs.add p.key
|
||||
|
||||
if options.projectName == "":
|
||||
options.projectName = unixToNativePath(p.key) # BUGFIX for portable build scripts
|
||||
|
||||
if pass == passCmd2:
|
||||
arguments = cmdLineRest(p)
|
||||
if optRun notin gGlobalOptions and arguments != "":
|
||||
@@ -55,33 +58,30 @@ proc prependCurDir(f: string): string =
|
||||
else: result = "./" & f
|
||||
else:
|
||||
result = f
|
||||
|
||||
|
||||
proc HandleCmdLine() =
|
||||
var start = epochTime()
|
||||
if paramCount() == 0:
|
||||
writeCommandLineUsage()
|
||||
else:
|
||||
# Process command line arguments:
|
||||
var command = ""
|
||||
var filename = ""
|
||||
ProcessCmdLine(passCmd1, command, filename)
|
||||
if filename != "":
|
||||
var fullpath: string
|
||||
ProcessCmdLine(passCmd1)
|
||||
if projectName != "":
|
||||
try:
|
||||
fullPath = expandFilename(filename)
|
||||
except EOS:
|
||||
fullpath = filename
|
||||
var p = splitFile(fullPath)
|
||||
options.projectPath = p.dir
|
||||
options.projectName = p.name
|
||||
nimconf.LoadConfig(filename) # load the right config file
|
||||
projectFullPath = expandFilename(projectName)
|
||||
except EOS:
|
||||
projectFullPath = projectName
|
||||
var p = splitFile(projectFullPath)
|
||||
projectPath = p.dir
|
||||
projectName = p.name
|
||||
else:
|
||||
projectPath = getCurrentDir()
|
||||
LoadConfigs() # load all config files
|
||||
# now process command line arguments again, because some options in the
|
||||
# command line can overwite the config file's settings
|
||||
extccomp.initVars()
|
||||
command = ""
|
||||
filename = ""
|
||||
ProcessCmdLine(passCmd2, command, filename)
|
||||
MainCommand(command, filename)
|
||||
ProcessCmdLine(passCmd2)
|
||||
MainCommand()
|
||||
if gVerbosity >= 2: echo(GC_getStatistics())
|
||||
if msgs.gErrorCounter == 0:
|
||||
when hasTinyCBackend:
|
||||
@@ -91,11 +91,10 @@ proc HandleCmdLine() =
|
||||
rawMessage(hintSuccessX, [$gLinesCompiled,
|
||||
formatFloat(epochTime() - start, ffDecimal, 3)])
|
||||
if optRun in gGlobalOptions:
|
||||
var ex = quoteIfContainsWhite(changeFileExt(filename, "").prependCurDir)
|
||||
var ex = quoteIfContainsWhite(changeFileExt(projectName, "").prependCurDir)
|
||||
execExternalProgram(ex & ' ' & arguments)
|
||||
|
||||
#GC_disableMarkAndSweep()
|
||||
cmdLineInfo = newLineInfo("command line", -1, -1)
|
||||
condsyms.InitDefines()
|
||||
HandleCmdLine()
|
||||
quit(options.gExitcode)
|
||||
|
||||
@@ -33,6 +33,7 @@ type # please make sure we have under 32 options
|
||||
optSafeCode, # only allow safe code
|
||||
optCDebug, # turn on debugging information
|
||||
optGenDynLib, # generate a dynamic library
|
||||
optGenStaticLib, # generate a static library
|
||||
optGenGuiApp, # generate a GUI application
|
||||
optGenScript, # generate a script file to compile the *.c files
|
||||
optGenMapping, # generate a mapping file
|
||||
@@ -40,6 +41,7 @@ type # please make sure we have under 32 options
|
||||
optSymbolFiles, # use symbol files for speeding up compilation
|
||||
optSkipConfigFile, # skip the general config file
|
||||
optSkipProjConfigFile, # skip the project's config file
|
||||
optSkipUserConfigFile, # skip the users's config file
|
||||
optNoMain, # do not generate a "main" proc
|
||||
optThreads, # support for multi-threading
|
||||
optStdout, # output to stdout
|
||||
@@ -98,11 +100,24 @@ const
|
||||
var
|
||||
gConfigVars* = newStringTable(modeStyleInsensitive)
|
||||
libpath* = ""
|
||||
projectPath* = ""
|
||||
projectName* = ""
|
||||
projectName* = "" # holds a name like `nimrod'
|
||||
projectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/
|
||||
projectFullPath* = "" # projectPath/projectName
|
||||
nimcacheDir* = ""
|
||||
command* = "" # the main command (e.g. cc, check, scan, etc)
|
||||
commandArgs*: seq[string] = @[] # any arguments after the main command
|
||||
gKeepComments*: bool = true # whether the parser needs to keep comments
|
||||
gImplicitMods*: TStringSeq = @[] # modules that are to be implicitly imported
|
||||
implicitImports*: seq[string] = @[] # modules that are to be implicitly imported
|
||||
implicitIncludes*: seq[string] = @[] # modules that are to be implicitly included
|
||||
|
||||
proc mainCommandArg*: string =
|
||||
## This is intended for commands like check or parse
|
||||
## which will work on the main project file unless
|
||||
## explicitly given a specific file argument
|
||||
if commandArgs.len > 0:
|
||||
result = commandArgs[0]
|
||||
else:
|
||||
result = projectName
|
||||
|
||||
proc existsConfigVar*(key: string): bool =
|
||||
result = hasKey(gConfigVars, key)
|
||||
@@ -117,11 +132,6 @@ proc getOutFile*(filename, ext: string): string =
|
||||
if options.outFile != "": result = options.outFile
|
||||
else: result = changeFileExt(filename, ext)
|
||||
|
||||
proc addImplicitMod*(filename: string) =
|
||||
var length = len(gImplicitMods)
|
||||
setlen(gImplicitMods, length + 1)
|
||||
gImplicitMods[length] = filename
|
||||
|
||||
proc getPrefixDir*(): string =
|
||||
## gets the application directory
|
||||
result = SplitPath(getAppDir()).head
|
||||
|
||||
@@ -151,10 +151,24 @@ proc processModule(module: PSym, filename: string, stream: PLLStream,
|
||||
s = stream
|
||||
while true:
|
||||
openParsers(p, filename, s)
|
||||
|
||||
if sfSystemModule notin module.flags:
|
||||
template processImplicits(implicits, nodeKind: expr): stmt =
|
||||
for module in items(implicits):
|
||||
var importStmt = newNodeI(nodeKind, gCmdLineInfo)
|
||||
var str = newStrNode(nkStrLit, module)
|
||||
str.info = gCmdLineInfo
|
||||
importStmt.addSon str
|
||||
processTopLevelStmt importStmt, a
|
||||
|
||||
processImplicits implicitImports, nkImportStmt
|
||||
processImplicits implicitIncludes, nkIncludeStmt
|
||||
|
||||
while true:
|
||||
var n = parseTopLevelStmt(p)
|
||||
if n.kind == nkEmpty: break
|
||||
processTopLevelStmt(n, a)
|
||||
|
||||
closeParsers(p)
|
||||
if s.kind != llsStdIn: break
|
||||
closePasses(a)
|
||||
|
||||
@@ -285,14 +285,16 @@ proc magicCall(m: PSym, n: PNode): PNode =
|
||||
b = nil
|
||||
result = evalOp(s.magic, n, a, b, c)
|
||||
|
||||
proc getAppType(n: PNode): PNode =
|
||||
proc getAppType(n: PNode): PNode =
|
||||
if gGlobalOptions.contains(optGenDynLib):
|
||||
result = newStrNodeT("lib", n)
|
||||
elif gGlobalOptions.contains(optGenStaticLib):
|
||||
result = newStrNodeT("staticlib", n)
|
||||
elif gGlobalOptions.contains(optGenGuiApp):
|
||||
result = newStrNodeT("gui", n)
|
||||
else:
|
||||
result = newStrNodeT("console", n)
|
||||
|
||||
|
||||
proc foldConv*(n, a: PNode): PNode =
|
||||
case skipTypes(n.typ, abstractRange).kind
|
||||
of tyInt..tyInt64:
|
||||
|
||||
@@ -14,9 +14,10 @@ Advanced commands:
|
||||
--track:FILE,LINE,COL track a file/cursor position
|
||||
--suggest suggest all possible symbols at position
|
||||
--def list all possible symbols at position
|
||||
--context list possible invokation context
|
||||
--context list possible invokation context
|
||||
|
||||
Advanced options:
|
||||
-m, --mainmodule:FILE set the project main module
|
||||
-o, --out:FILE set the output filename
|
||||
--stdout output to stdout
|
||||
-w, --warnings:on|off turn all warnings on|off
|
||||
@@ -25,6 +26,8 @@ Advanced options:
|
||||
--hint[X]:on|off turn specific hint X on|off
|
||||
--recursivePath:PATH add a path and all of its subdirectories
|
||||
--lib:PATH set the system library path
|
||||
--import:PATH add an automatically imported module
|
||||
--include:PATH add an automatically included module
|
||||
--nimcache:PATH set the path used for generated files
|
||||
-c, --compileOnly compile only; do not assemble or link
|
||||
--noLinking compile but do not link
|
||||
@@ -37,6 +40,10 @@ Advanced options:
|
||||
--debugger:on|off turn Embedded Nimrod Debugger on|off
|
||||
-t, --passc:OPTION pass an option to the C compiler
|
||||
-l, --passl:OPTION pass an option to the linker
|
||||
--cincludes:DIR modify the C compiler header search path
|
||||
--clibdir:DIR modify the linker library search path
|
||||
--clib:LIBNAME link an additional C library
|
||||
(you should omit platform-specific extensions)
|
||||
--genMapping generate a mapping file containing
|
||||
(Nimrod, mangled) identifier pairs
|
||||
--lineDir:on|off generation of #line directive on|off
|
||||
@@ -46,6 +53,7 @@ Advanced options:
|
||||
--symbolFiles:on|off turn symbol files on|off (experimental)
|
||||
--skipCfg do not read the general configuration file
|
||||
--skipProjCfg do not read the project's configuration file
|
||||
--skipUserCfg do not read the user's configuration file
|
||||
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
||||
--index:FILE use FILE to generate a documentation index file
|
||||
--putenv:key=value set an environment variable
|
||||
|
||||
@@ -28,7 +28,8 @@ Options:
|
||||
--infChecks:on|off turn Inf checks on|off
|
||||
--deadCodeElim:on|off whole program dead code elimination on|off
|
||||
--opt:none|speed|size optimize not at all or for speed|size
|
||||
--app:console|gui|lib generate a console|GUI application|dynamic library
|
||||
--app:console|gui|lib|staticlib
|
||||
generate a console app|GUI app|DLL|static library
|
||||
-r, --run run the compiled program with given arguments
|
||||
--advanced show advanced command line switches
|
||||
-h, --help show this help
|
||||
|
||||
@@ -408,6 +408,36 @@ proc parentDir*(path: string): string {.
|
||||
else:
|
||||
result = path
|
||||
|
||||
proc isRootDir*(path: string): bool {.
|
||||
noSideEffect, rtl, extern: "nos$1".} =
|
||||
## Checks whether a given `path` is a root directory
|
||||
var p = parentDir(path)
|
||||
result = p == path or p.len == 0
|
||||
|
||||
iterator parentDirs*(path: string, fromRoot = false, inclusive = true): string =
|
||||
## Walks over all parent directories of a given `path`
|
||||
##
|
||||
## If `fromRoot` is set, the traversal will start from the file system root
|
||||
## diretory. If `inclusive` is set, the original argument will be included
|
||||
## in the traversal.
|
||||
##
|
||||
## Relative paths won't be expanded by this proc. Instead, it will traverse
|
||||
## only the directories appearing in the relative path.
|
||||
if not fromRoot:
|
||||
var current = path
|
||||
if inclusive: yield path
|
||||
while true:
|
||||
if current.isRootDir: break
|
||||
current = current.parentDir
|
||||
yield current
|
||||
else:
|
||||
for i in countup(0, path.len - 2): # ignore the last /
|
||||
# deal with non-normalized paths such as /foo//bar//baz
|
||||
if path[i] in {dirsep, altsep} and (i == 0 or path[i-1] notin {dirsep, altsep}):
|
||||
yield path.substr(0, i)
|
||||
|
||||
if inclusive: yield path
|
||||
|
||||
proc `/../` * (head, tail: string): string {.noSideEffect.} =
|
||||
## The same as ``parentDir(head) / tail``
|
||||
return parentDir(head) / tail
|
||||
@@ -522,7 +552,7 @@ proc cmpPaths*(pathA, pathB: string): int {.
|
||||
result = cmpIgnoreCase(pathA, pathB)
|
||||
|
||||
proc isAbsolute*(path: string): bool {.rtl, noSideEffect, extern: "nos$1".} =
|
||||
## Checks whether a given path is absolute.
|
||||
## Checks whether a given `path` is absolute.
|
||||
##
|
||||
## on Windows, network paths are considered absolute too.
|
||||
when doslike:
|
||||
|
||||
16
web/news.txt
16
web/news.txt
@@ -46,6 +46,7 @@ Changes affecting backwards compatibility
|
||||
raise hooks.
|
||||
- Changed exception handling/error reporting for ``os.removeFile`` and
|
||||
``os.removeDir``.
|
||||
- The algorithm for searching and loading configuration files have been changed
|
||||
- Operators now have diffent precedence rules: Assignment-like operators
|
||||
(like ``*=``) are now special-cased.
|
||||
- The fields in ``TStream`` have been renamed to have an ``Impl`` suffix
|
||||
@@ -85,6 +86,15 @@ Compiler Additions
|
||||
and Objective C somewhat easier.
|
||||
- Added a ``--nimcache:PATH`` configuration option for control over the output
|
||||
directory for generated code.
|
||||
- Added ``--cincludes:dir``, ``--clibdir:lib`` configuration options for
|
||||
modifying the C compiler's header/library search path in cross-platform way.
|
||||
- Added ``--clib:lib`` configuration options for specifying additional
|
||||
C libraries to be linked.
|
||||
- Added ``--mainmodule:file`` configuration options for specifying the main
|
||||
project file. This is intended to be used in project configuration files to
|
||||
allow commands like ``nimrod c`` or ``nimrod check`` to be executed anywhere
|
||||
within the project's directory structure
|
||||
- Added a ``--app:staticlib`` option for creating static libraries
|
||||
- Added a ``--tlsEmulation:on|off`` switch for control over thread local
|
||||
storage emulation.
|
||||
- The compiler and standard library now support a *taint mode*. Input strings
|
||||
@@ -94,6 +104,9 @@ Compiler Additions
|
||||
- The compiler now supports the compilation cache via ``--symbolFiles:on``.
|
||||
This potentially speeds up compilations by an order of magnitude, but is
|
||||
still highly experimental!
|
||||
- Added ``--import:file`` and ``--include:file`` configuration options
|
||||
for specifying modules that will be automatically imported/incluced.
|
||||
- ``nimrod i`` can now optionally be given a module to execute.
|
||||
|
||||
|
||||
Library Additions
|
||||
@@ -110,7 +123,8 @@ Library Additions
|
||||
- Added ``system.running`` for threads.
|
||||
- Added ``system.program_result``.
|
||||
- Added ``xmltree.innerText``.
|
||||
- Added ``os.isAbsolute``, ``os.dynLibFormat``.
|
||||
- Added ``os.isAbsolute``, ``os.dynLibFormat``, ``os.isRootDir``,
|
||||
``os.parentDirs``.
|
||||
- Added ``parseutils.interpolatedFragments``.
|
||||
- Added ``macros.treeRepr``, ``macros.lispRepr``, ``macros.dumpTree``,
|
||||
``macros.dumpLisp``, ``macros.parseExpr``, ``macros.parseStmt``,
|
||||
|
||||
Reference in New Issue
Block a user