Fix #7 - separate file searching from include dirs

This commit is contained in:
Ganesh Viswanathan 2018-11-21 21:53:40 -06:00
commit a8bb2dc01f
4 changed files with 51 additions and 25 deletions

View file

@ -57,11 +57,15 @@ Detailed documentation is still forthcoming.
`cDebug()` - enable debug messages `cDebug()` - enable debug messages
`cDefine()` - `#define` an identifer that is forwarded to the compiler using `{.passC: "-DXXX".}` as well as _eventually_ used in processing `#ifdef` statements `cDefine("XXX")` - `#define` an identifer that is forwarded to the C/C++ compiler using `{.passC: "-DXXX".}` as well as _eventually_ used in processing `#ifdef` statements
`cIncludeDir()` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}` as well as searched for files included using `cImport()` statements and following `cIncludeDir()` statements `cIncludeDir("XXX")` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}`
`cImport()` - import all supported definitions from specific import header file `cImport("header.h")` - import all supported definitions from header file
`cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()`
`cSearchPath("header.h")` - return a file or directory found in search path configured using `cSearchPath()` - can be used in `cCompile()`, `cIncludeDir()` and `cImport()` calls
`gitPull()` - pull a git repository prior to C/C++ interop `gitPull()` - pull a git repository prior to C/C++ interop

View file

@ -2,20 +2,31 @@ import macros, os, strformat, strutils
import ast, getters, globals, lisp import ast, getters, globals, lisp
proc search(path: string): string = proc findPath(path: string, fail = true): string =
result = joinPath(getProjectPath(), path).replace("\\", "/") # As is
result = path.replace("\\", "/")
if not fileExists(result) and not dirExists(result): if not fileExists(result) and not dirExists(result):
result = path # Relative to project path
result = joinPath(getProjectPath(), path).replace("\\", "/")
if not fileExists(result) and not dirExists(result): if not fileExists(result) and not dirExists(result):
var found = false if fail:
for inc in gIncludeDirs:
result = inc & "/" & path
if fileExists(result) or dirExists(result):
found = true
break
if not found:
echo "File or directory not found: " & path echo "File or directory not found: " & path
quit(1) quit(1)
else:
return ""
proc cSearchPath*(path: string): string =
result = findPath(path, fail = false)
if result.len() == 0:
var found = false
for inc in gSearchDirs:
result = (inc & "/" & path).replace("\\", "/")
if fileExists(result) or dirExists(result):
found = true
break
if not found:
echo "File or directory not found: " & path
quit(1)
macro cDebug*(): untyped = macro cDebug*(): untyped =
gDebug = true gDebug = true
@ -34,13 +45,23 @@ macro cDefine*(name: static[string], val: static[string] = ""): untyped =
if gDebug: if gDebug:
echo result.repr echo result.repr
macro cAddSearchDir*(dir: static[string]): untyped =
result = newNimNode(nnkStmtList)
let fullpath = cSearchPath(dir)
if fullpath notin gSearchDirs:
gSearchDirs.add(fullpath)
macro cIncludeDir*(dir: static[string]): untyped = macro cIncludeDir*(dir: static[string]): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
let fullpath = search(dir) let
gIncludeDirs.add(fullpath) fullpath = findPath(dir)
str = "-I\"" & fullpath & "\""
let str = "-I\"" & fullpath & "\""
if fullpath notin gIncludeDirs:
gIncludeDirs.add(fullpath)
result.add(quote do: result.add(quote do:
{.passC: `str`.} {.passC: `str`.}
) )
@ -61,9 +82,8 @@ macro cIncludeC*(): untyped =
break break
if inc: if inc:
if gDebug: result = quote do:
echo "Including " & line.strip() cIncludeDir(line)
gIncludeDirs.add(line.strip())
macro cCompile*(path: static[string]): untyped = macro cCompile*(path: static[string]): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
@ -94,7 +114,7 @@ macro cCompile*(path: static[string]): untyped =
if path.contains("*") or path.contains("?"): if path.contains("*") or path.contains("?"):
dcompile(path) dcompile(path)
else: else:
let fpath = search(path) let fpath = findPath(path)
if fileExists(fpath): if fileExists(fpath):
stmt &= fcompile(fpath) & "\n" stmt &= fcompile(fpath) & "\n"
elif dirExists(fpath): elif dirExists(fpath):
@ -114,7 +134,7 @@ macro cImport*(filename: static[string]): untyped =
result.add addReorder() result.add addReorder()
let let
fullpath = search(filename) fullpath = findPath(filename)
root = parseLisp(fullpath) root = parseLisp(fullpath)
echo "Importing " & fullpath echo "Importing " & fullpath

View file

@ -25,6 +25,7 @@ var
gHeaders* {.compiletime.}: seq[string] gHeaders* {.compiletime.}: seq[string]
gIncludeDirs* {.compiletime.}: seq[string] gIncludeDirs* {.compiletime.}: seq[string]
gProcs* {.compiletime.}: seq[string] gProcs* {.compiletime.}: seq[string]
gSearchDirs* {.compiletime.}: seq[string]
gTypes* {.compiletime.}: seq[string] gTypes* {.compiletime.}: seq[string]
gCode* {.compiletime.}: string gCode* {.compiletime.}: string

View file

@ -2,9 +2,10 @@ import nimterop/cimport
cDebug() cDebug()
cIncludeDir("include") cIncludeDir "include"
cCompile("test.c") cAddSearchDir "include"
cImport("test.h") cCompile cSearchPath("test.c")
cImport cSearchPath "test.h"
doAssert TEST_INT == 512 doAssert TEST_INT == 512
doAssert TEST_FLOAT == 5.12 doAssert TEST_FLOAT == 5.12