PmDriver.icl 76.9 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
	| DComp !Bool !*DirCache !DriverCompilingInfo ![!ModuleDirAndName] !DriverStateRecord
	| DQuitCompilers ![!ModuleDirAndName] !DriverCompilingInfo !DriverStateRecord
119
	| DGene ![!ModuleDirAndName] !DriverCodeGenerationInfo !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 & fileinfo = fileinfo, abccache = abccache, ok = ok}
	= cont (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds, ps)

751
step intr (DLink ds=:{ok, newpaths, fileinfo, libsinfo, modpaths, abccache, project, continue}) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
752
753
	//	Check whether executable is out of date and relink it	if required.
	| intr || not ok
754
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
755
	# lo						= PR_GetLinkOptions project
756
	# (prj_path,ps)				= getProjectFilePath ps
Diederik van Arkel's avatar
Diederik van Arkel committed
757
	# (app_path,ps)				= getStup ps
758
	# (srcpaths,ps)				= get_project_and_environment_paths project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
759
760
761
762
763
764
	// set up dircache for 'Clean System Files'
	# ((errs,warns,abcPathsCache),ps)	= accFiles (DC_Setup (Map MakeSystemPathname srcpaths)) ps
	// need to handle this differently? Now barfs on paths without Clean System File subdirs
	// maybe use variant DC_Setup which ignores nonexistent CSF-dirs...
	# ({be_verbose},ps)			= getPrefs ps
	# ps						= HandleDCErrors be_verbose errs warns ps
765
766
767
	# system_abc				= MakeABCPathname System
	# (ok,full_sys0,_,abcPathsCache) = DC_Search system_abc abcPathsCache
	# full_sys					= full_sys0 +++ DirSeparatorString +++ system_abc
768
	# system_mdn 				= {mdn_dir=full_sys0,mdn_name=System}
Diederik van Arkel's avatar
Diederik van Arkel committed
769
770
771
772
	
	# ao						= PR_GetApplicationOptions project
	// possibly patch _system to correct profiling settings...

773
	# (tp,ps)					= getCurrentProc ps
774
	# ((modinfo,abccache,fileinfo),ps)
775
								= FI_GetFileInfo tp system_mdn abccache fileinfo ps
Diederik van Arkel's avatar
Diederik van Arkel committed
776
777
778
779
	
	# wantstp					= ao.profiling //&& (not co.neverTimeProfile)
	# compile					= /*mp <> info.abcOptions.abcMemoryProfile ||*/ wantstp <> modinfo.abcOptions.abcTimeProfile
	# lines						= if (be_verbose && compile)
780
									(Level3 ["["+++system_abc+++",]: compiled with different options"])
Diederik van Arkel's avatar
Diederik van Arkel committed
781
									(Level3 [])
782
	# ps						= verboseInfo be_verbose lines ps
Diederik van Arkel's avatar
Diederik van Arkel committed
783
784
785
	# (version,ps)				= getCurrentVers ps
	# (patched, ps)				= accFiles