PmDriver.icl 79.1 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
Diederik van Arkel's avatar
Diederik van Arkel committed
4
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

trace_n _ g :== g
24
trace_n` _ g :== g
Diederik van Arkel's avatar
Diederik van Arkel committed
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
53
54
55
56
57
58

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

traceInfo _ ps :== ps
//traceInfo i ps :== showInfo i ps

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

59
:: SetMadeProjectFun :== Bool -> Bool -> Project -> GeneralSt -> GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
60
61

//	Compile /Check Syntax of the designated module
62
CompileProjectModule ::	!CompileOrCheckSyntax !Pathname !Project !SetMadeProjectFun !*GeneralSt -> *GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
63
CompileProjectModule compilerOrCheckSyntax path project setproject ps
64
	# ps					= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
65
66
67
68
69
70
71
72
73
74
	# (syspaths,ps)			= getCurrentPaths ps
	# prjpaths				= PR_GetPaths project
	# srcpaths				= AppendLists prjpaths syspaths
	#! (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
	#! (ps,fileinfo,_,abccache,project,ok,newpaths,_,_)
75
							= CompileTheProjectModule compilerOrCheckSyntax path fileinfo dircache abccache project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
76
77
78
79
	# ps					= setABCCache abccache ps
	# ps					= setFICache fileinfo ps
	= setproject ok newpaths project ps

80
GenAsmProjectModule :: !.Pathname !Project !SetMadeProjectFun !*GeneralSt -> *GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
81
GenAsmProjectModule path project setproject ps
82
	# ps					= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
83
84
85
86
87
88
89
90
91
92
	# (syspaths,ps)			= getCurrentPaths ps
	# prjpaths				= PR_GetPaths project
	# srcpaths				= AppendLists prjpaths syspaths
	# (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
	# (ps,fileinfo,_,abccache,project,ok,newpaths,abcpath,_)
93
							= CompileTheProjectModule Compilation path fileinfo dircache abccache project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
94
95
96
97
98
99
100
101
102
103
	| not ok || newpaths
		# ps				= setABCCache abccache ps
		# ps				= setFICache fileinfo ps
		= setproject True False project ps
	#	(ps,abccache,fileinfo,project,ok,_)
							= GenCodeTheProjectModule True False AsmGeneration abcpath abccache fileinfo project ps
	# ps					= setABCCache abccache ps
	# ps					= setFICache fileinfo ps
	= setproject True ok project ps

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

106
107
:: *DriverCompilingInfo
	= Sync
108
	| AsyncWin ![CurrentlyCompiled] !AsyncWinCompilingInfo
109
110
111
	| Async	![CurrentlyCompiled] !AsyncCompilingInfo
	| Pers	!*CompilingInfo

112
113
114
115
116
::	AsyncWinCompilingInfo = {
		win_max_n_processes :: !Int,
		win_compiler_process_ids :: !CompilerProcessIds
	};

117
118
119
120
121
122
::	AsyncCompilingInfo = {
		max_n_processes :: !Int,
		compiler_process_ids :: !CompilerProcessIds,
		unknown_finished_processors :: !UnknownFinishedProcessors
	};

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
:: *DriverState
	= DInit !Bool !Project !MTPContinuation
	| DComp !Bool !*DirCache !DriverCompilingInfo !(List String) !DriverStateRecord
	| DGene !(List String) !DriverCodeGenerationInfo !DriverStateRecord
	| DLink !DriverStateRecord
	| DDone

:: *DriverStateRecord =
	{ project	:: !Project
	, continue	:: !MTPContinuation
	, fileinfo	:: !FileInfoCache
	, abccache	:: !*ABCCache
	, libsinfo	:: !StaticLibInfo
	, ok		:: !Bool
	, newpaths	:: !Bool
	, modpaths	:: !List String
	}

141
BringProjectUptoDate :: !Bool CleanupCont !*GeneralSt -> *GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
142
143
144
145
146
147
BringProjectUptoDate force continuation ps
	#  (project,ps)		= getProject ps

	#	ps				= PrecompileFase project ps

	#	ps				= showInfo (Level1 "Bring up to date...") ps
148
	#	ps				= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
149
		ini_step		= DInit force project cleanup
150
	= start ini_step step ps
Diederik van Arkel's avatar
Diederik van Arkel committed
151
152
153
154
155
156
157
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???
158
159
160
			= ps
		= ps

161
162
163
	PostlinkFase ok project ps
		| not ok
			= ps
Diederik van Arkel's avatar
Diederik van Arkel committed
164
165
		# (postlink,project)	= PR_GetPostlink project
		| isJust postlink
166
			# (Just post_link)	= postlink
167
			# (prj_path,ps)		= getProjectFilePath ps
168
			# prj_dir_path  = PR_GetRootDir project
169
170
			# (app_path,ps)		= getStup ps
			# post_link			= fulPath app_path prj_dir_path post_link
Diederik van Arkel's avatar
Diederik van Arkel committed
171
			# ps				= showInfo (Level1 "Postlink...") ps
172
			# (ok,ec,ps)		= Execute` ("\""+++post_link+++"\" \""+++prj_path+++"\"") ps
