Skip to content

Commit d7787c1

Browse files
authored
use nifmake instead of make (#1152)
1 parent c041fc1 commit d7787c1

File tree

5 files changed

+336
-147
lines changed

5 files changed

+336
-147
lines changed

src/hastur.nim

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,11 @@ proc removeMakeErrors(output: string): string =
173173
result = output.strip
174174
for prefix in ["FAILURE:", "make:"]:
175175
let lastLine = rfind(result, '\n')
176-
if lastLine >= 0 and lastLine + prefix.len < result.len and
177-
result[lastLine + 1 .. lastLine + prefix.len] == prefix:
178-
result = result[0 .. lastLine].strip
179-
else: break
176+
if lastLine >= 0:
177+
if result.continuesWith(prefix, lastLine+1):
178+
result.setLen lastLine
179+
elif result.startsWith(prefix):
180+
result.setLen 0
180181

181182
proc compareValgrindOutput(s1: string, s2: string): bool =
182183
# ==90429==
@@ -576,6 +577,7 @@ proc handleCmdLine =
576577
buildNimony()
577578
buildNifc()
578579
buildHexer()
580+
buildNifmake()
579581
nimonytests(overwrite)
580582
nifctests(overwrite)
581583
#hexertests(overwrite)

src/nifmake/nifmake.nim

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ type
7474
CliCommand = enum
7575
cmdRun, cmdMakefile, cmdHelp, cmdVersion
7676

77+
CliOption = enum
78+
Parallel, Force, Verbose
79+
7780
proc skipParRi(n: var Cursor) =
7881
## Helper to skip a closing parenthesis
7982
if n.kind == ParRi:
@@ -99,17 +102,20 @@ proc findTool(name: string): string =
99102
if fileExists(result):
100103
discard "ok"
101104
elif not name.isAbsolute:
102-
result = toolDir(result)
105+
let t = toolDir(result)
106+
if fileExists(t):
107+
result = t
103108

104109
proc addSpace(result: var string) {.inline.} =
105110
if result.len > 0 and result[^1] != ' ': result.add ' '
106111

107112
proc addFilename(result: var string; filename, prefix, suffix: string) =
108-
result.addSpace()
109-
if prefix.len > 0: result.add prefix
110-
# This is not a bug, a suffix is always assumed to be part of the filename
111-
# and so also subject to quoting:
112-
result.add (suffix & filename).quoteShell
113+
if filename.len > 0:
114+
result.addSpace()
115+
if prefix.len > 0: result.add prefix
116+
# This is not a bug, a suffix is always assumed to be part of the filename
117+
# and so also subject to quoting:
118+
result.add (suffix & filename).quoteShell
113119

114120
proc expandCommand(cmd: Command; inputs, outputs: seq[string]): string =
115121
result = ""
@@ -131,6 +137,7 @@ proc expandCommand(cmd: Command; inputs, outputs: seq[string]): string =
131137
inc n
132138
of ParLe:
133139
let tag = pool.tags[n.tag]
140+
let L = if tag == "output": outputs.len else: inputs.len
134141
var a = 0
135142
var b = 0
136143
inc n
@@ -140,12 +147,12 @@ proc expandCommand(cmd: Command; inputs, outputs: seq[string]): string =
140147
inc n
141148
if n.kind == IntLit:
142149
a = pool.integers[n.intId]
143-
if a < 0: a = inputs.len + a
150+
if a < 0: a = L + a
144151
b = a
145152
inc n
146153
if n.kind == IntLit:
147154
b = pool.integers[n.intId]
148-
if b < 0: b = outputs.len + b
155+
if b < 0: b = L + b
149156
inc n
150157
var suffix = ""
151158
if n.kind == StringLit:
@@ -214,7 +221,18 @@ proc getFileTime(dag: var Dag; filename: string): Time =
214221
result = getTime() # Use current time for non-existent files
215222
dag.timestampCache[filename] = result
216223

217-
proc needsRebuild(dag: var Dag; node: Node): bool =
224+
proc removeOutdatedArtifacts(dag: var Dag; node: Node; opt: set[CliOption]) =
225+
## Remove outdated build artifacts for a node
226+
for output in node.outputs:
227+
if fileExists(output):
228+
try:
229+
removeFile(output)
230+
if Verbose in opt:
231+
echo "Removed outdated artifact: ", output
232+
except:
233+
stderr.writeLine "Warning: Could not remove outdated artifact: ", output
234+
235+
proc needsRebuild(dag: var Dag; node: Node; opt: set[CliOption]): bool =
218236
## Check if a node needs to be rebuilt
219237
result = false
220238

@@ -234,6 +252,8 @@ proc needsRebuild(dag: var Dag; node: Node): bool =
234252
if fileExists(input):
235253
let inputTime = dag.getFileTime(input)
236254
if inputTime >= oldestOutput:
255+
# Remove outdated artifacts before rebuilding
256+
dag.removeOutdatedArtifacts(node, opt)
237257
return true
238258

239259
proc visit(nodes: var seq[Node]; nodeId: int; sortedNodes: var seq[int]; maxDepth: var int): bool =
@@ -275,16 +295,20 @@ proc executeCommand(command: string): bool =
275295
except:
276296
result = false
277297

298+
proc failed(arg: string) =
299+
stdout.write "make: "
300+
stdout.writeLine arg
301+
278302
type
279303
CmdStatus = enum
280304
Enqueued, Running, Finished
281305

282-
proc runDag(dag: var Dag; parallel: bool): bool =
306+
proc runDag(dag: var Dag; opt: set[CliOption]): bool =
283307
## Execute the DAG in topological order
284308
result = true
285309
let sortedNodes = topologicalSort(dag)
286310

287-
if parallel:
311+
if Parallel in opt:
288312
var i = 0
289313
while i < sortedNodes.len:
290314
let currentDepth = dag.nodes[sortedNodes[i]].depth
@@ -294,10 +318,12 @@ proc runDag(dag: var Dag; parallel: bool): bool =
294318
# Collect all commands at the current depth
295319
while i < sortedNodes.len and dag.nodes[sortedNodes[i]].depth == currentDepth:
296320
let node = addr dag.nodes[sortedNodes[i]]
297-
if dag.needsRebuild(node[]):
298-
echo "Building: ", node.outputs.join(", ")
321+
if Force in opt or dag.needsRebuild(node[], opt):
322+
if Verbose in opt:
323+
echo "Building: ", node.outputs.join(", ")
299324
let expandedCmd = expandCommand(dag.commands[node.cmdIdx], node.inputs, node.outputs)
300-
echo "Command: ", expandedCmd
325+
if Verbose in opt:
326+
echo "Command: ", expandedCmd
301327
commands.add(expandedCmd)
302328
nodeIds.add(sortedNodes[i])
303329
inc i
@@ -312,21 +338,24 @@ proc runDag(dag: var Dag; parallel: bool): bool =
312338
if maxExitCode != 0:
313339
for i, p in pairs(progress):
314340
if p == Running:
315-
echo "Error: Command failed: ", commands[i]
341+
failed commands[i]
316342
return false
317343
else:
318344
# Sequential execution
319345
for nodeId in sortedNodes:
320346
let node = addr dag.nodes[nodeId]
321-
if dag.needsRebuild(node[]):
322-
echo "Building: ", node.outputs.join(", ")
347+
if Force in opt or dag.needsRebuild(node[], opt):
348+
if Verbose in opt:
349+
echo "Building: ", node.outputs.join(", ")
323350
let expandedCmd = expandCommand(dag.commands[node.cmdIdx], node.inputs, node.outputs)
324-
echo "Command: ", expandedCmd
351+
if Verbose in opt:
352+
echo "Command: ", expandedCmd
325353
if not executeCommand(expandedCmd):
326-
echo "Error: Command failed: ", expandedCmd
354+
failed expandedCmd
327355
return false
328356
else:
329-
echo "Up to date: ", node.outputs.join(", ")
357+
if Verbose in opt:
358+
echo "Up to date: ", node.outputs.join(", ")
330359

331360
proc mescape(p: string): string =
332361
when defined(windows):
@@ -504,6 +533,8 @@ Commands:
504533
Options:
505534
-j, --parallel Enable parallel builds (for 'run' command)
506535
--makefile <name> Output Makefile name (default: Makefile)
536+
--force Force rebuild of all targets
537+
--verbose Show verbose output
507538
508539
Examples:
509540
nifmake run build.nif
@@ -521,7 +552,7 @@ proc main() =
521552
cmd = cmdHelp
522553
inputFile = ""
523554
outputMakefile = "Makefile"
524-
parallel = false
555+
opt: set[CliOption] = {}
525556

526557
for kind, key, val in getopt():
527558
case kind
@@ -541,8 +572,10 @@ proc main() =
541572
case key.normalize
542573
of "help", "h": writeHelp()
543574
of "version", "v": writeVersion()
544-
of "parallel", "j": parallel = true
575+
of "parallel", "j": opt.incl Parallel
545576
of "makefile": outputMakefile = val
577+
of "force": opt.incl Force
578+
of "verbose": opt.incl Verbose
546579
else:
547580
echo "Unknown option: --", key
548581
quit(1)
@@ -557,8 +590,8 @@ proc main() =
557590
quit "Input file required for 'run' command"
558591

559592
var dag = parseNifFile(inputFile)
560-
if not runDag(dag, parallel):
561-
quit "Build failed"
593+
if not runDag(dag, opt):
594+
quit 1
562595

563596
of cmdMakefile:
564597
if inputFile == "":

0 commit comments

Comments
 (0)