PmDriver.icl 77.6 KB
Newer Older
Diederik van Arkel's avatar
Diederik van Arkel committed
1 2
implementation module PmDriver

3
import StdArray,StdBool,StdList,StdMisc,StdEnum,StdStrictLists
4
from StdOverloadedList import Foldr,++|,Hd,Any
Diederik van Arkel's avatar
Diederik van Arkel committed
5 6 7
import UtilNewlinesFile, UtilIO

import IdeState
8

9
from typeatt import update_type_window
10
from errwin  import updateErrorWindow
Diederik van Arkel's avatar
Diederik van Arkel committed
11
from messwin import showInfo, :: InfoMessage(..)
Diederik van Arkel's avatar
Diederik van Arkel committed
12
from projwin import pm_update_project_window
13

14 15
import PmCallBack

16
import PmCleanSystem,PmPath,PmProject
17
from PmDialogues import doPathsDialog
18
import PmAbcMagic,PmFileInfo,PmDirCache
19

20
import Platform
21
from StdLibMisc import :: Date{..}, :: Time{..}
Diederik van Arkel's avatar
Diederik van Arkel committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

verboseInfo verbose info ps :== verbi verbose info ps
where
	verbi verbose info ps
		| not verbose && level3 info
			= ps
			= showInfo info ps

	level3 (Level3 _) = True
	level3 _ = False

getFICache` ps
	# (_,ps)	= getFICache ps
	# fi		= FI_EmptyCache
	= (fi,ps)

/*--- TO DO:

system module dependancy analysis is possible...

	ie. when you encounter a system module that must be recompiled then check in done list
	and remove those that depend on this system module and put them back into the todo list

should also be possible to detect cycles... -> generate warning dialogue...

---*/

System			:== "_system"

//--- project manager routines

53
:: SetMadeProjectFun :== Bool -> Bool -> Project -> GeneralSt -> GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
54 55

//	Compile /Check Syntax of the designated module
56
CompileProjectModule ::	!CompileOrCheckSyntax !Pathname !Project !SetMadeProjectFun !*GeneralSt -> *GeneralSt
57
CompileProjectModule compileOrCheckSyntax imp_pathname project setproject ps
58
	# ps					= ClearCompilerCache` ps
59
	# (srcpaths,ps)			= get_project_and_environment_paths project ps
60
	# (mdn,imp_pathname) = determine_dir_and_filename imp_pathname srcpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
61 62 63 64 65 66
	#! (abccache,ps)		= getABCCache ps
	#! (fileinfo,ps)		= getFICache` ps
	#! ((errs,warns,dircache),ps)
							= accFiles (DC_Setup srcpaths) ps
	# ({be_verbose},ps)		= getPrefs ps
	#! ps					= HandleDCErrors be_verbose errs warns ps
67 68
	#! (fileinfo,abccache,project,ok,newpaths,_,_,_,ps)
							= CompileTheProjectModule compileOrCheckSyntax mdn imp_pathname fileinfo abccache project dircache ps
Diederik van Arkel's avatar
Diederik van Arkel committed
69 70 71 72
	# ps					= setABCCache abccache ps
	# ps					= setFICache fileinfo ps
	= setproject ok newpaths project ps

73
GenAsmProjectModule :: !.Pathname !Project !SetMadeProjectFun !*GeneralSt -> *GeneralSt
74
GenAsmProjectModule imp_pathname project setproject ps
75
	# ps					= ClearCompilerCache` ps
76
	# (srcpaths,ps)			= get_project_and_environment_paths project ps
77
	# (mdn,imp_pathname) = determine_dir_and_filename imp_pathname srcpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
78 79 80 81 82 83
	# (abccache,ps)			= getABCCache ps
	#! (fileinfo,ps)		= getFICache` ps
	# ((errs,warns,dircache),ps)
							= accFiles (DC_Setup srcpaths) ps
	# ({be_verbose},ps)		= getPrefs ps
	# ps					= HandleDCErrors be_verbose errs warns ps
84 85
	# (fileinfo,abccache,project,ok,newpaths,abcpath,_,_,ps)
							= CompileTheProjectModule Compilation mdn imp_pathname fileinfo abccache project dircache ps
Diederik van Arkel's avatar
Diederik van Arkel committed
86 87 88 89
	| not ok || newpaths
		# ps				= setABCCache abccache ps
		# ps				= setFICache fileinfo ps
		= setproject True False project ps
90
	# (ps,abccache,fileinfo,project,ok,_)
91
							= GenCodeTheProjectModule True False AsmGeneration mdn abcpath abccache fileinfo project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
92 93 94 95
	# ps					= setABCCache abccache ps
	# ps					= setFICache fileinfo ps
	= setproject True ok project ps

96
:: CleanupCont :== Pathname Bool Bool *GeneralSt -> *GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
97

98 99
:: *DriverCompilingInfo
	= Sync
100
	| AsyncWin ![CurrentlyCompiled] !AsyncWinCompilingInfo
101 102 103
	| Async	![CurrentlyCompiled] !AsyncCompilingInfo
	| Pers	!*CompilingInfo

104 105 106 107 108
::	AsyncWinCompilingInfo = {
		win_max_n_processes :: !Int,
		win_compiler_process_ids :: !CompilerProcessIds
	};

109 110 111 112 113 114
::	AsyncCompilingInfo = {
		max_n_processes :: !Int,
		compiler_process_ids :: !CompilerProcessIds,
		unknown_finished_processors :: !UnknownFinishedProcessors
	};

115 116
:: *DriverState
	= DInit !Bool !Project !MTPContinuation
117 118 119
	| DComp !Bool !*DirCache !DriverCompilingInfo ![!ModuleDirAndName] !DriverStateRecord
	| DGene ![!ModuleDirAndName] !DriverCodeGenerationInfo !DriverStateRecord
	| DQuitCompilers ![!ModuleDirAndName] !DriverCompilingInfo !DriverStateRecord