Diederik van Arkel's avatar
Diederik van Arkel committed
173
174
			= ps
		= ps
175

176
	cleanup :: !Bool !Bool !Bool !FileInfoCache !StaticLibInfo !(List Modulename) !Project !Bool (!*ABCCache,!GeneralSt) -> *(!*DriverState,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
177
178
179
	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
180
			# ps			= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
181
182
			= MakeTheProject False fileinfo libsinfo abccache project cleanup` ps

183
		# ps				= PostlinkFase ok project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
		
		# 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

198
:: MTPContinuation :== Bool Bool Bool FileInfoCache StaticLibInfo (List Modulename) Project Bool *(*ABCCache,GeneralSt) -> *(*DriverState,*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
199

200
MakeTheProject :: !Bool !FileInfoCache !StaticLibInfo !*ABCCache !Project !MTPContinuation !GeneralSt -> (!*DriverState,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
MakeTheProject force fileinfo libsinfo abccache project continue ps
	# (syspaths,ps)			= getCurrentPaths ps
	# prjpaths				= PR_GetPaths project
	# srcpaths				= AppendLists prjpaths syspaths
	# ((errs,warns,dircache),ps)
							= accFiles (DC_Setup srcpaths) ps
	# ({be_verbose},ps)		= getPrefs ps
	# ps					= HandleDCErrors be_verbose errs warns ps
	# (root,project)		= PR_GetRootPathName project
	# root					= MakeDefPathname root	// avoid double compilation...
	# inidone				= Nil
	# (env_static_libs,ps)	= getCurrentSlibs ps
	# sfiles				= (StrictListToList(Concat (SL_Libs libsinfo) env_static_libs))
	# (err,ps)				= check_exists sfiles ps
	| isJust err
		# line				= Level3 ["Error: Unable to find static library: '" +++ fromJust err +++ "'."]
		# ps				= showInfo line ps
		= continue False False False fileinfo libsinfo Nil project False (abccache, ps)
	# ((errs,slibs),ps)		= accFiles (getLibs sfiles) ps
	| not (isEmpty errs)
		# line				= Level3 ["Error: Failed reading static libraries: '" :errs]
		# ps				= showInfo line ps
		= continue False False False fileinfo libsinfo Nil project False (abccache, ps)
	# slibs					= ListToStrictList slibs
	# libsinfo				= SL_SetDcls slibs libsinfo
	# ps					= showInfo (Level1 "Compiling...") ps
	# rest					= root :! Nil
	# (method,ps)			= getCurrentMeth ps
229
230
	# (compinfo,ps) = case method of
				CompileSync			-> (Sync,ps)
231
				(CompileAsync cmax)	-> PlatformDependant
232
										(AsyncWin [] {win_max_n_processes=cmax,win_compiler_process_ids=NoCompilerProcessIds},ps)								// win
233
234
235
236
										(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)
237
238
239
240
241
242
243
244
245
246
247
	# ds = 
		{ project	= project
		, continue	= continue
		, fileinfo	= fileinfo
		, abccache	= abccache
		, libsinfo	= libsinfo
		, ok		= True
		, newpaths	= False
		, modpaths	= inidone
		}
	= step False (DComp force dircache compinfo rest ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
248
249
250
251
252
253
254
255
256
257
258
259
260
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 =
	{ iclModule	:: !String
	, options	:: CompilerOptions
	, slot		:: !Int
	}

261
262
263
:: *DriverCodeGenerationInfo
	= SyncCodeGeneration
	| ASyncCodeGeneration ![(Int,String,String)] !AsyncCompilingInfo // [(busy_process_number,abc_path,obj_path)]
264
265
266
267
268
269
270
271
272
273
	| 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,
274
	wcgp_abc_path :: !Pathname,
275
276
277
278
279
280
281
282
283
284
285
286
	wcgp_obj_path :: !Pathname
   }

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
287

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

296
297
298
step True (DComp force dircache (Pers inf) rest ds) ps
	# ds			= {ds & ok = False}
	# (paths,ds)	= ds!modpaths
299
300
	// compile phase finished: kill clean compiler
	# (_,ps)				= ExitCleanCompiler (inf,ps)
301
	= step True (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
302

303
step True (DComp force dircache compinfo rest ds) ps
304
	// need async cocl shootdown as well..
305
306
307
	# ds			= {ds & ok = False}
	# (paths,ds)	= ds!modpaths
	= step True (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
308

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

318
step intr (DComp force dircache Sync (next :! rest) ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
319
	// compile phase: check module 'next'
320
	| StringOccurs next ds.modpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
321
		// if already done then skip
322
		= step intr (DComp force dircache Sync rest ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
323
	# modname					= GetModuleName next
324
325
326
327
328
329
	| isProjLibraryModule modname ds.libsinfo
		// 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
330
	| not ok
331
332
333
334
		# (paths,ds)		= ds!modpaths
		= step intr (DGene paths SyncCodeGeneration ds) ps
	# ds	= {ds & modpaths = next :! ds.modpaths}
	= cont (DComp force dircache compinfo rest ds,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
335

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

347
step intr (DComp force dircache compinfo=:(Pers _) (next :! rest) ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
348
	// compile phase: check module 'next'
349
350
	# ps = trace_n ("comp step",next) ps
	| StringOccurs next 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
Diederik van Arkel's avatar
Diederik van Arkel committed
353
	# modname					= GetModuleName next
354
355
	| isProjLibraryModule modname ds.libsinfo
		// instead of testing explicitly put libmodules in done <= conflicts with other administration
356
		= step intr (DComp force dircache compinfo rest ds) ps
357
358
359
	# (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
360
	| not ok
361
362
363
364
365
		# (Pers inf)		= compinfo
		# (paths,ds)		= ds!modpaths
		= step intr (DGene paths SyncCodeGeneration ds) ps
	# ds	= {ds & modpaths = next :! ds.modpaths}
	= 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}) Nil 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
Diederik van Arkel's avatar
Diederik van Arkel committed
370
	# (modpaths,project)	= PR_GetModulenames True IclMod 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}) Nil ds) ps
378
379
380
381
	// compile phase finished: remove all modules not (indirectly) imported by main module
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
	# (modpaths,project)	= PR_GetModulenames True IclMod project
	# 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 (ASyncCodeGenerationWin [] win_max_n_processes) ds) ps
386

387
step intr state=:(DComp force _ (Async _ _) _ _) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
388
	# ps					= traceInfo (Level3 ["check_completed..."]) ps
389
	# (state, ps)			= check_completed state ps
Diederik van Arkel's avatar
Diederik van Arkel committed
390
	# ps					= traceInfo (Level3 ["start_compilations..."]) ps
391
	# (state, ps)			= start_compilations state ps
Diederik van Arkel's avatar
Diederik van Arkel committed
392
393
	= cont (state, ps)
	where
394
		check_completed :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
395
396
		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
397
398
399
400
				(NoFinishedCompiler,ps)
					-> check_unknow_processors_are_known state ps
				(UnknownFinishedCompiler,ps)
					-> case state of
401
						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
402
							# unknown_finished_processors = add_unknown_finished_processor unknown_finished_processors
403
							# 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
404
405
406
407
408
409
410
411
							-> check_completed state ps
				(FinishedCompiler completedSlot exitcode,ps)
					# ps = traceInfo (Level3 ["process_completed...",toString completedSlot,toString 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

412
413
414
		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
415
416
417
				# (state,ps) = handle_completed_processes 0 state ps
					with
						handle_completed_processes process_n state ps
418
							| process_n>=max_n_processes
Diederik van Arkel's avatar
Diederik van Arkel committed
419
420
421
422
423
424
425
426
427
428
429
430
431
432
								= (state,ps)
							| isMember process_n known_finished_processors
								= handle_completed_processes (process_n+1) state ps
								# (_,ps) = SendRepeatResult process_n ps
								/*
								# exitcode = 1
								# ps = traceInfo (Level3 ["process_completed...",toString process_n,toString exitcode]) ps
								#! (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)

433
		process_completed :: !Int !Int !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
434
		process_completed completedSlot exitcode (DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors}) todo ds) ps
435
436
437
			# (completed, current)			= removeFromCurrent completedSlot current
			# unknown_finished_processors	= remove_from_unknown_finished_processors completedSlot unknown_finished_processors
			# (startupdir,ps)				= getStup ps
438
439
			# (interact, ps)				= getInteract ps
			#  typewin = update_type_window interact (GetModuleName completed.iclModule)
440
			# ccstring						= "dummy ccstring for now.."
441
			# (abcpath,res,ps)				= CompileHandleExitCode exitcode ccstring startupdir completedSlot updateErrorWindow typewin 
442
												completed.iclModule completed.options.listTypes ps // types param
443
444
			# (_,(ps,fileinfo,dircache,abccache,project,ok,newpaths`,_,deps))
											= ProcessCompilerMsg Nothing Compilation completed.options completed.iclModule abcpath res ds.fileinfo dircache ds.abccache ds.project ps
