diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 94edbd9375..8013cfb2be 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -2270,7 +2270,7 @@ proc registerReusedInit*(g: BModuleList; moduleBase: string; g.mainModProcs.finishProcHeaderAsProto() g.otherModsInit.addCallStmt(init) -proc registerReusedModuleToMain(g: BModuleList; m: BModule; +proc registerReusedModuleToMain*(g: BModuleList; m: BModule; initRequired, datInitRequired: bool) = ## `registerModuleToMain` for a module whose cached translation unit is ## reused: the init/datInit presence comes from the artifact's meta head diff --git a/compiler/nifbackend.nim b/compiler/nifbackend.nim index ca8712840c..9514a4aa79 100644 --- a/compiler/nifbackend.nim +++ b/compiler/nifbackend.nim @@ -569,10 +569,19 @@ proc generateCgStage(g: ModuleGraph; mainFileIdx: FileIndex) = return generateCodeForModule(g, target) + let bl = BModuleList(g.backend) # The main module also owns the whole-program method dispatchers + NimMain. if sfMainModule in target.module.flags: emitMethodDispatchers(g) - let bl = BModuleList(g.backend) + # NimMain (generated when the main module is finished) must call every other + # module's init/datInit. Those translation units are produced by their own + # `cg` processes, so the calls are registered here from each `.c.nif` meta + # head — which is why the main module's `cg` runs last, after every other + # `.c.nif` exists. Modules without init code (no `.c.nif`) register nothing. + for m in bl.mods: + if m != nil and sfMainModule notin m.module.flags: + let heads = readCnifHeads(getCFile(m).string & ".nif") + registerReusedModuleToMain(bl, m, heads.initRequired, heads.datInitRequired) let tb = bl.mods[target.module.position] if tb != nil: finishModule(g, tb)