PmDriver.icl 77.3 KB
Newer Older
Diederik van Arkel's avatar
Diederik van Arkel committed
1 2 3 4 5 6 7 8 9
implementation module PmDriver

import StdArray, StdBool, StdList, StdMisc, StdEnum
import StdPSt, StdSystem, StdPStClass, StdTimer
import StdWindow

import UtilNewlinesFile, UtilIO

import IdeState
10

11
from typewin import updateTypeWindow, tw_safe_close, class Typer, :: TypeWinInfo
Diederik van Arkel's avatar
Diederik van Arkel committed
12
from typeatt import typeWinKeyboard, typeWinMouse
13
from errwin  import updateErrorWindow, ew_safe_close
Diederik van Arkel's avatar
Diederik van Arkel committed
14
from messwin import showInfo, :: InfoMessage(..)
Diederik van Arkel's avatar
Diederik van Arkel committed
15
from projwin import pm_update_project_window
16

17 18
import PmCallBack

19 20 21 22
import PmCleanSystem
import PmPath
import PmProject
from PmDialogues import doPathsDialog
23
import PmAbcMagic
Diederik van Arkel's avatar
Diederik van Arkel committed
24 25
import PmFileInfo
import PmDirCache
26

Diederik van Arkel's avatar
Diederik van Arkel committed
27
import interrupt,Platform
28
from StdLibMisc import :: Date{..}, :: Time{..}
Diederik van Arkel's avatar
Diederik van Arkel committed
29 30

//from dodebug import trace_n`
31
//import nodebug
32
//import dodebug
Diederik van Arkel's avatar
Diederik van Arkel committed
33
trace_n _ g :== g
34 35
trace_n` _ g :== g
//from StdDebug import trace_r
Diederik van Arkel's avatar
Diederik van Arkel committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
//--

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

74
:: SetMadeProjectFun :== Bool -> Bool -> Project -> GeneralSt -> GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
75 76

//	Compile /Check Syntax of the designated module
77
CompileProjectModule ::	!CompileOrCheckSyntax !Pathname !Project !SetMadeProjectFun !*GeneralSt -> *GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
78
CompileProjectModule compilerOrCheckSyntax path project setproject ps
79
	# ps					= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
80 81 82 83 84 85 86 87 88 89
	# (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,_,_)
90
							= CompileTheProjectModule compilerOrCheckSyntax path fileinfo dircache abccache project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
91 92 93 94
	# ps					= setABCCache abccache ps
	# ps					= setFICache fileinfo ps
	= setproject ok newpaths project ps

95
GenAsmProjectModule :: !.Pathname !Project !SetMadeProjectFun !*GeneralSt -> *GeneralSt
Diederik van Arkel's avatar
Diederik van Arkel committed
96
GenAsmProjectModule path project setproject ps
97
	# ps					= ClearCompilerCache` ps
Diederik van Arkel's avatar
Diederik van Arkel committed
98 99 100 101 102 103 104 105 106 107
	# (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,_)
108
							= CompileTheProjectModule Compilation path fileinfo dircache abccache project ps
Diederik van Arkel's avatar
Diederik van Arkel committed
109 110 111 112 113 114 115 116 117 118
	| 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

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

121 122
:: *DriverCompilingInfo
	= Sync
123
	| AsyncWin ![CurrentlyCompiled] !AsyncWinCompilingInfo
124 125 126
	| Async	![CurrentlyCompiled] !AsyncCompilingInfo
	| Pers	!*CompilingInfo

127 128 129 130 131
::	AsyncWinCompilingInfo = {
		win_max_n_processes :: !Int,
		win_compiler_process_ids :: !CompilerProcessIds
	};

132 133 134 135 136 137
::	AsyncCompilingInfo = {
		max_n_processes :: !Int,
		compiler_process_ids :: !CompilerProcessIds,
		unknown_finished_processors :: !UnknownFinishedProcessors
	};

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

	#	ps				= ew_safe_close ps							// close error window
	#	ps				= tw_safe_close ps							// close types window

	#	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 150

	#!	(intr_info,ps) 	= getInterrupt ps
