diff options
Diffstat (limited to 'compiler/options.nim')
-rw-r--r-- | compiler/options.nim | 188 |
1 files changed, 98 insertions, 90 deletions
diff --git a/compiler/options.nim b/compiler/options.nim index c9334991a..a95d9930a 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -9,7 +9,7 @@ import os, strutils, strtabs, osproc, sets, lineinfos, platform, - prefixmatches + prefixmatches, pathutils from terminal import isatty from times import utc, fromUnix, local, getTime, format, DateTime @@ -121,7 +121,8 @@ type notnil, dynamicBindSym, forLoopMacros, - caseStmtMacros + caseStmtMacros, + codeReordering, SymbolFilesOption* = enum disabledSf, writeOnlySf, readOnlySf, v2Sf @@ -135,7 +136,7 @@ type External ## file was introduced via .compile pragma Cfile* = object - cname*, obj*: string + cname*, obj*: AbsoluteFile flags*: set[CFileFlag] CfileList* = seq[Cfile] @@ -203,13 +204,14 @@ type ## symbols are always guaranteed to be style ## insensitive. Otherwise hell would break lose. packageCache*: StringTableRef - searchPaths*: seq[string] - lazyPaths*: seq[string] - outFile*, prefixDir*, libpath*, nimcacheDir*: string + searchPaths*: seq[AbsoluteDir] + lazyPaths*: seq[AbsoluteDir] + outFile*: AbsoluteFile + prefixDir*, libpath*, nimcacheDir*: AbsoluteDir dllOverrides, moduleOverrides*: StringTableRef projectName*: string # holds a name like 'nim' - projectPath*: string # holds a path like /home/alice/projects/nim/compiler/ - projectFull*: string # projectPath/projectName + projectPath*: AbsoluteDir # holds a path like /home/alice/projects/nim/compiler/ + projectFull*: AbsoluteFile # projectPath/projectName projectIsStdin*: bool # whether we're compiling from stdin projectMainIdx*: FileIndex # the canonical path id of the main module command*: string # the main command (e.g. cc, check, scan, etc) @@ -221,9 +223,9 @@ type # The string uses the formatting variables `path` and `line`. # the used compiler - cIncludes*: seq[string] # directories to search for included files - cLibs*: seq[string] # directories to search for lib files - cLinkedLibs*: seq[string] # libraries to link + cIncludes*: seq[AbsoluteDir] # directories to search for included files + cLibs*: seq[AbsoluteDir] # directories to search for lib files + cLinkedLibs*: seq[string] # libraries to link externalToLink*: seq[string] # files to link in addition to the file # we compiled (*) @@ -302,12 +304,13 @@ proc newConfigRef*(): ConfigRef = packageCache: newPackageCache(), searchPaths: @[], lazyPaths: @[], - outFile: "", prefixDir: "", libpath: "", nimcacheDir: "", + outFile: AbsoluteFile"", prefixDir: AbsoluteDir"", + libpath: AbsoluteDir"", nimcacheDir: AbsoluteDir"", dllOverrides: newStringTable(modeCaseInsensitive), moduleOverrides: newStringTable(modeStyleInsensitive), projectName: "", # holds a name like 'nim' - projectPath: "", # holds a path like /home/alice/projects/nim/compiler/ - projectFull: "", # projectPath/projectName + projectPath: AbsoluteDir"", # holds a path like /home/alice/projects/nim/compiler/ + projectFull: AbsoluteFile"", # projectPath/projectName projectIsStdin: false, # whether we're compiling from stdin projectMainIdx: FileIndex(0'i32), # the canonical path id of the main module command: "", # the main command (e.g. cc, check, scan, etc) @@ -401,7 +404,7 @@ template optPreserveOrigSource*(conf: ConfigRef): untyped = optEmbedOrigSrc in conf.globalOptions const - genSubDir* = "nimcache" + genSubDir* = RelativeDir"nimcache" NimExt* = "nim" RodExt* = "rod" HtmlExt* = "html" @@ -409,10 +412,10 @@ const TagsExt* = "tags" TexExt* = "tex" IniExt* = "ini" - DefaultConfig* = "nim.cfg" - DefaultConfigNims* = "config.nims" - DocConfig* = "nimdoc.cfg" - DocTexConfig* = "nimdoc.tex.cfg" + DefaultConfig* = RelativeFile"nim.cfg" + DefaultConfigNims* = RelativeFile"config.nims" + DocConfig* = RelativeFile"nimdoc.cfg" + DocTexConfig* = RelativeFile"nimdoc.tex.cfg" const oKeepVariableNames* = true @@ -437,56 +440,61 @@ proc getConfigVar*(conf: ConfigRef; key: string, default = ""): string = proc setConfigVar*(conf: ConfigRef; key, val: string) = conf.configVars[key] = val -proc getOutFile*(conf: ConfigRef; filename, ext: string): string = - if conf.outFile != "": result = conf.outFile - else: result = changeFileExt(filename, ext) +proc getOutFile*(conf: ConfigRef; filename: RelativeFile, ext: string): AbsoluteFile = + if not conf.outFile.isEmpty: result = conf.outFile + else: result = conf.projectPath / changeFileExt(filename, ext) -proc getPrefixDir*(conf: ConfigRef): string = +proc getPrefixDir*(conf: ConfigRef): AbsoluteDir = ## Gets the prefix dir, usually the parent directory where the binary resides. ## ## This is overridden by some tools (namely nimsuggest) via the ``conf.prefixDir`` - ## global. - if conf.prefixDir != "": result = conf.prefixDir - else: result = splitPath(getAppDir()).head + ## field. + if not conf.prefixDir.isEmpty: result = conf.prefixDir + else: result = AbsoluteDir splitPath(getAppDir()).head proc setDefaultLibpath*(conf: ConfigRef) = # set default value (can be overwritten): - if conf.libpath == "": + if conf.libpath.isEmpty: # choose default libpath: var prefix = getPrefixDir(conf) when defined(posix): - if prefix == "/usr": conf.libpath = "/usr/lib/nim" - elif prefix == "/usr/local": conf.libpath = "/usr/local/lib/nim" - else: conf.libpath = joinPath(prefix, "lib") - else: conf.libpath = joinPath(prefix, "lib") + if prefix == AbsoluteDir"/usr": + conf.libpath = AbsoluteDir"/usr/lib/nim" + elif prefix == AbsoluteDir"/usr/local": + conf.libpath = AbsoluteDir"/usr/local/lib/nim" + else: + conf.libpath = prefix / RelativeDir"lib" + else: + conf.libpath = prefix / RelativeDir"lib" # Special rule to support other tools (nimble) which import the compiler # modules and make use of them. let realNimPath = findExe("nim") # Find out if $nim/../../lib/system.nim exists. let parentNimLibPath = realNimPath.parentDir.parentDir / "lib" - if not fileExists(conf.libpath / "system.nim") and + if not fileExists(conf.libpath.string / "system.nim") and fileExists(parentNimlibPath / "system.nim"): - conf.libpath = parentNimLibPath + conf.libpath = AbsoluteDir parentNimLibPath -proc canonicalizePath*(conf: ConfigRef; path: string): string = +proc canonicalizePath*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile = # on Windows, 'expandFilename' calls getFullPathName which doesn't do # case corrections, so we have to use this convoluted way of retrieving # the true filename (see tests/modules and Nimble uses 'import Uri' instead # of 'import uri'): when defined(windows): - result = path.expandFilename - for x in walkFiles(result): - return x + result = AbsoluteFile path.string.expandFilename + for x in walkFiles(result.string): + return AbsoluteFile x else: - result = path.expandFilename + result = AbsoluteFile path.string.expandFilename -proc shortenDir*(conf: ConfigRef; dir: string): string = +proc shortenDir*(conf: ConfigRef; dir: string): string {. + deprecated: "use 'relativeTo' instead".} = ## returns the interesting part of a dir - var prefix = conf.projectPath & DirSep + var prefix = conf.projectPath.string & DirSep if startsWith(dir, prefix): return substr(dir, len(prefix)) - prefix = getPrefixDir(conf) & DirSep + prefix = getPrefixDir(conf).string & DirSep if startsWith(dir, prefix): return substr(dir, len(prefix)) result = dir @@ -507,89 +515,89 @@ proc getOsCacheDir(): string = when defined(posix): result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim" else: - result = getHomeDir() / genSubDir + result = getHomeDir() / genSubDir.string -proc getNimcacheDir*(conf: ConfigRef): string = +proc getNimcacheDir*(conf: ConfigRef): AbsoluteDir = # XXX projectName should always be without a file extension! - result = if conf.nimcacheDir.len > 0: + result = if not conf.nimcacheDir.isEmpty: conf.nimcacheDir elif conf.cmd == cmdCompileToJS: - shortenDir(conf, conf.projectPath) / genSubDir - else: getOsCacheDir() / splitFile(conf.projectName).name & - (if isDefined(conf, "release"): "_r" else: "_d") + conf.projectPath / genSubDir + else: + AbsoluteDir(getOsCacheDir() / splitFile(conf.projectName).name & + (if isDefined(conf, "release"): "_r" else: "_d")) proc pathSubs*(conf: ConfigRef; p, config: string): string = let home = removeTrailingDirSep(os.getHomeDir()) result = unixToNativePath(p % [ - "nim", getPrefixDir(conf), - "lib", conf.libpath, + "nim", getPrefixDir(conf).string, + "lib", conf.libpath.string, "home", home, "config", config, "projectname", conf.projectName, - "projectpath", conf.projectPath, - "projectdir", conf.projectPath, - "nimcache", getNimcacheDir(conf)]) + "projectpath", conf.projectPath.string, + "projectdir", conf.projectPath.string, + "nimcache", getNimcacheDir(conf).string]) if "~/" in result: result = result.replace("~/", home & '/') -proc toGeneratedFile*(conf: ConfigRef; path, ext: string): string = +proc toGeneratedFile*(conf: ConfigRef; path: AbsoluteFile, + ext: string): AbsoluteFile = ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod" - var (head, tail) = splitPath(path) - #if len(head) > 0: head = shortenDir(head & dirSep) - result = joinPath([getNimcacheDir(conf), changeFileExt(tail, ext)]) - #echo "toGeneratedFile(", path, ", ", ext, ") = ", result - -proc completeGeneratedFilePath*(conf: ConfigRef; f: string, createSubDir: bool = true): string = - var (head, tail) = splitPath(f) - #if len(head) > 0: head = removeTrailingDirSep(shortenDir(head & dirSep)) - var subdir = getNimcacheDir(conf) # / head + let (head, tail) = splitPath(path.string) + result = getNimcacheDir(conf) / RelativeFile changeFileExt(tail, ext) + +proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile, + createSubDir: bool = true): AbsoluteFile = + let (head, tail) = splitPath(f.string) + let subdir = getNimcacheDir(conf) if createSubDir: try: - createDir(subdir) + createDir(subdir.string) except OSError: - writeLine(stdout, "cannot create directory: " & subdir) + writeLine(stdout, "cannot create directory: " & subdir.string) quit(1) - result = joinPath(subdir, tail) + result = subdir / RelativeFile tail #echo "completeGeneratedFilePath(", f, ") = ", result -proc rawFindFile(conf: ConfigRef; f: string; suppressStdlib: bool): string = +proc rawFindFile(conf: ConfigRef; f: RelativeFile; suppressStdlib: bool): AbsoluteFile = for it in conf.searchPaths: - if suppressStdlib and it.startsWith(conf.libpath): + if suppressStdlib and it.string.startsWith(conf.libpath.string): continue - result = joinPath(it, f) - if existsFile(result): + result = it / f + if fileExists(result): return canonicalizePath(conf, result) - result = "" + result = AbsoluteFile"" -proc rawFindFile2(conf: ConfigRef; f: string): string = +proc rawFindFile2(conf: ConfigRef; f: RelativeFile): AbsoluteFile = for i, it in conf.lazyPaths: - result = joinPath(it, f) - if existsFile(result): + result = it / f + if fileExists(result): # bring to front for j in countDown(i,1): swap(conf.lazyPaths[j], conf.lazyPaths[j-1]) return canonicalizePath(conf, result) - result = "" + result = AbsoluteFile"" template patchModule(conf: ConfigRef) {.dirty.} = - if result.len > 0 and conf.moduleOverrides.len > 0: - let key = getPackageName(conf, result) & "_" & splitFile(result).name + if not result.isEmpty and conf.moduleOverrides.len > 0: + let key = getPackageName(conf, result.string) & "_" & splitFile(result).name if conf.moduleOverrides.hasKey(key): let ov = conf.moduleOverrides[key] - if ov.len > 0: result = ov + if ov.len > 0: result = AbsoluteFile(ov) -proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): string {.procvar.} = +proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): AbsoluteFile {.procvar.} = if f.isAbsolute: - result = if f.existsFile: f else: "" + result = if f.existsFile: AbsoluteFile(f) else: AbsoluteFile"" else: - result = rawFindFile(conf, f, suppressStdlib) - if result.len == 0: - result = rawFindFile(conf, f.toLowerAscii, suppressStdlib) - if result.len == 0: - result = rawFindFile2(conf, f) - if result.len == 0: - result = rawFindFile2(conf, f.toLowerAscii) + result = rawFindFile(conf, RelativeFile f, suppressStdlib) + if result.isEmpty: + result = rawFindFile(conf, RelativeFile f.toLowerAscii, suppressStdlib) + if result.isEmpty: + result = rawFindFile2(conf, RelativeFile f) + if result.isEmpty: + result = rawFindFile2(conf, RelativeFile f.toLowerAscii) patchModule(conf) const stdlibDirs = [ @@ -599,7 +607,7 @@ const stdlibDirs = [ "wrappers", "wrappers/linenoise", "windows", "posix", "js"] -proc findModule*(conf: ConfigRef; modulename, currentModule: string): string = +proc findModule*(conf: ConfigRef; modulename, currentModule: string): AbsoluteFile = # returns path to module const pkgPrefix = "pkg/" const stdPrefix = "std/" @@ -610,13 +618,13 @@ proc findModule*(conf: ConfigRef; modulename, currentModule: string): string = if m.startsWith(stdPrefix): let stripped = m.substr(stdPrefix.len) for candidate in stdlibDirs: - let path = (conf.libpath / candidate / stripped) + let path = (conf.libpath.string / candidate / stripped) if fileExists(path): m = path break let currentPath = currentModule.splitFile.dir - result = currentPath / m - if not existsFile(result): + result = AbsoluteFile currentPath / m + if not fileExists(result): result = findFile(conf, m) patchModule(conf) |