445
			# ds							= {ds & newpaths = ds.newpaths || newpaths`, fileinfo = fileinfo, abccache = abccache, project = project, ok = ok}
446
447
448
			| ok				
				# ds = {ds & modpaths = icl_to_dcl_file_name completed.iclModule :! ds.modpaths}
				= (DComp force dircache (Async current {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) (Concat deps todo) ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
449
			// not ok
450
				# (os_error,ps) = ClearCompilerCaches compiler_process_ids ps;
451
452
				# (paths,ds)	= ds!modpaths
				= (DGene paths SyncCodeGeneration ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
453
454
455
456
457
458
459
460
461
462
463
			where
				removeFromCurrent :: Int [CurrentlyCompiled] -> (CurrentlyCompiled, [CurrentlyCompiled])
				removeFromCurrent _ []
					=	abort "driver.icl: unknown threadId"
				removeFromCurrent completedSlot [current=:{slot} : rest]
					| completedSlot == slot
						=	(current, rest)
					// otherwise
						# (completed, rest) = removeFromCurrent completedSlot rest
						= (completed, [current : rest])

464
		start_compilations :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
465
		start_compilations state=:(DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors}) (next :! rest) ds) ps
466
			// all threads used?
467
468
			| length current >= max_n_processes
				# ps = DelayEventLoop ps;			
Diederik van Arkel's avatar
Diederik van Arkel committed
469
				= (state, ps)
470
			// compile phase: check module 'next'
471
472
473
			# next_icl = dcl_to_icl_file_name next;
			| StringOccurs next ds.modpaths || currently_compiled next_icl current
				= 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
Diederik van Arkel's avatar
Diederik van Arkel committed
474
			# modname = GetModuleName next
475
476
			| isProjLibraryModule modname ds.libsinfo
				// instead of testing explicitly put libmodules in done <= conflicts with other administration
477
				= (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)
478
			# (ps,dircache,ok,_,rest,compinfo,ds,_)
479
				= 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
480
			# ds = {ds & ok = ok}
Diederik van Arkel's avatar
Diederik van Arkel committed
481
			| not ok
482
				# (os_error,ps) = ClearCompilerCaches compiler_process_ids ps;
483
484
485
				#! (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
486
487
		start_compilations state ps
//			# ps = traceInfo (Level3 ["start_compilations no next..."]) ps
488
			# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
489
490
491
492
			= (state, ps)

		currently_compiled :: String [CurrentlyCompiled] -> Bool
		currently_compiled next current
493
			=	or [c.iclModule == next	\\ c <- current]
Diederik van Arkel's avatar
Diederik van Arkel committed
494
495
496
497
498
499
500
501

step intr state=:(DComp force dircache compinfo=:(AsyncWin _ _) rest ds) ps
	# ps					= traceInfo (Level3 ["check_completed..."]) ps
	# (state, ps) = check_completed state ps
	# ps					= traceInfo (Level3 ["start_compilations..."]) ps
	# (state, ps) = start_compilations state ps
	= cont (state, ps)
	where
502
		check_completed :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
503
504
		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
505
506
507
508
					(NoFinishedCompiler, ps)
						-> (state, ps)
					(FinishedCompiler completedSlot exitcode, ps)
						#! (state,ps) = process_completed completedSlot exitcode state ps
509
510
511
						-> IF_BATCHBUILD_OR_IDE
								(state,ps)
								(check_completed state ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
512
513
514
515
516
					(UnknownFinishedCompiler,ps)
						-> (state, ps)	// -> doesn't occur on win
		check_completed state ps
			=	(state, ps)

517
		process_completed :: !Int !Int !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
518
		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
519
520
			# (completed, current)	= removeFromCurrent completedSlot current
			# (startupdir,ps)		= getStup ps
521
522
			# (interact, ps)		= getInteract ps
			# typewin				= update_type_window interact (GetModuleName completed.iclModule)
Diederik van Arkel's avatar
Diederik van Arkel committed
523
			# ccstring				= "dummy ccstring for now.."
524
			# (abcpath,res,ps)		= CompileHandleExitCode exitcode ccstring startupdir completedSlot updateErrorWindow typewin 
Diederik van Arkel's avatar
Diederik van Arkel committed
525
										completed.iclModule completed.options.listTypes ps // types param
526
527
			# (_,(ps,fileinfo,dircache,abccache,project,ok,newpaths`,_,deps))
				= 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
528
529
			# ds					= {ds & newpaths = ds.newpaths || newpaths`, fileinfo = fileinfo, abccache = abccache, project = project, ok = ok}
			| ok
530
531
				# ds = {ds & modpaths = icl_to_dcl_file_name completed.iclModule :! ds.modpaths}
				= (DComp force dircache (AsyncWin current {win_max_n_processes=win_max_n_processes,win_compiler_process_ids=win_compiler_process_ids}) (Concat deps todo) ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
532
533
			// not ok
				# (paths,ds)	= ds!modpaths
534
				# ps = app_world_instead_of_ps (QuitCleanCompiler True win_compiler_process_ids) ps;
Diederik van Arkel's avatar
Diederik van Arkel committed
535
536
537
538
539
540
541
542
543
544
545
546
				= (DGene paths SyncCodeGeneration ds, ps)
			where
				removeFromCurrent :: Int [CurrentlyCompiled] -> (CurrentlyCompiled, [CurrentlyCompiled])
				removeFromCurrent _ []
					=	abort "driver.icl: unknown threadId"
				removeFromCurrent completedSlot [current=:{slot} : rest]
					| completedSlot == slot
						=	(current, rest)
					// otherwise
						# (completed, rest) = removeFromCurrent completedSlot rest
						= (completed, [current : rest])

547
		start_compilations :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
548
549
550
		start_compilations state=:(DComp force dircache (AsyncWin current {win_max_n_processes,win_compiler_process_ids}) (next :! rest) ds) ps
			| length current >= win_max_n_processes
				# ps = DelayEventLoop ps;			
Diederik van Arkel's avatar
Diederik van Arkel committed
551
552
				= (state, ps)
		// compile phase: check module 'next'
553
554
555
			# next_icl = dcl_to_icl_file_name next;
			| StringOccurs next ds.modpaths || currently_compiled next_icl current
				= 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
Diederik van Arkel's avatar
Diederik van Arkel committed
556
557
558
			# modname = GetModuleName next
			| isProjLibraryModule modname ds.libsinfo
				// instead of testing explicitly put libmodules in done <= conflicts with other administration
559
				= (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
560
			# (ps,dircache,ok,_,rest,compinfo,ds,_)
561
				= 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
562
563
564
			# ds = {ds & ok = ok}
			| not ok
				#! (paths,ds)	= ds!modpaths
565
				# ps = app_world_instead_of_ps (QuitCleanCompiler True win_compiler_process_ids) ps;
Diederik van Arkel's avatar
Diederik van Arkel committed
566
567
				= (DGene paths SyncCodeGeneration ds, ps)
			= start_compilations (DComp force dircache compinfo rest ds) ps
568
569
		start_compilations state=:(DComp force dircache (AsyncWin [] _) Nil ds) ps
			= (state, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
570
		start_compilations state ps
571
			# ps = DelayEventLoop ps;
Diederik van Arkel's avatar
Diederik van Arkel committed
572
573
574
575
576
			= (state, ps)

		currently_compiled :: String [CurrentlyCompiled] -> Bool
		currently_compiled next current
			=	or [c.iclModule == next \\ c <- current]
577

578
step intr (DGene Nil SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
579
	#! ps	= showInfo (Level1 "Linking...") ps
580
	= step intr (DLink ds) ps
581

582
583
step intr (DGene Nil (ASyncCodeGeneration [] {unknown_finished_processors=NoUnknownFinishedProcessors,compiler_process_ids}) ds) ps
	# ps = setCompilerProcessIds compiler_process_ids ps
Diederik van Arkel's avatar
Diederik van Arkel committed
584
	#! ps	= showInfo (Level1 "Linking...") ps
585
	= step intr (DLink ds) ps
586

587
588
589
590
step intr (DGene Nil (ASyncCodeGenerationWin [] _) ds) ps
	#! ps	= showInfo (Level1 "Linking...") ps
	= step intr (DLink ds) ps

591
592
593
594
595
596
597
step intr (DGene (path:!rest) SyncCodeGeneration ds) ps
	| not ds.ok || intr
		# ds = {ds & ok = False}
		= step intr (DLink ds) ps
	# (ps,abccache,fileinfo,gen,abcpath)	= CheckABCOutOfDate False path ds.abccache ds.fileinfo ds.project ps
	# (ps,abccache,fileinfo,project,ok,_)	= GenCodeTheProjectModule gen False CodeGeneration abcpath abccache fileinfo ds.project ps
	# ds = {ds & abccache = abccache, fileinfo = fileinfo, project = project, ok = ok}
Diederik van Arkel's avatar
Diederik van Arkel committed
598
	| not ok
599
600
		= step intr (DLink ds) ps
	= cont (DGene rest SyncCodeGeneration ds, ps)
601

602
step intr (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes,compiler_process_ids,unknown_finished_processors}) ds) ps
603
604
	# (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
605
606
		with
			handle_finished_code_generators busy_processes=:[_:_] unknown_finished_processors project fileinfo ps
607
				= case (CompilePollCompleted compiler_process_ids ps) of
Diederik van Arkel's avatar
Diederik van Arkel committed
608
609
610
611
612
613
614
615
616
617
					(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
618
						# (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
619
							with
620
								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
621
622
									| finished_cg_slot_n==slot
										= (abc_path,obj_path,rest)
623
										# (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
624
										= (abc_path,obj_path,[busy_process:rest])
625
								get_paths_and_remove_process_from_list finished_cg_slot_n []
Diederik van Arkel's avatar
Diederik van Arkel committed
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
									= abort "driver.icl: unknown code generator id"
						| exit_code==0
							# (fileinfo,ps) = accFiles (FI_UpdateObjDate abc_path obj_path fileinfo) ps
							# project = PR_SetCodeGenerated (GetModuleName abc_path) project
							-> 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
647
									# (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
648
										with
649
											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
650
651
												| process_n==slot
													= (abc_path,obj_path,rest)
652
													# (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
653
													= (abc_path,obj_path,[busy_process:rest])
654
											get_paths_and_remove_process_from_list finished_cg_slot_n []
Diederik van Arkel's avatar
Diederik van Arkel committed
655
656
657
658
659
660
661
662
												= 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)
663
664
	# ds = {ds & fileinfo = fileinfo, project = project, ok = ds.ok && ok && not intr}
	| not ds.ok
665
666
667
668
		= 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)
	| (length busy_processes>=max_n_processes || (case paths of Nil -> True ; _ -> False))
		# 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)
669
	# (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
670
		with
671
			start_code_generators :: (List {#Char}) [(Int,{#Char},{#Char})] FileInfoCache *ABCCache !*GeneralSt -> *(.Bool,(List {#Char}),[(Int,{#Char},{#Char})],FileInfoCache,*ABCCache,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
672
673
			start_code_generators paths=:(path :! rest) busy_processes fileinfo abccache ps
				| length busy_processes>=max_n_processes
674
		 			# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
675
					= (True,paths,busy_processes,fileinfo,abccache,ps)
676
677
678
				# (ps,abccache,fileinfo,gen,abc_path)
									= CheckABCOutOfDate False path abccache fileinfo project ps
				# cgo				= PR_GetCodeGenOptions project
679
				# (proc,ps)			= getCurrentProc ps
680
				# ((abccache,fileinfo,info), ps)
681
									= FI_GetFileInfo proc abc_path abccache fileinfo ps
Diederik van Arkel's avatar
Diederik van Arkel committed
682
683
				| not gen
					= start_code_generators rest busy_processes fileinfo abccache ps
684
				# ps				= showInfo (Level2 (
Diederik van Arkel's avatar
Diederik van Arkel committed
685
686
687
688
689
690
691
692
693
694
695
696
													(foldl (+++) ("Generating code for "
																	+++ RemovePath abc_path) [" "+++RemovePath abc_path \\ (_,abc_path,_)<-busy_processes])
													)) ps
				# (startupdir,ps)	= getStup ps
				# (cgen,ps)			= getCurrentCgen ps
				# ao				= PR_GetApplicationOptions project
				# (prefs,ps)		= getPrefs ps
				# defaultCO			= prefs.compopts
				# modname			= GetModuleName abc_path
				# co				= case (PR_GetModuleInfo modname project) of
										Just modinfo	-> modinfo.compilerOptions
										_				-> defaultCO
697
				# timeprofile		= ao.profiling && (not co.neverTimeProfile)
Diederik van Arkel's avatar
Diederik van Arkel committed
698
699
700
701
702
				# free_slot			= hd (removeMembers [0..max_n_processes-1] [slot \\ (slot,_,_) <- busy_processes])				

//				# ps  = trace ("code generator started "+++toString free_slot+++"\n") ps
//				# ps  = trace ("s "+++toString free_slot+++" ") ps

703
				# (res,obj_path,compiler_process_ids,ps) = StartCodeGenerator cgen updateErrorWindow CodeGeneration abc_path free_slot timeprofile cgo proc ao startupdir compiler_process_ids ps
Diederik van Arkel's avatar
Diederik van Arkel committed
704
705
706
707
708
				| not res				
					= (False,rest,busy_processes,fileinfo,abccache,ps)
				# busy_processes	= [(free_slot,abc_path,obj_path):busy_processes]
				= start_code_generators rest busy_processes fileinfo abccache ps
			start_code_generators Nil busy_processes fileinfo abccache ps
709
				# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
710
				= (True,Nil,busy_processes,fileinfo,abccache,ps)
711
	# ds = {ds & fileinfo = fileinfo, abccache = abccache, ok = ok}
712
	= 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)
713

714
715
716
717
718
719
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}
720
				# (i,exit_code,ps) = wait_for_finished_code_generator process_handles ps
721
722
723
724
725
726
727
728
729
				| 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])