Diederik van Arkel's avatar
Diederik van Arkel committed
151
//		(interact,ps) 	= getInteract ps
Diederik van Arkel's avatar
Diederik van Arkel committed
152 153 154 155 156 157 158 159 160 161
		ini_step		= DInit force project cleanup
	#	ps				= StartIntr intr_info ini_step step ps
	= ps
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???
162 163 164
			= ps
		= ps

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

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

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

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

204
MakeTheProject :: !Bool !FileInfoCache !StaticLibInfo !*ABCCache !Project !MTPContinuation !GeneralSt -> (!*DriverState,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
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
233 234
	# (compinfo,ps) = case method of
				CompileSync			-> (Sync,ps)
235
				(CompileAsync cmax)	-> PlatformDependant
236
										(AsyncWin [] {win_max_n_processes=cmax,win_compiler_process_ids=NoCompilerProcessIds},ps)								// win
237 238 239 240
										(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)
241 242 243 244 245 246 247 248 249 250 251
	# 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
252 253 254 255 256 257 258 259 260 261 262 263 264
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
	}

265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
:: *DriverCodeGenerationInfo
	= SyncCodeGeneration
	| ASyncCodeGeneration ![(Int,String,String)] !AsyncCompilingInfo // [(busy_process_number,abc_path,obj_path)]

:: *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
	}

Diederik van Arkel's avatar
Diederik van Arkel committed
287 288
//--

289
cont :: !*(.a,!*GeneralSt) -> *(.a,!*GeneralSt);
Diederik van Arkel's avatar
Diederik van Arkel committed
290 291 292 293 294
cont (ls,ps)
	# (intr_info,ps) 	= getInterrupt ps
	# ps				= ContIntr intr_info ps
	= (ls,ps)

295
stop :: !*(.a,!*GeneralSt) -> *(.a,!*GeneralSt);
Diederik van Arkel's avatar
Diederik van Arkel committed
296 297 298 299 300
stop (ls,ps)
	# (intr_info,ps) 	= getInterrupt ps
	# ps				= StopIntr intr_info ps
	= (ls,ps)

301
step :: !Bool !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
Diederik van Arkel's avatar
Diederik van Arkel committed
302
step intr (DInit force project setproject) ps
303
//	# ps				= showInfo (Level1 "Make the project...") ps
Diederik van Arkel's avatar
Diederik van Arkel committed
304 305 306 307 308
	# libsinfo			= PR_GetStaticLibsInfo project
	# (abccache,ps)		= getABCCache ps
	# (fileinfo,ps)		= getFICache` ps
	= MakeTheProject force fileinfo libsinfo abccache project setproject ps

309 310 311
step True (DComp force dircache (Pers inf) rest ds) ps
	# ds			= {ds & ok = False}
	# (paths,ds)	= ds!modpaths
312 313
	// compile phase finished: kill clean compiler
	# (_,ps)				= ExitCleanCompiler (inf,ps)