120 121 122 123 124 125 126 127 128 129 130
	| DLink !DriverStateRecord
	| DDone

:: *DriverStateRecord =
	{ project	:: !Project
	, continue	:: !MTPContinuation
	, fileinfo	:: !FileInfoCache
	, abccache	:: !*ABCCache
	, libsinfo	:: !StaticLibInfo
	, ok		:: !Bool
	, newpaths	:: !Bool
131
	, modpaths	:: ![!ModuleDirAndName]
132 133
	}

134
BringProjectUptoDate :: !Bool CleanupCont !*GeneralSt -> *GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
135 136 137 138 139 140
BringProjectUptoDate force continuation ps
	#  (project,ps)		= getProject ps

	#	ps				= PrecompileFase project ps

	#	ps				= showInfo (Level1 "Bring up to date...") ps
141
	#	ps				= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
142
		ini_step		= DInit force project cleanup
143
	= start ini_step step ps
Diederik van Arkel's avatar
Diederik van Arkel committed
144 145 146 147 148 149 150
where
	PrecompileFase project ps
		# (precompile,project)	= PR_GetPrecompile project
		| isJust precompile
			# ps				= showInfo (Level1 "Precompile...") ps
			# (ok,ec,ps)		= Execute` (fromJust precompile) ps
			// error handling???
151 152 153
			= ps
		= ps

154 155 156
	PostlinkFase ok project ps
		| not ok
			= ps
Diederik van Arkel's avatar
Diederik van Arkel committed
157 158
		# (postlink,project)	= PR_GetPostlink project
		| isJust postlink
159
			# (Just post_link)	= postlink
160
			# (prj_path,ps)		= getProjectFilePath ps
161
			# prj_dir_path  = PR_GetRootDir project
162 163
			# (app_path,ps)		= getStup ps
			# post_link			= fulPath app_path prj_dir_path post_link
Diederik van Arkel's avatar
Diederik van Arkel committed
164
			# ps				= showInfo (Level1 "Postlink...") ps
165
			# (ok,ec,ps)		= Execute` ("\""+++post_link+++"\" \""+++prj_path+++"\"") ps
Diederik van Arkel's avatar
Diederik van Arkel committed
166 167
			= ps
		= ps
168