730
					# (ok,ps) = finish_code_generator finished_process.wcgp_process_handle finished_process.wcgp_scg exit_code updateErrorWindow ps
731
732
733
					| ok
						# module_name = finished_process.wcgp_module_name
						  obj_path = finished_process.wcgp_obj_path
734
735
						  abc_path = finished_process.wcgp_abc_path
						# (fileinfo,ps) = accFiles (FI_UpdateObjDate abc_path obj_path fileinfo) ps
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
						# 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)
	| length busy_processes>=win_max_n_processes || (case paths of Nil -> True ; _ -> False)
		= 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
			start_code_generators :: (List {#Char}) [WinCodeGeneratorProcess] FileInfoCache *ABCCache !*GeneralSt
						   -> *(Bool,(List {#Char}),[WinCodeGeneratorProcess],FileInfoCache,*ABCCache,!*GeneralSt )
			start_code_generators paths=:(mdn:!rest) busy_processes fileinfo abccache ps
				| length busy_processes>=win_max_n_processes
					= (True,paths,busy_processes,fileinfo,abccache,ps)
				# (ps,abccache,fileinfo,gen,abc_path)
									= CheckABCOutOfDate False mdn abccache fileinfo project ps
				# (proc,ps)			= getCurrentProc ps
				# ((abccache,fileinfo,_), ps) = FI_GetFileInfo proc mdn abccache fileinfo ps
				| not gen
					= start_code_generators rest busy_processes fileinfo abccache ps
				# module_name		= GetModuleName mdn
				# 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)
				# obj_path = MakeObjSystemPathname proc mdn
777
778
				# abc_path = MakeABCSystemPathname 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,wcgp_abc_path=abc_path}
779
780
781
782
783
784
785
				# busy_processes = [new_process:busy_processes]
				= start_code_generators rest busy_processes fileinfo abccache ps
			start_code_generators Nil busy_processes fileinfo abccache ps
				= (True,Nil,busy_processes,fileinfo,abccache,ps)
	# ds = {ds & fileinfo = fileinfo, abccache = abccache, ok = ok}
	= cont (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds, ps)

786
step intr (DLink ds=:{ok, newpaths, fileinfo, libsinfo, modpaths, abccache, project, continue}) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
787
788
	//	Check whether executable is out of date and relink it	if required.
	| intr || not ok
789
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
790
	# lo						= PR_GetLinkOptions project
791
	# (prj_path,ps)				= getProjectFilePath ps
Diederik van Arkel's avatar
Diederik van Arkel committed
792
793
794
795
796
797
798
799
800
801
802
803
	# (app_path,ps)				= getStup ps
	# (defpaths,ps)				= getCurrentPaths ps
	# prjpaths					= PR_GetPaths project
	# srcpaths					= AppendLists prjpaths defpaths

	// 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
	# (ok,full_sys0,_,abcPathsCache) = DC_Search (MakeABCPathname System) abcPathsCache
804
	# full_sys					= full_sys0 +++ DirSeparatorString +++ (MakeABCPathname System)
Diederik van Arkel's avatar
Diederik van Arkel committed
805
806
807
808
809
	# full_sys`					= MakeImpPathname full_sys
	
	# ao						= PR_GetApplicationOptions project
	// possibly patch _system to correct profiling settings...

810
	# (tp,ps)					= getCurrentProc ps
Diederik van Arkel's avatar
Diederik van Arkel committed
811
812
813
814
815
816
817
818
	# ((abccache,fileinfo,modinfo),ps)
								= FI_GetFileInfo tp  full_sys` abccache fileinfo ps
	
	# wantstp					= ao.profiling //&& (not co.neverTimeProfile)
	# compile					= /*mp <> info.abcOptions.abcMemoryProfile ||*/ wantstp <> modinfo.abcOptions.abcTimeProfile
	# lines						= if (be_verbose && compile)
									(Level3 ["["+++(MakeABCPathname System)+++",]: compiled with different options"])
									(Level3 [])
819
	# ps						= verboseInfo be_verbose lines ps
Diederik van Arkel's avatar
Diederik van Arkel committed
820
821
822
823
824
	# (version,ps)				= getCurrentVers ps
	# (patched, ps)				= accFiles (PatchSystemABC version compile full_sys /*ao.memoryProfiling*/ wantstp) ps
	| not patched
		# line					= Level3 ["Error: ["+++(MakeABCPathname System)+++",]: could not be patched."]
		# ps					= showInfo line ps
825
826
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
	# ((abcdate,fileinfo), ps)	= accFiles (FI_UpdateAbcDate full_sys` full_sys wantstp fileinfo) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
827
828
829
830
831
832
	# (ps,abccache,fileinfo,genabc,abcpath)
								// check _system module out of date
								= CheckABCOutOfDate True full_sys` abccache fileinfo project ps
	# (ps,abccache,fileinfo,project,ok,system_obj_path)
								// if out of date regenerate
								= GenCodeTheProjectModule genabc True CodeGeneration abcpath abccache fileinfo project ps
833
	# (sys_date, ps)			= accFiles (FModified full_sys) ps
834
	# sys_obj					= full_sys0 +++ DirSeparatorString +++ (MakeObjPathname tp System)
835
836
	# (sys_obj_date,ps)			= accFiles (FModified sys_obj) ps
	# sys_obj_date_time			= DATEtoDateTime sys_obj_date
Diederik van Arkel's avatar
Diederik van Arkel committed
837
	# (abcPathsCache,ps)		= case genabc of
Diederik van Arkel's avatar
Diederik van Arkel committed
838
									True
839
										-> (DC_Update ((MakeObjPathname tp System),full_sys0,sys_obj_date_time) abcPathsCache,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
840
												// need to check if line above actually works now...
Diederik van Arkel's avatar
Diederik van Arkel committed
841
842
									False
										-> (abcPathsCache,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
843
	| not ok
844
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
845

846
847
848
849
850
851
852
	# ((ok,_,_,_,sys_objs,sys_libs,abccache),ps)
								= accFiles (ParseABCDependencies` abcpath sys_date abccache) ps
	| not ok
		# line					= Level3 ["Error: ["+++(MakeABCPathname System)+++",]: could not be analysed."]
		# ps					= showInfo line ps
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
	
Diederik van Arkel's avatar
Diederik van Arkel committed
853
	# execpath					= PR_GetExecPath project
854
	# prj_path` = PR_GetRootDir project
Diederik van Arkel's avatar
Diederik van Arkel committed
855
856
857
	# execpath					= fulPath app_path prj_path` execpath
	# ps						= showInfo (Level2 ("Linking '" +++ RemovePath execpath +++ "'")) ps
	
858
859
	# (use_64_bit_processor,ps) = getCurrent64BitProcessor ps

Diederik van Arkel's avatar
Diederik van Arkel committed
860
	// runtime objects and dynamic libs
861
	# stdl						= Concat sys_libs (standardStaticLibraries tp lo.method)
862
	# stdo						= Concat sys_objs (standardObjectFiles ao.stack_traces ao.profiling tp use_64_bit_processor)
Diederik van Arkel's avatar
Diederik van Arkel committed
863
864
865
866
867
868
869
870
871
872
873
	# (stdoOk,ofiles,abcPathsCache)
								= case ao.standard_rte of
									True	-> GetPathNames stdo Nil abcPathsCache
									False	-> (True,Nil,abcPathsCache)
	# (stdlOk,lfiles,abcPathsCache)
								= case ao.standard_rte of
									True	-> GetPathNames stdl Nil abcPathsCache
									False	-> (True,Nil,abcPathsCache)
	| not stdoOk
		# line					= Level3 ["Link error: File: '" +++ (Head ofiles) +++ "' not found."]
		# ps					= showInfo line ps
874
		= continue False newpaths <