No more includes in build

This commit is contained in:
Ganesh Viswanathan 2020-06-24 12:24:15 -05:00
commit 63a75bce4e
15 changed files with 144 additions and 161 deletions

View file

@ -1,130 +1,39 @@
import hashes, osproc, sets, strformat, strutils
when not defined(TOAST):
import macros, tables
import os except findExe, sleep
import os except findExe, sleep
else:
import os
export extractFilename, `/`
# build specific debug since we cannot import globals (yet)
var
gDebug* = false
gDebugCT* {.compileTime.} = false
gNimExe* = ""
# Misc helpers
proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string =
result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)])
if not noQuote:
result = result.quoteShell
proc getCurrentNimCompiler*(): string =
when nimvm:
result = getCurrentCompilerExe()
when defined(nimsuggest):
result = result.replace("nimsuggest", "nim")
else:
result = gNimExe
template fixOutDir() {.dirty, used.} =
let
outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir
proc compareVersions*(ver1, ver2: string): int =
## Compare two version strings x.y.z and return -1, 0, 1
##
## ver1 < ver2 = -1
## ver1 = ver2 = 0
## ver1 > ver2 = 1
let
ver1seq = ver1.replace("-", "").split('.')
ver2seq = ver2.replace("-", "").split('.')
for i in 0 ..< ver1seq.len:
let
p1 = ver1seq[i]
p2 = if i < ver2seq.len: ver2seq[i] else: "0"
try:
let
h1 = p1.parseHexInt()
h2 = p2.parseHexInt()
if h1 < h2: return -1
elif h1 > h2: return 1
except ValueError:
if p1 < p2: return -1
elif p1 > p2: return 1
proc fixCmd(cmd: string): string =
when defined(Windows):
# Replace 'cd d:\abc' with 'd: && cd d:\abc`
var filteredCmd = cmd
if cmd.toLower().startsWith("cd"):
var
colonIndex = cmd.find(":")
driveLetter = cmd.substr(colonIndex-1, colonIndex)
if (driveLetter[0].isAlphaAscii() and
driveLetter[1] == ':' and
colonIndex == 4):
filteredCmd = &"{driveLetter} && {cmd}"
result = "cmd /c " & filteredCmd
elif defined(posix):
result = cmd
else:
doAssert false
import "."/build/misc
export misc
# Nim cfg file related functionality
include "."/build/nimconf
proc getNimteropCacheDir(): string =
# Get location to cache all nimterop artifacts
result = getNimcacheDir() / "nimterop"
import "."/build/nimconf
export nimconf
# Functionality shelled out to external executables
include "."/build/shell
proc getProjectCacheDir*(name: string, forceClean = true): string =
## Get a cache directory where all nimterop artifacts can be stored
##
## Projects can use this location to download source code and build binaries
## that can be then accessed by multiple apps. This is created under the
## per-user Nim cache directory.
##
## Use `name` to specify the subdirectory name for a project.
##
## `forceClean` is enabled by default and effectively deletes the folder
## if Nim is compiled with the `-f` or `--forceBuild` flag. This allows
## any project to start out with a clean cache dir on a forced build.
##
## NOTE: avoid calling `getProjectCacheDir()` multiple times on the same
## `name` when `forceClean = true` else checked out source might get deleted
## at the wrong time during build.
##
## E.g.
## `nimgit2` downloads `libgit2` source so `name = "libgit2"`
##
## `nimarchive` downloads `libarchive`, `bzlib`, `liblzma` and `zlib` so
## `name = "nimarchive" / "libarchive"` for `libarchive`, etc.
result = getNimteropCacheDir() / name
if forceClean and compileOption("forceBuild"):
echo "# Removing " & result
rmDir(result)
import "."/build/shell
export shell
# C compiler support
include "."/build/ccompiler
import "."/build/ccompiler
export ccompiler
when not defined(TOAST):
# configure, cmake, make support
include "."/build/tools
import "."/build/tools
export tools
# Conan.io support
include "."/build/conan
import "."/build/conan
export conan
# Julia BinaryBuilder.org support
include "."/build/jbb
import "."/build/jbb
export jbb
# getHeader support
include "."/build/getheader
import "."/build/getheader
export getheader

View file

@ -1,5 +1,7 @@
import os, strformat, strutils
import "."/shell
proc getCompilerMode*(path: string): string =
## Determines a target language mode from an input filename, if one is not already specified.
let file = path.splitFile()

View file

