diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 58d5b44376..77a221c875 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -2170,6 +2170,8 @@ proc genInitCode(m: BModule) = else: prcBody.add(extract(m.thing.s(section))) + #echo "PRE INIT PROC ", m.module.name.s, " ", m.s[cfsVars].buf.len + if m.preInitProc.s(cpsInit).buf.len > 0 or m.preInitProc.s(cpsStmts).buf.len > 0: # Give this small function its own scope prcBody.addScope(): @@ -2523,13 +2525,7 @@ proc shouldRecompile(m: BModule; code: Rope, cfile: Cfile): bool = rawMessage(m.config, errCannotOpenFile, cfile.cname.string) result = true -# We need 2 different logics here: pending modules (including -# 'nim__dat') may require file merging for the combination of dead code -# elimination and incremental compilation! Non pending modules need no -# such logic and in fact the logic hurts for the main module at least; -# it would generate multiple 'main' procs, for instance. - -proc writeModule(m: BModule, pending: bool) = +proc writeModule(m: BModule) = let cfile = getCFile(m) if moduleHasChanged(m.g.graph, m.module): genInitCode(m) @@ -2674,6 +2670,6 @@ proc cgenWriteModules*(backend: RootRef, config: ConfigRef) = genForwardedProcs(g) for m in cgenModules(g): - m.writeModule(pending=true) + m.writeModule() writeMapping(config, g.mapping) if g.generatedHeader != nil: writeHeader(g.generatedHeader) diff --git a/compiler/nifbackend.nim b/compiler/nifbackend.nim index a22404d52e..96071669d8 100644 --- a/compiler/nifbackend.nim +++ b/compiler/nifbackend.nim @@ -92,10 +92,16 @@ proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) = # Reset backend state resetForBackend(g) + # Ensure systemFileIdx is set up (might not be set in cmdNifC path) + if g.config.m.systemFileIdx == InvalidFileIdx: + g.config.m.systemFileIdx = msgs.fileInfoIdx(g.config, + g.config.libpath / RelativeFile"system.nim") + # Load system module first - it's always needed and contains essential hooks var precompSys = PrecompiledModule(module: nil) - if g.config.m.systemFileIdx != InvalidFileIdx: - precompSys = moduleFromNifFile(g, g.config.m.systemFileIdx, loadFullAst=true) + let systemFileIdx = g.config.m.systemFileIdx + if systemFileIdx != InvalidFileIdx: + precompSys = moduleFromNifFile(g, systemFileIdx, loadFullAst=true) g.systemModule = precompSys.module # Load all modules in dependency order using stack traversal @@ -117,19 +123,16 @@ proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) = discard setupNifBackendModule(g, precompSys.module) generateCodeForModule(g, precompSys) - # Generate code for all modules except main (main goes last) - # This ensures all modules are added to modulesClosed + # Track which modules have been processed to avoid duplicates + var processed = initIntSet() + if precompSys.module != nil: + processed.incl precompSys.module.position + # Generate code for all modules (skip system since it's already processed) for m in modules: - if m.module != g.systemModule: + if not processed.containsOrIncl(m.module.position): generateCodeForModule(g, m) - for m in BModuleList(g.backend).modules: - if m != nil: - assert m.module != nil - if sfMainModule notin m.module.flags: - finishModule g, m - # Write C files if g.backend != nil: cgenWriteModules(g.backend, g.config)