314
	= step True (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
315

316
step True (DComp force dircache compinfo rest ds) ps
317
	// need async cocl shootdown as well..
318 319 320
	# ds			= {ds & ok = False}
	# (paths,ds)	= ds!modpaths
	= step True (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
321

322
step intr (DComp force dircache Sync Nil ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
323
	// compile phase finished: remove all modules not (indirectly) imported by main module
324
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
Diederik van Arkel's avatar
Diederik van Arkel committed
325
	# (modpaths,project)	= PR_GetModulenames True IclMod project
326
	# ds					= {ds & modpaths = modpaths, project = project}
Diederik van Arkel's avatar
Diederik van Arkel committed
327
	# ps					= showInfo (Level1 "Generating...") ps
328 329
	# (paths,ds)			= ds!modpaths
	= step intr (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
330

331
step intr (DComp force dircache Sync (next :! rest) ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
332
	// compile phase: check module 'next'
333
	| StringOccurs next ds.modpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
334
		// if already done then skip
335
		= step intr (DComp force dircache Sync rest ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
336
	# modname					= GetModuleName next
337 338 339 340 341 342
	| 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
343
	| not ok
344 345 346 347
		# (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
348

349
step intr (DComp force dircache (Pers inf) Nil ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
350 351 352
	// compile phase finished: kill clean compiler
	# (_,ps)				= ExitCleanCompiler (inf,ps)
	// compile phase finished: remove all modules not (indirectly) imported by main module
353
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
Diederik van Arkel's avatar
Diederik van Arkel committed
354
	# (modpaths,project)	= PR_GetModulenames True IclMod project
355
	# ds					= {ds & modpaths = modpaths, project = project}
Diederik van Arkel's avatar
Diederik van Arkel committed
356 357
	# ps					= showInfo (Level1 "Generating...") ps
//XXX	= step intr (DGene True newpaths fileinfo libsinfo modpaths modpaths abccache project setproject) ps
358 359
	# (paths,ds)			= ds!modpaths
	= step intr (DGene paths SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
360

361
step intr (DComp force dircache compinfo=:(Pers _) (next :! rest) ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
362
	// compile phase: check module 'next'
363 364
	# ps = trace_n ("comp step",next) ps
	| StringOccurs next ds.modpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
365
		// if already done then skip
366
		= step intr (DComp force dircache compinfo rest ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
367
	# modname					= GetModuleName next
368 369
	| isProjLibraryModule modname ds.libsinfo
		// instead of testing explicitly put libmodules in done <= conflicts with other administration
370
		= step intr (DComp force dircache compinfo rest ds) ps
371 372 373 374
	# ps = trace_n ("update",next) ps
	# (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
375
	| not ok
376 377 378 379 380 381
		# (Pers inf)		= compinfo
		# (_,ps)			= trace_n "exit compiler!" ExitCleanCompiler (inf,ps)
		# (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)
382

383
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
384
	// compile phase finished: remove all modules not (indirectly) imported by main module
385
	# project				= PR_SetBuilt ds.modpaths ds.project	// removes unused modules
Diederik van Arkel's avatar
Diederik van Arkel committed
386
	# (modpaths,project)	= PR_GetModulenames True IclMod project
387
	# ds					= {ds & modpaths = modpaths, project = project}
388
	# (os_error,ps)			= ClearCompilerCaches compiler_process_ids ps;
Diederik van Arkel's avatar
Diederik van Arkel committed
389
	# ps					= showInfo (Level1 "Generating...") ps
390
	# (paths,ds)			= ds!modpaths
391
	= step intr (DGene paths (ASyncCodeGeneration [] async_compiling_info) ds) ps
392 393

step intr (DComp force dircache (AsyncWin [] {win_compiler_process_ids}) Nil ds) ps
394 395 396 397
	// 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}
398
	# ps = {ps & io=QuitCleanCompiler True win_compiler_process_ids ps.io};
399 400 401
	# ps					= showInfo (Level1 "Generating...") ps
	# (paths,ds)			= ds!modpaths
	= step intr (DGene paths SyncCodeGeneration ds) ps
402

403
step intr state=:(DComp force _ (Async _ _) _ _) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
404
	# ps					= traceInfo (Level3 ["check_completed..."]) ps
405
	# (state, ps)			= check_completed state ps
Diederik van Arkel's avatar
Diederik van Arkel committed
406
	# ps					= traceInfo (Level3 ["start_compilations..."]) ps
407
	# (state, ps)			= start_compilations state ps
Diederik van Arkel's avatar
Diederik van Arkel committed
408 409
	= cont (state, ps)
	where
410
		check_completed :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
411
		check_completed state=:(DComp force _ (Async current=:[_:_] {max_n_processes}) _ _)  ps
Diederik van Arkel's avatar
Diederik van Arkel committed
412 413 414 415 416
			= case (CompilePollCompleted ps) of
				(NoFinishedCompiler,ps)
					-> check_unknow_processors_are_known state ps
				(UnknownFinishedCompiler,ps)
					-> case state of
417
						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
418
							# unknown_finished_processors = add_unknown_finished_processor unknown_finished_processors
419
							# 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
420 421 422 423 424 425 426 427
							-> 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

428 429 430
		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
431 432 433
				# (state,ps) = handle_completed_processes 0 state ps
					with
						handle_completed_processes process_n state ps
434
							| process_n>=max_n_processes
Diederik van Arkel's avatar
Diederik van Arkel committed
435 436 437 438 439 440 441 442 443 444 445 446 447 448
								= (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)

449
		process_completed :: !Int !Int !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
450
		process_completed completedSlot exitcode (DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors}) todo ds) ps
451 452 453
			# (completed, current)			= removeFromCurrent completedSlot current
			# unknown_finished_processors	= remove_from_unknown_finished_processors completedSlot unknown_finished_processors
			# (startupdir,ps)				= getStup ps
454
			#  typewin = updateTypeWindow True (GetModuleName completed.iclModule) [typeWinKeyboard, typeWinMouse]
455
			# ccstring						= "dummy ccstring for now.."
456
			# (abcpath,res,ps)				= CompileHandleExitCode exitcode ccstring startupdir completedSlot updateErrorWindow typewin 
457
												completed.iclModule completed.options.listTypes ps // types param
458 459
			# (_,(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
460
			# ds							= {ds & newpaths = ds.newpaths || newpaths`, fileinfo = fileinfo, abccache = abccache, project = project, ok = ok}
461 462 463
			| 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
464
			// not ok
465
				# (os_error,ps) = ClearCompilerCaches compiler_process_ids ps;
466 467
				# (paths,ds)	= ds!modpaths
				= (DGene paths SyncCodeGeneration ds, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
468 469 470 471 472 473 474 475 476 477 478
			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])

479
		start_compilations :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
480
		start_compilations state=:(DComp force dircache (Async current {max_n_processes,compiler_process_ids,unknown_finished_processors}) (next :! rest) ds) ps
481
			// all threads used?
482 483
			| length current >= max_n_processes
				# ps = DelayEventLoop ps;			
Diederik van Arkel's avatar
Diederik van Arkel committed
484
				= (state, ps)
485
			// compile phase: check module 'next'
486 487 488
			# 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
489
			# modname = GetModuleName next
490 491
			| isProjLibraryModule modname ds.libsinfo
				// instead of testing explicitly put libmodules in done <= conflicts with other administration
492
				= (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)
493
			# (ps,dircache,ok,_,rest,compinfo,ds,_)
494
				= 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
495
			# ds = {ds & ok = ok}
Diederik van Arkel's avatar
Diederik van Arkel committed
496
			| not ok
497
				# (os_error,ps) = ClearCompilerCaches compiler_process_ids ps;
498 499 500
				#! (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
501 502
		start_compilations state ps
//			# ps = traceInfo (Level3 ["start_compilations no next..."]) ps
503
			# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
504 505 506 507
			= (state, ps)

		currently_compiled :: String [CurrentlyCompiled] -> Bool
		currently_compiled next current
508
			=	or [c.iclModule == next	\\ c <- current]
Diederik van Arkel's avatar
Diederik van Arkel committed
509 510 511 512 513 514 515 516

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
517
		check_completed :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
518
		check_completed state=:(DComp _ _ (AsyncWin current=:[_:_] _) _ _)  ps
Diederik van Arkel's avatar
Diederik van Arkel committed
519 520 521 522 523 524 525 526 527 528 529
			=	case (CompilePollCompleted ps) of
					(NoFinishedCompiler, ps)
						-> (state, ps)
					(FinishedCompiler completedSlot exitcode, ps)
						#! (state,ps) = process_completed completedSlot exitcode state ps
						-> check_completed state ps
					(UnknownFinishedCompiler,ps)
						-> (state, ps)	// -> doesn't occur on win
		check_completed state ps
			=	(state, ps)

530
		process_completed :: !Int !Int !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
531
		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
532 533
			# (completed, current)	= removeFromCurrent completedSlot current
			# (startupdir,ps)		= getStup ps
534
			# typewin				= updateTypeWindow True (GetModuleName completed.iclModule) [typeWinKeyboard, typeWinMouse]
Diederik van Arkel's avatar
Diederik van Arkel committed
535
			# ccstring				= "dummy ccstring for now.."
536
			# (abcpath,res,ps)		= CompileHandleExitCode exitcode ccstring startupdir completedSlot updateErrorWindow typewin 
Diederik van Arkel's avatar
Diederik van Arkel committed
537
										completed.iclModule completed.options.listTypes ps // types param
538 539
			# (_,(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
540 541
			# ds					= {ds & newpaths = ds.newpaths || newpaths`, fileinfo = fileinfo, abccache = abccache, project = project, ok = ok}
			| ok
542 543
				# 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
544 545
			// not ok
				# (paths,ds)	= ds!modpaths
546
				# ps = {ps & io=QuitCleanCompiler True win_compiler_process_ids ps.io};
Diederik van Arkel's avatar
Diederik van Arkel committed
547 548 549 550 551 552 553 554 555 556 557 558
				= (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])

559
		start_compilations :: !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
560 561 562
		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
563 564
				= (state, ps)
		// compile phase: check module 'next'
565 566 567
			# 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
568 569 570
			# modname = GetModuleName next
			| isProjLibraryModule modname ds.libsinfo
				// instead of testing explicitly put libmodules in done <= conflicts with other administration
571
				= (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
572
			# (ps,dircache,ok,_,rest,compinfo,ds,_)
573
				= 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
574 575 576
			# ds = {ds & ok = ok}
			| not ok
				#! (paths,ds)	= ds!modpaths
577
				# ps = {ps & io=QuitCleanCompiler True win_compiler_process_ids ps.io};
Diederik van Arkel's avatar
Diederik van Arkel committed
578 579
				= (DGene paths SyncCodeGeneration ds, ps)
			= start_compilations (DComp force dircache compinfo rest ds) ps
580 581
		start_compilations state=:(DComp force dircache (AsyncWin [] _) Nil ds) ps
			= (state, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
582
		start_compilations state ps
583
			# ps = DelayEventLoop ps;
Diederik van Arkel's avatar
Diederik van Arkel committed
584 585 586 587 588
			= (state, ps)

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

590
step intr (DGene Nil SyncCodeGeneration ds) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
591
	#! ps	= showInfo (Level1 "Linking...") ps
592
	= step intr (DLink ds) ps
593

594 595
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
596
	#! ps	= showInfo (Level1 "Linking...") ps
597
	= step intr (DLink ds) ps
598

599 600 601 602 603 604 605
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
606
	| not ok
607 608
		= step intr (DLink ds) ps
	= cont (DGene rest SyncCodeGeneration ds, ps)
609

610
step intr (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes,compiler_process_ids,unknown_finished_processors}) ds) ps
611 612
	# (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
613 614 615 616 617 618 619 620 621 622 623 624 625
		with
			handle_finished_code_generators busy_processes=:[_:_] unknown_finished_processors project fileinfo ps
				= case (CompilePollCompleted ps) of
					(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
626
						# (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
627
							with
628
								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
629 630
									| finished_cg_slot_n==slot
										= (abc_path,obj_path,rest)
631
										# (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
632
										= (abc_path,obj_path,[busy_process:rest])
633
								get_paths_and_remove_process_from_list finished_cg_slot_n []
Diederik van Arkel's avatar
Diederik van Arkel committed
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
									= 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
655
									# (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
656
										with
657
											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
658 659
												| process_n==slot
													= (abc_path,obj_path,rest)
660
													# (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
661
													= (abc_path,obj_path,[busy_process:rest])
662
											get_paths_and_remove_process_from_list finished_cg_slot_n []
Diederik van Arkel's avatar
Diederik van Arkel committed
663 664 665 666 667 668 669 670
												= 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)
671 672
	# ds = {ds & fileinfo = fileinfo, project = project, ok = ds.ok && ok && not intr}
	| not ds.ok
673 674 675 676
		= 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)
677
	# (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
678
		with
679
			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
680 681
			start_code_generators paths=:(path :! rest) busy_processes fileinfo abccache ps
				| length busy_processes>=max_n_processes
682
		 			# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
683
					= (True,paths,busy_processes,fileinfo,abccache,ps)
684 685 686
				# (ps,abccache,fileinfo,gen,abc_path)
									= CheckABCOutOfDate False path abccache fileinfo project ps
				# cgo				= PR_GetCodeGenOptions project
687
				# (proc,ps)			= getCurrentProc ps
688
				# ((abccache,fileinfo,info), ps)
689
									= FI_GetFileInfo proc abc_path abccache fileinfo ps
Diederik van Arkel's avatar
Diederik van Arkel committed
690 691
				| not gen
					= start_code_generators rest busy_processes fileinfo abccache ps
692
				# ps				= showInfo (Level2 (
Diederik van Arkel's avatar
Diederik van Arkel committed
693 694 695 696 697 698 699 700 701 702 703 704
													(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
705
				# timeprofile		= ao.profiling && (not co.neverTimeProfile)
Diederik van Arkel's avatar
Diederik van Arkel committed
706 707 708 709 710
				# 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

711
				# (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
712 713 714 715 716
				| 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
717
				# ps = DelayEventLoop ps
Diederik van Arkel's avatar
Diederik van Arkel committed
718
				= (True,Nil,busy_processes,fileinfo,abccache,ps)
719
	# ds = {ds & fileinfo = fileinfo, abccache = abccache, ok = ok}
720
	= 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)
721

722
step intr (DLink ds=:{ok, newpaths, fileinfo, libsinfo, modpaths, abccache, project, continue}) ps
Diederik van Arkel's avatar
Diederik van Arkel committed
723 724
	//	Check whether executable is out of date and relink it	if required.
	| intr || not ok
725
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
	# lo						= PR_GetLinkOptions project
	# (prj_path,ps)				= getPath ps
	# (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
	# full_sys					= full_sys0 +++ {dirseparator} +++ (MakeABCPathname System)
	# full_sys`					= MakeImpPathname full_sys
	
	# ao						= PR_GetApplicationOptions project
	// possibly patch _system to correct profiling settings...

746 747
//	# tp						= PR_GetProcessor project
	# (tp,ps)					= getCurrentProc ps
Diederik van Arkel's avatar
Diederik van Arkel committed
748 749 750 751 752 753 754 755
	# ((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 [])
756
	# ps						= verboseInfo be_verbose lines ps
Diederik van Arkel's avatar
Diederik van Arkel committed
757 758 759 760 761
	# (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
762 763
		= 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
764 765 766 767 768 769
	# (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
770 771 772 773
	# (sys_date, ps)			= accFiles (FModified full_sys) ps
	# sys_obj					= full_sys0 +++ {dirseparator} +++ (MakeObjPathname tp System)
	# (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
774
	# (abcPathsCache,ps)		= case genabc of
Diederik van Arkel's avatar
Diederik van Arkel committed
775
									True
776
										-> (DC_Update ((MakeObjPathname tp System),full_sys0,sys_obj_date_time) abcPathsCache,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
777
												// need to check if line above actually works now...
Diederik van Arkel's avatar
Diederik van Arkel committed
778 779
									False
										-> (abcPathsCache,ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
780
	| not ok
781
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
782

783 784 785 786 787 788 789
	# ((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
790 791 792 793 794
	# prj_path`					= RemoveFilename prj_path
	# execpath					= PR_GetExecPath project
	# execpath					= fulPath app_path prj_path` execpath
	# ps						= showInfo (Level2 ("Linking '" +++ RemovePath execpath +++ "'")) ps
	
795 796
	# (use_64_bit_processor,ps) = getCurrent64BitProcessor ps

Diederik van Arkel's avatar
Diederik van Arkel committed
797
	// runtime objects and dynamic libs
798
	# stdl						= Concat sys_libs (standardStaticLibraries tp lo.method)
799
	# stdo						= Concat sys_objs (standardObjectFiles ao.stack_traces ao.profiling tp use_64_bit_processor)
Diederik van Arkel's avatar
Diederik van Arkel committed
800 801 802 803 804 805 806 807 808 809 810
	# (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
811
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
812 813 814
	| not stdlOk
		# line					= Level3 ["Link error: File: '" +++ (Head lfiles) +++ "' not found."]
		# ps					= showInfo line ps
815
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
816 817 818 819

	// environment objects and dynamic libs
	# (deflibs,ps)				= getCurrentDlibs ps
	# (defobjs,ps)				= getCurrentObjts ps
820 821
	# ofiles					= Concat defobjs ofiles
	# lfiles					= Concat deflibs lfiles
Diederik van Arkel's avatar
Diederik van Arkel committed
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
/* NO: these are stored with full path so need different approach???
	# (defobjsOk,defobjs,abcPathsCache)
								= GetPathNames defobjs Nil abcPathsCache
	# (deflibsOk,deflibs,abcPathsCache)
								= GetPathNames deflibs Nil abcPathsCache
	| not defobjsOk
		# line					= Level3 ["Link error: File: '" +++ (Head defobjs) +++ "' not found."]
		# ps					= showInfo line ps
		= continue False newpaths False fileinfo libsinfo abccache modpaths project intr ps
	| not deflibsOk
		# line					= Level3 ["Link error: File: '" +++ (Head deflibs) +++ "' not found."]
		# ps					= showInfo line ps
		= continue False newpaths False fileinfo libsinfo abccache modpaths project intr ps
*/

	// clean modules
	# (clmodpaths,fileinfo)		= FI_GetCleanModules system_obj_path libsinfo fileinfo
839 840 841 842
	// why couldn't we use ds.modpaths above??? No we need to do trickery to ensure main module is first!
	# (rootpath,project)		= PR_GetRootPathName project
	# rootpath					= MakeObjSystemPathname tp rootpath 
	# clmodpaths				= RemoveStringFromList rootpath clmodpaths
Diederik van Arkel's avatar
Diederik van Arkel committed
843
	# ofiles` = ofiles
844 845
	# ofiles					= rootpath :! ofiles
	
Diederik van Arkel's avatar
Diederik van Arkel committed
846
	# ofiles					= Reverse2 clmodpaths ofiles
Diederik van Arkel's avatar
Diederik van Arkel committed
847 848 849

	// module imported objects and dynamic libs
	# abcLinkInfo				= PR_GetABCLinkInfo project
850
	# linkObjFileNames			= Map (append_object_file_extension_if_dot_at_end tp use_64_bit_processor) abcLinkInfo.linkObjFileNames
Diederik van Arkel's avatar
Diederik van Arkel committed
851
	# (objPathsOk,ofiles,abcPathsCache)
852
								= GetPathNames linkObjFileNames ofiles abcPathsCache
853
	# (_,ofiles`,abcPathsCache) = GetPathNames /*abcLinkInfo.*/linkObjFileNames ofiles` abcPathsCache
Diederik van Arkel's avatar
Diederik van Arkel committed
854 855 856 857 858
	# (libPathsOk,lfiles,abcPathsCache)
								= GetPathNames abcLinkInfo.linkLibraryNames lfiles abcPathsCache
	| not objPathsOk
		# line					= Level3 ["Link error: File: '" +++ (Head ofiles) +++ "' not found."]
		# ps					= showInfo line ps
859
		= continue False newpaths False fileinfo libsinfo modpaths project intr (abccache, ps)
Diederik van Arkel's avatar
Diederik van Arkel committed
860 861 862
	| not libPathsOk
		# line					= Level3 ["Link error: File: '" +++ (Head lfiles) +++ "' not found."