@ -1,5 +1,7 @@
import os, strformat, strutils, tables
import "."/[ccompiler, misc, nimconf, shell]
when (NimMajor, NimMinor, NimPatch) < (1, 2, 0):
import marshal
else:
@ -77,6 +79,10 @@ proc jsonGet(url: string): JsonNode =
discard
rmFile(file)
template fixOutDir() {.dirty.} =
let
outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir
proc `==`*(pkg1, pkg2: ConanPackage): bool =
## Check if two ConanPackage objects are equal
(not pkg1.isNil and not pkg2.isNil and

View file

@ -1,4 +1,9 @@
import macros, os, strutils, tables
import macros, strformat, strutils, tables
import os except findExe
import ".."/globals
import "."/[ccompiler, conan, jbb, nimconf, shell, tools]
var
gDefines {.compileTime.} = initTable[string, string]()

View file

@ -1,5 +1,7 @@
import json, os, strformat, strutils, tables
import "."/[ccompiler, nimconf, shell]
when (NimMajor, NimMinor, NimPatch) < (1, 2, 0):
import marshal
@ -27,6 +29,10 @@ var
# Reuse dependencies already downloaded
gJBBRequires {.compileTime.}: Table[string, JBBPackage]
template fixOutDir() {.dirty.} =
let
outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir
proc `==`*(pkg1, pkg2: JBBPackage): bool =
## Check if two JBBPackage objects are equal
(not pkg1.isNil and not pkg2.isNil and

View file

@ -1,5 +1,7 @@
import json, os, osproc, sets, strformat, strutils
import "."/misc
when nimvm:
when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0):
import std/compilesettings
@ -227,3 +229,7 @@ proc getOutDir*(projectDir = ""): string =
let
cfg = getNimConfig(projectDir)
result = cfg.outDir
proc getNimteropCacheDir*(): string =
## Get location to cache all nimterop artifacts
result = getNimcacheDir() / "nimterop"

View file

@ -1,15 +1,25 @@
import os, strformat, strutils
import hashes, osproc, sets, strformat, strutils
proc sleep*(milsecs: int) =
## Sleep at compile time
let
cmd =
when defined(Windows):
"cmd /c timeout "
else:
"sleep "
when not defined(TOAST):
import os except findExe, sleep
else:
import os
discard gorgeEx(cmd & $(milsecs / 1000))
import "."/[misc, nimconf]
when not defined(TOAST):
proc sleep*(milsecs: int) =
## Sleep at compile time
let
cmd =
when defined(Windows):
"cmd /c timeout "
else:
"sleep "
discard gorgeEx(cmd & $(milsecs / 1000))
else:
export sleep
proc execAction*(cmd: string, retry = 0, die = true, cache = false,
cacheKey = "", onRetry: proc() = nil): tuple[output: string, ret: int] =
@ -73,20 +83,23 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false,
doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd &
"\nresult:\n" & result.output
proc findExe*(exe: string): string =
## Find the specified executable using the `which`/`where` command - supported
## at compile time
var
cmd =
when defined(Windows):
"where " & exe
else:
"which " & exe
when not defined(TOAST):
proc findExe*(exe: string): string =
## Find the specified executable using the `which`/`where` command - supported
## at compile time
var
cmd =
when defined(Windows):
"where " & exe
else:
"which " & exe
(output, ret) = execAction(cmd, die = false)
(output, ret) = execAction(cmd, die = false)
if ret == 0:
return output.splitLines()[0].strip().sanitizePath
if ret == 0:
return output.splitLines()[0].strip().sanitizePath
else:
export findExe
proc mkDir*(dir: string) =
## Create a directory at compile time
@ -465,3 +478,31 @@ proc getNumProcs*(): string =
execAction("sysctl -n hw.ncpu").output.strip()
else:
"1"
proc getProjectCacheDir*(name: string, forceClean = true): string =
## Get a cache directory where all nimterop artifacts can be stored
##
## Projects can use this location to download source code and build binaries
## that can be then accessed by multiple apps. This is created under the
## per-user Nim cache directory.
##
## Use `name` to specify the subdirectory name for a project.
##
## `forceClean` is enabled by default and effectively deletes the folder
## if Nim is compiled with the `-f` or `--forceBuild` flag. This allows
## any project to start out with a clean cache dir on a forced build.
##
## NOTE: avoid calling `getProjectCacheDir()` multiple times on the same
## `name` when `forceClean = true` else checked out source might get deleted
## at the wrong time during build.
##
## E.g.
## `nimgit2` downloads `libgit2` source so `name = "libgit2"`
##
## `nimarchive` downloads `libarchive`, `bzlib`, `liblzma` and `zlib` so
## `name = "nimarchive" / "libarchive"` for `libarchive`, etc.
result = getNimteropCacheDir() / name
if forceClean and compileOption("forceBuild"):
echo "# Removing " & result
rmDir(result)

View file

@ -1,20 +1,16 @@
import os, strformat, strutils
import strformat, strutils
type
BuildType* = enum
btAutoconf, btCmake
import os except findExe
BuildStatus = object
built: bool
buildPath: string
error: string
import ".."/globals
import "."/[misc, shell]
proc echoDebug(str: string) =
let str = "\n# " & str.strip().replace("\n", "\n# ")
when nimvm:
if gDebugCT: echo str
when defined(TOAST):
if gState.debug: echo str
else:
if gDebug: echo str
if gStateCT.debug: echo str
proc configure*(path, check: string, flags = "") =
## Run the GNU `configure` command to generate all Makefiles or other
@ -208,7 +204,7 @@ proc make*(path, check: string, flags = "", regex = false) =
doAssert findFile(check, path, regex = regex).len != 0, "make failed"
proc buildWithCmake(outdir, flags: string): BuildStatus =
proc buildWithCmake*(outdir, flags: string): BuildStatus =
if not fileExists(outdir / "Makefile"):
if fileExists(outdir / "CMakeLists.txt"):
if findExe("cmake").len != 0:
@ -238,7 +234,7 @@ proc buildWithCmake(outdir, flags: string): BuildStatus =
else:
result.buildPath = outdir
proc buildWithAutoConf(outdir, flags: string): BuildStatus =
proc buildWithAutoConf*(outdir, flags: string): BuildStatus =
if not fileExists(outdir / "Makefile"):
if findExe("bash").len != 0:
for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]:

View file

@ -376,7 +376,6 @@ proc cSearchPath*(path: string): string {.compileTime.}=
proc cDebug*() {.compileTime.} =
## Enable debug messages and display the generated Nim code
gStateCT.debug = true
build.gDebugCT = true
proc cDisableCaching*() {.compileTime.} =
## Disable caching of generated Nim code - useful during wrapper development

View file

@ -7,7 +7,7 @@ when defined(TOAST):
import compiler/[ast, idents, modulegraphs, options]
import "."/treesitter/api
# import "."/treesitter/api
type
Feature* = enum
@ -78,6 +78,21 @@ type
pluginSource*: string # `cPlugin()` generated code to write to plugin file from
searchDirs*: seq[string] # `cSearchPath()` added directories for header search
BuildType* = enum
btAutoconf, btCmake
BuildStatus* = object
built*: bool
buildPath*: string
error*: string
when nimvm:
var
gStateCT* {.compileTime, used.} = new(State)
else:
var
gState*: State
when defined(TOAST):
const
gAtoms* {.used.} = @[
@ -119,9 +134,6 @@ when defined(TOAST):
template decho*(args: varargs[string, `$`]): untyped =
if gState.debug:
gecho join(args, "").getCommented()
else:
var
gStateCT* {.compileTime, used.} = new(State)
template nBl*(s: typed): untyped {.used.} =
(s.len != 0)

View file

@ -1,6 +1,6 @@
import os
import "."/build
import "."/build/shell
const
cacheDir* = getProjectCacheDir("nimterop", forceClean = false)

View file

@ -1,6 +1,7 @@
import os, strutils
import "."/[build, paths]
import "."/[paths]
import "."/build/[shell]
proc treesitterSetup*() =
gitPull("https://github.com/tree-sitter/tree-sitter", cacheDir / "treesitter", """

View file

@ -2,10 +2,12 @@ import os, osproc, sets, strformat, strutils, tables, times
import "."/treesitter/[api, c, cpp]
import "."/[build, globals]
import "."/[globals]
import "."/toastlib/[ast2, getters, tshelp]
import "."/build/[ccompiler, misc]
proc process(gState: State, path: string) =
doAssert existsFile(path), &"Invalid path {path}"
@ -54,7 +56,7 @@ proc main(
) =
# Setup global state with arguments
var gState = State(
gState = State(
convention: convention,
debug: debug,
defines: defines,
@ -76,10 +78,6 @@ proc main(
symOverride: symOverride
)
# Set gDebug in build.nim
build.gDebug = gState.debug
build.gNimExe = gState.nim
# Split some arguments with ,
gState.symOverride = gState.symOverride.getSplitComma()
gState.prefix = gState.prefix.getSplitComma()

View file

@ -2,7 +2,8 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times
import regex
import ".."/[build, globals, plugin]
import ".."/[globals, plugin]
import ".."/build/[ccompiler, misc, nimconf, shell]
const gReserved = """
addr and as asm

View file

@ -1,6 +1,7 @@
import strutils, os
import ".."/[build, setup, paths]
import ".."/[setup, paths]
import ".."/build/shell
static:
treesitterCppSetup()