169
	cleanup :: !Bool !Bool !Bool !FileInfoCache !StaticLibInfo ![!ModuleDirAndName] !Project !Bool (!*ABCCache,!GeneralSt) -> *(!*DriverState,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
170 171 172
	cleanup ok newpaths linked fileinfo libsinfo modpaths project intr (abccache,ps)
		| newpaths && not intr		// if paths have changed -> try again
			# ps			= showInfo (Level1 "Paths have changed: remaking.") ps
173
			# ps			= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
174 175
			= MakeTheProject False fileinfo libsinfo abccache project cleanup` ps

176
		# ps				= PostlinkFase ok project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
177 178 179 180 181 182 183 184 185 186 187 188 189 190
		
		# ps				= showInfo (Level1 "Finished making.") ps
		# ps				= setProject project ps
		# ps				= setABCCache abccache ps
		# ps				= setFICache fileinfo ps
		# ps				= pm_update_project_window ps
		# path				= PR_GetExecPath project
		= stop (DDone,continuation path linked ok ps)
	
	cleanup` :: MTPContinuation
	cleanup` = cleanup

//-- Private stuff

191 192 193 194 195 196
get_project_and_environment_paths :: Project *GeneralSt -> *(!List String,!*GeneralSt)
get_project_and_environment_paths project ps
	# (syspaths,ps)			= getCurrentPaths ps
	# prjpaths				= PR_GetPaths project
	= (AppendLists prjpaths syspaths,ps)

197
:: MTPContinuation :== Bool Bool Bool FileInfoCache StaticLibInfo [!ModuleDirAndName] Project Bool *(*ABCCache,GeneralSt) -> *(*DriverState,*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
198

199
MakeTheProject :: !Bool !FileInfoCache !StaticLibInfo !*ABCCache !Project !MTPContinuation !GeneralSt -> (!*DriverState,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
200
MakeTheProject force fileinfo libsinfo abccache project continue ps
201
	# (srcpaths,ps)			= get_project_and_environment_paths project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
202 203 204 205
	# ((errs,warns,dircache),ps)
							= accFiles (DC_Setup srcpaths) ps
	# ({be_verbose},ps)		= getPrefs ps
	# ps					= HandleDCErrors be_verbose errs warns ps
206
	# (root_mdn,project)	= PR_GetRootModuleDirAndName project
Diederik van Arkel's avatar
Diederik van Arkel committed
207
	# (env_static_libs,ps)	= getCurrentSlibs ps
208
	# sfiles				= StrictListToList (Concat (SL_Libs libsinfo) env_static_libs)
Diederik van Arkel's avatar
Diederik van Arkel committed
209 210 211 212
	# (err,ps)				= check_exists sfiles ps
	| isJust err
		# line				= Level3 ["Error: Unable to find static library: '" +++ fromJust err +++ "'."]
		# ps				= showInfo line ps
213
		= continue False False False fileinfo libsinfo [!] project False (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
214 215 216 217
	# ((errs,slibs),ps)		= accFiles (getLibs sfiles) ps
	| not (isEmpty errs)
		# line				= Level3 ["Error: Failed reading static libraries: '" :errs]
		# ps				= showInfo line ps
218
		= continue False False False fileinfo libsinfo [!] project False (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
219 220 221
	# slibs					= ListToStrictList slibs
	# libsinfo				= SL_SetDcls slibs libsinfo
	# ps					= showInfo (Level1 "Compiling...") ps
222
	# rest					= [!root_mdn]
Diederik van Arkel's avatar
Diederik van Arkel committed
223
	# (method,ps)			= getCurrentMeth ps
224 225
	# (compinfo,ps) = case method of
				CompileSync			-> (Sync,ps)
226
				(CompileAsync cmax)	-> PlatformDependant
227
										(AsyncWin [] {win_max_n_processes=cmax,win_compiler_process_ids=NoCompilerProcessIds},ps)								// win
228 229 230 231
										(let (compiler_process_ids,ps2) = getCompilerProcessIds ps
										 in  (Async [] {max_n_processes=cmax,compiler_process_ids=compiler_process_ids,unknown_finished_processors=NoUnknownFinishedProcessors},ps2)	// mac
										)
				CompilePers			-> (Pers InitCompilingInfo,ps)
232 233 234 235 236 237 238 239
	# ds = 
		{ project	= project
		, continue	= continue
		, fileinfo	= fileinfo
		, abccache	= abccache
		, libsinfo	= libsinfo
		, ok		= True
		, newpaths	= False
240
		, modpaths	= [!]
241 242
		}
	= step False (DComp force dircache compinfo rest ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
243 244 245 246 247 248 249 250
where
	check_exists [] ps = (Nothing,ps)
	check_exists [file:rest] ps
		# (ok,ps) = accFiles (FExists file) ps
		| ok = check_exists rest ps
		= (Just file,ps)

:: CurrentlyCompiled =
251
	{ iclModule	:: !ModuleDirAndName
Diederik van Arkel's avatar
Diederik van Arkel committed
252 253 254 255
	, options	:: CompilerOptions
	, slot		:: !Int
	}

256 257
:: *DriverCodeGenerationInfo
	= SyncCodeGeneration
258
	| ASyncCodeGeneration ![CodeGeneratorProcessNAndPaths] !AsyncCompilingInfo
259 260 261 262 263 264 265 266 267 268 269 270 271
	| ASyncCodeGenerationWin ![WinCodeGeneratorProcess] /*max_n_processes*/!Int

:: CodeGeneratorProcessNAndPaths
	= { cgp_process_n :: !Int, cgp_module_name :: !Modulename, cgp_obj_path :: !Pathname }

:: WinCodeGeneratorProcess = {
	wcgp_process_n :: !Int,
	wcgp_process_handle :: !Int,
	wcgp_scg :: !StartedCodeGenerator,
	wcgp_module_name :: !Modulename,
	wcgp_obj_path :: !Pathname
   }

272 273 274 275
module_occurs :: !String ![!ModuleDirAndName] -> Bool
module_occurs s [|x:xs] = x.mdn_name == s || module_occurs s xs
module_occurs s [!] =  False

276 277 278 279 280 281 282 283 284
get_neverTimeProfile_option :: !{#Char} Project !*GeneralSt -> (!Bool,!*GeneralSt)
get_neverTimeProfile_option module_name project ps
	= case (PR_GetModuleInfo module_name project) of
		Just modinfo
			-> (modinfo.compilerOptions.neverTimeProfile,ps)
		_
			# (prefs,ps) = getPrefs ps
			  defaultCO = prefs.compopts
			-> (defaultCO.neverTimeProfile,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
285

286
step :: !Bool !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
287
step intr (DInit force project setproject) ps
288
//	# ps				= showInfo (Level1 "Make the project...") ps
Diederik van Arkel's avatar
Diederik van Arkel committed
289 290 291 292 293
	# libsinfo			= PR_GetStaticLibsInfo project
	# (abccache,ps)		= getABCCache ps
	# (fileinfo,ps)		= getFICache` ps
	= MakeTheProject force fileinfo libsinfo abccache project setproject ps

294
step True (DComp force dircache compinfo rest ds) ps
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
	# ds = {ds & ok = False}
	# (modpaths,ds) = ds!modpaths
	= case compinfo of
		Pers inf
			#! ds = DGene modpaths SyncCodeGeneration ds
			// compile phase finished: kill clean compiler
			# (_,ps) = ExitCleanCompiler (inf,ps)
			-> step True ds ps
		AsyncWin _ _
			#! ds = DQuitCompilers modpaths compinfo ds
			-> step True ds ps
		_
			#! ds = DGene modpaths SyncCodeGeneration ds
			// need async cocl shootdown as well..
			-> step True ds ps
Diederik van Arkel's avatar
Diederik van Arkel committed
310

311
step intr (DComp force dircache Sync [!] ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
312
	// compile phase finished: remove all modules not (indirectly) imported by main module
313
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
314
	# (modpaths,project)	= PR_GetDirAndModulenames project
315
	# ds					= {ds & modpaths = modpaths, project = project}
Diederik van Arkel's avatar
Diederik van Arkel committed
316
	# ps					= showInfo (Level1 "Generating...") ps
317 318
	# (paths,ds)			= ds!modpaths
	= step intr (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
319

320
step intr (DComp force dircache Sync [!next : rest] ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
321
	// compile phase: check module 'next'
322
	| module_occurs next.mdn_name ds.modpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
323
		// if already done then skip
324
		= step intr (DComp force dircache Sync rest ds) ps
325
	| isProjLibraryModule next.mdn_name ds.libsinfo
326 327 328 329 330
		// instead of testing explicitly put libmodules in done <= conflicts with other administration
		= step intr (DComp force dircache Sync rest ds) ps
	# (ps,dircache,ok,newpaths`,rest,compinfo,ds,_)
							= UpdateDependencies force next rest Sync dircache ds ps
	# ds	= {ds & newpaths = ds.newpaths || newpaths`, ok = ok}
Diederik van Arkel's avatar
Diederik van Arkel committed
331
	| not ok
332 333
		# (paths,ds)		= ds!modpaths
		= step intr (DGene paths SyncCodeGeneration ds) ps
334
	# ds & modpaths = [!next : ds.modpaths]
335
	= cont (DComp force dircache compinfo rest ds,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
336

337
step intr (DComp force dircache (Pers inf) [!] ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
338 339 340
	// compile phase finished: kill clean compiler
	# (_,ps)				= ExitCleanCompiler (inf,ps)
	// compile phase finished: remove all modules not (indirectly) imported by main module
341
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
342
	# (modpaths,project)	= PR_GetDirAndModulenames project
343
	# ds					= {ds & modpaths = modpaths, project = project}
Diederik van Arkel's avatar
Diederik van Arkel committed
344
	# ps					= showInfo (Level1 "Generating...") ps
345 346
	# (paths,ds)			= ds!modpaths
	= step intr (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
347

348
step intr (DComp force dircache compinfo=:(Pers _) [!next:rest] ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
349
	// compile phase: check module 'next'
350
	| module_occurs next.mdn_name ds.modpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
351
		// if already done then skip
352
		= step intr (DComp force dircache compinfo rest ds) ps
353
	| isProjLibraryModule next.mdn_name ds.libsinfo
354
		// instead of testing explicitly put libmodules in done <= conflicts with other administration
355
		= step intr (DComp force dircache compinfo rest ds) ps
356 357 358
	# (ps,dircache,ok,newpaths`,rest,compinfo,ds,_)
							= UpdateDependencies force next rest compinfo dircache ds ps
	# ds	= {ds & newpaths = ds.newpaths || newpaths`, ok = ok}
Diederik van Arkel's avatar
Diederik van Arkel committed
359
	| not ok
360
		# (Pers inf)		= compinfo
361
		# (_,ps)			= ExitCleanCompiler (inf,ps)
362 363
		# (paths,ds)		= ds!modpaths
		= step intr (DGene paths SyncCodeGeneration ds) ps
364
	# ds & modpaths = [!next : ds.modpaths]
365
	= cont (DComp force dircache compinfo rest ds,ps)
366

367
step intr (DComp force dircache (Async [] async_compiling_info=:{max_n_processes,compiler_process_ids,unknown_finished_processors=NoUnknownFinishedProcessors}) [!] ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
368
	// compile phase finished: remove all modules not (indirectly) imported by main module
369
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
370
	# (modpaths,project)	= PR_GetDirAndModulenames project
371
	# ds					= {ds & modpaths = modpaths, project = project}
372
	# (os_error,ps)			= ClearCompilerCaches compiler_process_ids ps;
Diederik van Arkel's avatar
Diederik van Arkel committed
373
	# ps					= showInfo (Level1 "Generating...") ps
374
	# (paths,ds)			= ds!modpaths
375
	= step intr (DGene paths (ASyncCodeGeneration [] async_compiling_info) ds) ps
376

377
step intr (DComp force dircache (AsyncWin [] {win_compiler_process_ids,win_max_n_processes}) [!] ds) ps
378 379
	// compile phase finished: remove all modules not (indirectly) imported by main module
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
380
	# (modpaths,project)	= PR_GetDirAndModulenames project
381
	# ds					= {ds & modpaths = modpaths, project = project}
382
	# ps = app_world_instead_of_ps (QuitCleanCompiler True win_compiler_process_ids) ps;
383 384
	# ps					= showInfo (Level1 "Generating...") ps
	# (paths,ds)			= ds!modpaths
385
	= step intr (DGene paths (IF_MACOSX SyncCodeGeneration (ASyncCodeGenerationWin [] win_max_n_processes)) ds) ps
386

387
step intr state=:(DComp force _ (Async _ _) _ _) ps
388 389
	# (state, ps)			= check_completed state ps
	# (state, ps)			= start_compilations state ps
Diederik van Arkel's avatar
Diederik van Arkel committed
390 391
	= cont (state, ps)
	where
392
		check_completed :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
393 394
		check_completed state=:(DComp force _ (Async current=:[_:_] {max_n_processes,compiler_process_ids}) _ _)  ps
			= case (CompilePollCompleted compiler_process_ids ps) of
Diederik van Arkel's avatar
Diederik van Arkel committed
395 396 397 398
				(NoFinishedCompiler,ps)
					-> check_unknow_processors_are_known state ps
				(UnknownFinishedCompiler,ps)
					-> case state of
399
						DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors}) todo ds
Diederik van Arkel's avatar
Diederik van Arkel committed
400
							# unknown_finished_processors = add_unknown_finished_processor unknown_finished_processors
401
							# state = DComp force dircache (Async current {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) todo ds
Diederik van Arkel's avatar
Diederik van Arkel committed
402 403 404 405 406 407 408
							-> check_completed state ps
				(FinishedCompiler completedSlot exitcode,ps)
					#! (state,ps) = process_completed completedSlot exitcode state ps
					-> check_completed state ps
		check_completed state ps
			= check_unknow_processors_are_known state ps

409 410 411
		check_unknow_processors_are_known (DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors=UnknownFinishedProcessors n_unknown_finished_processors known_finished_processors}) todo ds) ps
			| n_unknown_finished_processors+length known_finished_processors>=max_n_processes
				# state = DComp force dircache (Async current {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=NoUnknownFinishedProcessors}) todo ds
Diederik van Arkel's avatar
Diederik van Arkel committed
412 413 414
				# (state,ps) = handle_completed_processes 0 state ps
					with
						handle_completed_processes process_n state ps
415
							| process_n>=max_n_processes
Diederik van Arkel's avatar
Diederik van Arkel committed
416 417 418 419 420 421 422 423 424 425 426 427 428
								= (state,ps)
							| isMember process_n known_finished_processors
								= handle_completed_processes (process_n+1) state ps
								# (_,ps) = SendRepeatResult process_n ps
								/*
								# exitcode = 1
								#! (state,ps) = process_completed process_n exitcode state ps
								*/
								= handle_completed_processes (process_n+1) state ps								
				= (state, ps)
		check_unknow_processors_are_known state ps
			=	(state, ps)

429
		process_completed :: !Int !Int !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
430
		process_completed completedSlot exitcode (DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors}) todo ds) ps
431 432 433
			# (completed, current)			= removeFromCurrent completedSlot current
			# unknown_finished_processors	= remove_from_unknown_finished_processors completedSlot unknown_finished_processors
			# (startupdir,ps)				= getStup ps
434
			# (interact, ps)				= getInteract ps
435
			# typewin = update_type_window interact completed.iclModule.mdn_name
436
			# ccstring						= "dummy ccstring for now.."
437
			# (abcpath,res,ps)				= CompileHandleExitCode exitcode ccstring startupdir completedSlot updateErrorWindow typewin 
438
												completed.iclModule completed.options.listTypes ps // types param
439
			# (_,(fileinfo,abccache,project,ok,newpaths`,_,deps,dircache,ps))
440
											= ProcessCompilerMsg Nothing Compilation completed.options completed.iclModule abcpath res ds.fileinfo dircache ds.abccache ds.project ps
441
			# ds							= {ds & newpaths = ds.newpaths || newpaths`, fileinfo = fileinfo, abccache = abccache, project = project, ok = ok}
442 443 444 445
			| ok
				# ds & modpaths = [!completed.iclModule : ds.modpaths]
				  todo = deps++|todo
				= (DComp force dircache (Async current {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) todo ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
446
			// not ok
447
				# (os_error,ps) = ClearCompilerCaches compiler_process_ids ps;
448 449
				# (paths,ds)	= ds!modpaths
				= (DGene paths SyncCodeGeneration ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
450

451
		start_compilations :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
452
		start_compilations state=:(DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors}) [!next : rest] ds) ps
453
			// all threads used?
454 455
			| length current >= max_n_processes
				# ps = DelayEventLoop ps;			
Diederik van Arkel's avatar
Diederik van Arkel committed
456
				= (state, ps)
457
			// compile phase: check module 'next'
458
			| module_occurs next.mdn_name ds.modpaths || currently_compiled next.mdn_name current
459
				= start_compilations (DComp force dircache (Async current {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) rest ds) ps
460
			| isProjLibraryModule next.mdn_name ds.libsinfo
461
				// instead of testing explicitly put libmodules in done <= conflicts with other administration
462
				= (DComp force dircache (Async current {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) rest ds, ps)
463
			# (ps,dircache,ok,_,rest,compinfo,ds,_)
464
				= UpdateDependencies force next rest (Async current {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) dircache ds ps
465
			# ds = {ds & ok = ok}
Diederik van Arkel's avatar
Diederik van Arkel committed
466
			| not ok
467
				# (os_error,ps) = ClearCompilerCaches compiler_process_ids ps;
468 469 470
				#! (paths,ds)	= ds!modpaths
				= (DGene paths SyncCodeGeneration ds, ps)
			= start_compilations (DComp force dircache compinfo rest ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
471
		start_compilations state ps
472
			# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
473 474 475 476 477 478 479
			= (state, ps)

step intr state=:(DComp force dircache compinfo=:(AsyncWin _ _) rest ds) ps
	# (state, ps) = check_completed state ps
	# (state, ps) = start_compilations state ps
	= cont (state, ps)
	where
480
		check_completed :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
481 482
		check_completed state=:(DComp _ _ (AsyncWin current=:[_:_] {win_compiler_process_ids}) _ _)  ps
			=	case (CompilePollCompleted win_compiler_process_ids ps) of
Diederik van Arkel's avatar
Diederik van Arkel committed
483 484 485 486
					(NoFinishedCompiler, ps)
						-> (state, ps)
					(FinishedCompiler completedSlot exitcode, ps)
						#! (state,ps) = process_completed completedSlot exitcode state ps
487 488 489
						-> IF_BATCHBUILD_OR_IDE
								(state,ps)
								(check_completed state ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
490 491 492 493 494
					(UnknownFinishedCompiler,ps)
						-> (state, ps)	// -> doesn't occur on win
		check_completed state ps
			=	(state, ps)

495
		process_completed :: !Int !Int !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
496
		process_completed completedSlot exitcode (DComp force dircache (AsyncWin current {win_max_n_processes,win_compiler_process_ids}) todo ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
497 498
			# (completed, current)	= removeFromCurrent completedSlot current
			# (startupdir,ps)		= getStup ps
499
			# (interact, ps)		= getInteract ps
500
			# typewin				= update_type_window interact completed.iclModule.mdn_name
Diederik van Arkel's avatar
Diederik van Arkel committed
501
			# ccstring				= "dummy ccstring for now.."
502
			# (abcpath,res,ps)		= CompileHandleExitCode exitcode ccstring startupdir completedSlot updateErrorWindow typewin 
Diederik van Arkel's avatar
Diederik van Arkel committed
503
										completed.iclModule completed.options.listTypes ps // types param
504
			# (_,(fileinfo,abccache,project,ok,newpaths`,_,deps,dircache,ps))
505
				= ProcessCompilerMsg Nothing Compilation completed.options completed.iclModule abcpath res ds.fileinfo dircache ds.abccache ds.project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
506 507
			# ds					= {ds & newpaths = ds.newpaths || newpaths`, fileinfo = fileinfo, abccache = abccache, project = project, ok = ok}
			| ok
508 509 510
				# ds & modpaths = [!completed.iclModule : ds.modpaths]
				  todo = deps++|todo
				= (DComp force dircache (AsyncWin current {win_max_n_processes=win_max_n_processes,win_compiler_process_ids=win_compiler_process_ids}) todo ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
511 512
			// not ok
				# (paths,ds)	= ds!modpaths
513
				= (DQuitCompilers paths (AsyncWin current {win_max_n_processes=win_max_n_processes,win_compiler_process_ids=win_compiler_process_ids}) ds,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
514

515
		start_compilations :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
516
		start_compilations state=:(DComp force dircache (AsyncWin current {win_max_n_processes,win_compiler_process_ids}) [!next : rest] ds) ps
517 518
			| length current >= win_max_n_processes
				# ps = DelayEventLoop ps;			
Diederik van Arkel's avatar
Diederik van Arkel committed
519
				= (state, ps)
520 521
			// compile phase: check module 'next'
			| module_occurs next.mdn_name ds.modpaths || currently_compiled next.mdn_name current
522
				= start_compilations (DComp force dircache (AsyncWin current {win_max_n_processes=win_max_n_processes,win_compiler_process_ids=win_compiler_process_ids}) rest ds) ps
523
			| isProjLibraryModule next.mdn_name ds.libsinfo
Diederik van Arkel's avatar
Diederik van Arkel committed
524
				// instead of testing explicitly put libmodules in done <= conflicts with other administration
525
				= (DComp force dircache (AsyncWin current {win_max_n_processes=win_max_n_processes,win_compiler_process_ids=win_compiler_process_ids}) rest ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
526
			# (ps,dircache,ok,_,rest,compinfo,ds,_)
527
				= UpdateDependencies force next rest (AsyncWin current {win_max_n_processes=win_max_n_processes,win_compiler_process_ids=win_compiler_process_ids}) dircache ds ps
Diederik van Arkel's avatar
Diederik van Arkel committed
528 529 530
			# ds = {ds & ok = ok}
			| not ok
				#! (paths,ds)	= ds!modpaths
531
				= (DQuitCompilers paths (AsyncWin current {win_max_n_processes=win_max_n_processes,win_compiler_process_ids=win_compiler_process_ids}) ds,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
532
			= start_compilations (DComp force dircache compinfo rest ds) ps
533
		start_compilations state=:(DComp force dircache (AsyncWin [] _) [!] ds) ps
534
			= (state, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
535
		start_compilations state ps
536
			# ps = DelayEventLoop ps;
Diederik van Arkel's avatar
Diederik van Arkel committed
537 538
			= (state, ps)

539 540 541 542 543 544 545 546 547 548 549 550 551
step intr (DQuitCompilers modpaths (AsyncWin [] {win_compiler_process_ids}) ds) ps
	# ps = app_world_instead_of_ps (QuitCleanCompiler True win_compiler_process_ids) ps
	= step intr (DGene modpaths SyncCodeGeneration ds) ps
step intr state=:(DQuitCompilers modpaths (AsyncWin current async_win_compiling_info=:{win_compiler_process_ids}) ds) ps
	= case (CompilePollCompleted win_compiler_process_ids ps) of
		(NoFinishedCompiler, ps)
			-> cont (state, ps)
		(FinishedCompiler completedSlot exitcode, ps)
			# (completed, current) = removeFromCurrent completedSlot current
			-> cont (DQuitCompilers modpaths (AsyncWin current async_win_compiling_info) ds, ps)
		(UnknownFinishedCompiler,ps)
			-> cont (state, ps)	// -> doesn't occur on win

552
step intr (DGene [!] SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
553
	#! ps	= showInfo (Level1 "Linking...") ps
554
	= step intr (DLink ds) ps
555

556
step intr (DGene [!] (ASyncCodeGeneration [] {unknown_finished_processors=NoUnknownFinishedProcessors,compiler_process_ids}) ds) ps
557
	# ps = setCompilerProcessIds compiler_process_ids ps
Diederik van Arkel's avatar
Diederik van Arkel committed
558
	#! ps	= showInfo (Level1 "Linking...") ps
559
	= step intr (DLink ds) ps
560

561
step intr (DGene [!] (ASyncCodeGenerationWin [] _) ds) ps
562 563 564
	#! ps	= showInfo (Level1 "Linking...") ps
	= step intr (DLink ds) ps

565
step intr (DGene [!mdn:rest] SyncCodeGeneration ds) ps
566 567 568
	| not ds.ok || intr
		# ds = {ds & ok = False}
		= step intr (DLink ds) ps
569
	# (abccache,fileinfo,gen,abcpath,ps)	= check_object_file_out_of_date mdn False ds.abccache ds.fileinfo ds.project ps
570
	# (ps,abccache,fileinfo,project,ok,_)	= GenCodeTheProjectModule gen False CodeGeneration mdn abcpath abccache fileinfo ds.project ps
571
	# ds = {ds & abccache = abccache, fileinfo = fileinfo, project = project, ok = ok}
Diederik van Arkel's avatar
Diederik van Arkel committed
572
	| not ok
573 574
		= step intr (DLink ds) ps
	= cont (DGene rest SyncCodeGeneration ds, ps)
575

576
step intr (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes,compiler_process_ids,unknown_finished_processors}) ds) ps
577 578
	# (ok,busy_processes,unknown_finished_processors,project,fileinfo,ps)
		= handle_finished_code_generators busy_processes unknown_finished_processors ds.project ds.fileinfo ps
Diederik van Arkel's avatar
Diederik van Arkel committed
579 580
		with
			handle_finished_code_generators busy_processes=:[_:_] unknown_finished_processors project fileinfo ps
581
				= case (CompilePollCompleted compiler_process_ids ps) of
Diederik van Arkel's avatar
Diederik van Arkel committed
582 583 584 585 586 587 588 589 590 591
					(NoFinishedCompiler, ps)
						-> check_unknow_processors_are_known busy_processes unknown_finished_processors project fileinfo ps
					(UnknownFinishedCompiler,ps)
						# unknown_finished_processors = add_unknown_finished_processor unknown_finished_processors
						-> (True,busy_processes,unknown_finished_processors,project,fileinfo,ps)
					(FinishedCompiler finished_cg_slot_n exit_code, ps)
//						# ps  = trace ("code generator finished "+++toString finished_cg_slot_n+++" "+++toString exit_code+++"\n") ps
//						# ps  = trace ("f "+++toString finished_cg_slot_n+++" "+++toString exit_code+++" ") ps

						# unknown_finished_processors = remove_from_unknown_finished_processors finished_cg_slot_n unknown_finished_processors
592
						# (module_name,obj_path,busy_processes) = get_paths_and_remove_process_from_list finished_cg_slot_n busy_processes
Diederik van Arkel's avatar
Diederik van Arkel committed
593
							with
594 595 596 597 598
								get_paths_and_remove_process_from_list finished_cg_slot_n [busy_process=:{cgp_process_n,cgp_module_name,cgp_obj_path} : rest]
									| finished_cg_slot_n==cgp_process_n
										= (cgp_module_name,cgp_obj_path,rest)
										# (module_name,obj_path,rest) = get_paths_and_remove_process_from_list finished_cg_slot_n rest
										= (module_name,obj_path,[busy_process:rest])
599
								get_paths_and_remove_process_from_list finished_cg_slot_n []
Diederik van Arkel's avatar
Diederik van Arkel committed
600 601
									= abort "driver.icl: unknown code generator id"
						| exit_code==0
602 603
							# (fileinfo,ps) = accFiles (FI_UpdateObjDate module_name obj_path fileinfo) ps
							# project = PR_SetCodeGenerated module_name project
Diederik van Arkel's avatar
Diederik van Arkel committed
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
							-> handle_finished_code_generators busy_processes unknown_finished_processors project fileinfo ps
							-> (False,busy_processes,unknown_finished_processors,project,fileinfo,ps)
			handle_finished_code_generators [] unknown_finished_processors project fileinfo ps
				= check_unknow_processors_are_known [] unknown_finished_processors project fileinfo ps

			check_unknow_processors_are_known busy_processes (UnknownFinishedProcessors n_unknown_finished_processors known_finished_processors) project fileinfo ps
				| n_unknown_finished_processors+length known_finished_processors>=max_n_processes
					# (busy_processes,project,fileinfo,ps) = handle_completed_processes 0 busy_processes project fileinfo ps
						with
							handle_completed_processes process_n busy_processes project fileinfo ps
								| process_n>=max_n_processes
									= (busy_processes,project,fileinfo,ps)
								| isMember process_n known_finished_processors
									= handle_completed_processes (process_n+1) busy_processes project fileinfo ps
									# (_,ps) = SendRepeatResult process_n ps
									/*
									# unknown_finished_processors = remove_from_unknown_finished_processors finished_cg_slot_n unknown_finished_processors
621
									# (abc_path,obj_path,busy_processes) = get_paths_and_remove_process_from_list finished_cg_slot_n busy_processes
Diederik van Arkel's avatar
Diederik van Arkel committed
622
										with
623
											get_paths_and_remove_process_from_list finished_cg_slot_n [busy_process=:(slot,abc_path,obj_path) : rest]
Diederik van Arkel's avatar
Diederik van Arkel committed
624 625
												| process_n==slot
													= (abc_path,obj_path,rest)
626
													# (abc_path,obj_path,rest) = get_paths_and_remove_process_from_list finished_cg_slot_n rest
Diederik van Arkel's avatar
Diederik van Arkel committed
627
													= (abc_path,obj_path,[busy_process:rest])
628
											get_paths_and_remove_process_from_list finished_cg_slot_n []
Diederik van Arkel's avatar
Diederik van Arkel committed
629 630 631 632 633 634 635 636
												= abort "driver.icl: unknown code generator id"
									# (fileinfo,ps) = accFiles (FI_UpdateObjDate abc_path obj_path fileinfo) ps
									# project = PR_SetCodeGenerated (GetModuleName abc_path) project
									*/
									= handle_completed_processes (process_n+1) busy_processes project fileinfo ps								
					= (True,busy_processes,NoUnknownFinishedProcessors,project,fileinfo,ps)
			check_unknow_processors_are_known busy_processes unknown_finished_processors project fileinfo ps
				= (True,busy_processes,unknown_finished_processors,project,fileinfo,ps)
637 638
	# ds = {ds & fileinfo = fileinfo, project = project, ok = ds.ok && ok && not intr}
	| not ds.ok
639
		= cont (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) ds,ps)
640
	| length busy_processes>=max_n_processes || (case paths of [!] -> True ; _ -> False)
641 642
		# ps = DelayEventLoop ps
		= cont (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) ds,ps)
643
	# (ok,paths,busy_processes,fileinfo,abccache,ps) = start_code_generators paths busy_processes ds.fileinfo ds.abccache ps
Diederik van Arkel's avatar
Diederik van Arkel committed
644
		with
645 646
			start_code_generators :: [!ModuleDirAndName] [CodeGeneratorProcessNAndPaths] FileInfoCache *ABCCache !*GeneralSt -> *(.Bool,[!ModuleDirAndName],[CodeGeneratorProcessNAndPaths],FileInfoCache,*ABCCache,!*GeneralSt)
			start_code_generators paths=:[!mdn : rest] busy_processes fileinfo abccache ps
Diederik van Arkel's avatar
Diederik van Arkel committed
647
				| length busy_processes>=max_n_processes
648
		 			# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
649
					= (True,paths,busy_processes,fileinfo,abccache,ps)
650 651
				# (abccache,fileinfo,gen,abc_path,ps)
									= check_object_file_out_of_date mdn False abccache fileinfo project ps
652
				# cgo				= PR_GetCodeGenOptions project
653
				# (proc,ps)			= getCurrentProc ps
654
				# ((info,abccache,fileinfo), ps)
655
									= FI_GetFileInfo proc mdn abccache fileinfo ps
Diederik van Arkel's avatar
Diederik van Arkel committed
656 657
				| not gen
					= start_code_generators rest busy_processes fileinfo abccache ps
658
				# module_name		= mdn.mdn_name
659
				# ps				= showInfo (Level2 (
660 661
													(foldl (+++) ("Generating code for " +++ module_name)
															[" "+++cgp_module_name \\ {cgp_module_name}<-busy_processes])
Diederik van Arkel's avatar
Diederik van Arkel committed
662 663
													)) ps
				# (startupdir,ps)	= getStup ps
664 665 666 667
				  (cgen,ps)			= getCurrentCgen ps
				  (neverTimeProfile,ps) = get_neverTimeProfile_option module_name project ps
				  ao				= PR_GetApplicationOptions project
				  timeprofile		= ao.profiling && (not neverTimeProfile)
668
				# free_slot			= hd (removeMembers [0..max_n_processes-1] [cgp_process_n \\ {cgp_process_n} <- busy_processes])
Diederik van Arkel's avatar
Diederik van Arkel committed
669

670
				# (res,obj_path,compiler_process_ids,ps) = StartCodeGenerator cgen updateErrorWindow CodeGeneration abc_path free_slot timeprofile cgo proc ao startupdir compiler_process_ids ps
671
				| not res
Diederik van Arkel's avatar
Diederik van Arkel committed
672
					= (False,rest,busy_processes,fileinfo,abccache,ps)
673
				# busy_processes	= [{cgp_process_n=free_slot,cgp_module_name=module_name,cgp_obj_path=obj_path}:busy_processes]
Diederik van Arkel's avatar
Diederik van Arkel committed
674
				= start_code_generators rest busy_processes fileinfo abccache ps
675
			start_code_generators [!] busy_processes fileinfo abccache ps
676
				# ps = DelayEventLoop ps
677
				= (True,[!],busy_processes,fileinfo,abccache,ps)
678
	# ds = {ds & fileinfo = fileinfo, abccache = abccache, ok = ok}
679
	= cont (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) ds, ps)
680

681 682 683 684 685 686
step intr (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds) ps
	# (ok,busy_processes,project,fileinfo,ps)
		= handle_finished_code_generators busy_processes ds.project ds.fileinfo ps
		with
			handle_finished_code_generators busy_processes=:[|_:_] project fileinfo ps
				# process_handles = {wcgp_process_handle \\ {wcgp_process_handle} <- busy_processes}
687
				# (i,exit_code,ps) = wait_for_finished_code_generator process_handles ps
688 689 690 691 692 693 694 695 696
				| i<0
					= (False,busy_processes,project,fileinfo,ps)
					# (finished_process,busy_processes) = remove_finished_process_from_list i busy_processes
						with
							remove_finished_process_from_list i [p:ps]
								| i==0
									= (p,ps)
									# (fp,ps) = remove_finished_process_from_list (i-1) ps;
									= (fp,[p:ps])
697
					# (ok,ps) = finish_code_generator finished_process.wcgp_process_handle finished_process.wcgp_scg exit_code updateErrorWindow ps
698 699 700
					| ok
						# module_name = finished_process.wcgp_module_name
						  obj_path = finished_process.wcgp_obj_path
701
						# (fileinfo,ps) = accFiles (FI_UpdateObjDate module_name obj_path fileinfo) ps
702 703 704 705 706 707 708 709
						# project = PR_SetCodeGenerated module_name project
						= (True,busy_processes,project,fileinfo,ps)
						= (False,busy_processes,project,fileinfo,ps)
			handle_finished_code_generators [|] project fileinfo ps
				= (True,[],project,fileinfo,ps)
	# ds = {ds & fileinfo = fileinfo, project = project, ok = ds.ok && ok && not intr}
	| not ds.ok
		= cont (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds,ps)
710
	| length busy_processes>=win_max_n_processes || (case paths of [!] -> True ; _ -> False)
711 712 713
		= cont (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds,ps)
	# (ok,paths,busy_processes,fileinfo,abccache,ps) = start_code_generators paths busy_processes ds.fileinfo ds.abccache ps
		with
714 715 716
			start_code_generators :: [!ModuleDirAndName] [WinCodeGeneratorProcess] FileInfoCache *ABCCache !*GeneralSt
						   -> *(Bool,[!ModuleDirAndName],[WinCodeGeneratorProcess],FileInfoCache,*ABCCache,!*GeneralSt )
			start_code_generators paths=:[!mdn:rest] busy_processes fileinfo abccache ps
717 718
				| length busy_processes>=win_max_n_processes
					= (True,paths,busy_processes,fileinfo,abccache,ps)
719 720
				# (abccache,fileinfo,gen,abc_path,ps)
									= check_object_file_out_of_date mdn False abccache fileinfo project ps
721
				# (proc,ps)			= getCurrentProc ps
722
				# ((_,abccache,fileinfo), ps) = FI_GetFileInfo proc mdn abccache fileinfo ps
723 724
				| not gen
					= start_code_generators rest busy_processes fileinfo abccache ps
725
				# module_name		= mdn.mdn_name
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
				# ps				= showInfo (Level2 (
													(foldl (+++) ("Generating code for "+++ module_name)
															[" "+++wcgp_module_name \\ {wcgp_module_name}<-busy_processes])
													)) ps
				# (startupdir,ps)	= getStup ps
				  (cgen,ps)			= getCurrentCgen ps
				  (neverTimeProfile,ps) = get_neverTimeProfile_option module_name project ps
				  ao				= PR_GetApplicationOptions project
				  timeprofile		= ao.profiling && (not neverTimeProfile)
				  cgo				= PR_GetCodeGenOptions project
				# free_slot			= hd (removeMembers [0..win_max_n_processes-1] [wcgp_process_n \\ {wcgp_process_n} <- busy_processes])

				# (res,process_handle,scg,ps)
					= start_code_generator cgen updateErrorWindow abc_path free_slot timeprofile cgo proc startupdir ps
				| not res
					= (False,rest,busy_processes,fileinfo,abccache,ps)
742 743
				# obj_path = ModuleDirAndNameToObjSystemPathname proc mdn
				# new_process = {wcgp_process_n=free_slot,wcgp_process_handle=process_handle,wcgp_scg=scg,wcgp_module_name=module_name,wcgp_obj_path=obj_path}
744 745
				# busy_processes = [new_process:busy_processes]
				= start_code_generators rest busy_processes fileinfo abccache ps
746 747
			start_code_generators [!] busy_processes fileinfo abccache ps
				= (True,[!],busy_processes,fileinfo,abccache,ps)
748 749 750
	# ds = {ds &