1 ///	
2 // Written in the D programming language.
3 /**
4 This is a build tool,compile *.d to exe or lib,and help to build dfl2 gui (or other you like).
5 now default DC is dmd ,default platform is windows.
6 
7 If your DC is dmd, dco can start only 'dco.ini' config file. 
8 
9 Compiler dco.d :dmd dco.d -release,and dco ↓,
10 
11 Usage:
12 Config some info to 'dco.ini' file,';' or '#' means you can do as it.Then copy dco.ini to your PATH: such as dmd's config file:sc.ini.
13 And dco.exe can auto copy itsself to EnvPath,that also is  dmd.exe 's path: dmd2\window\bin.
14 After that,you can run the 'dco.exe'  anywhere.
15 If not found 'dco.ini',run: dco -ini,please.
16 
17 For example:
18 to get the debug version( -release to get another)
19 
20 build some *.d to lib or exe 			 : dco ↓
21 build some *.d to lib or exe for 64 bit	 : dco -m64 ↓
22 build  one app.d in many *.d    		 : dco app or  dco app.d
23 build for libs 	such as dfl,dgui         : dco  -lib
24 build for app.d use dfl2				 : dco  -gui
25 build app.d use dfl2 for console		 : dco  -con
26 build lib and copy to libs				 : dco -lib -copy
27 build by custom	and copy to libs         : dco -arg -addlib -lib -copy
28 
29 if your exe's file works on console,you should add '-con' or '-console'. 
30 
31 Copyright: Copyright FrankLIKE 2014-.
32 
33 License:   $(LGPL-3.0).
34 
35 Authors:   FrankLIKE
36 
37 Source: $(dco.d)
38 
39 Created Time:2014-10-27
40 Modify Time:2014-10-31~2015-1-7
41 */
42 module dco;
43 /// dco 
44 import	std.stdio;
45 import	std.datetime;
46 import	std.process; 
47 import	std.string;
48 import	std.file;
49 import	std.path;
50 import	std.exception;
51 import  std.json;
52 import std.typetuple;
53 
54 string strVersion ="v0.1.0";
55 
56 string	strAddArgs,strAddArgsdfl = " -de -w -property ";
57 string	buildMode,strDebugDefault=" -debug";
58 string	strTargetLflags,strConsole=" -L-su:console:4 ",strWindows = " -L-Subsystem:Windows ",strWindows64 = " -L-Subsystem:Windows -L-ENTRY:mainCRTStartup ";
59 string	strTargetLib,SpecialLib = "dfl",strWinLibs=" ole32.lib oleAut32.lib gdi32.lib Comctl32.lib Comdlg32.lib advapi32.lib uuid.lib ws2_32.lib kernel32.lib ",strWinLibs64 =" user32.lib "; 
60 string	strDFile;
61 string	strAddLib;
62 string	strOtherArgs;
63 string	strImportDefault = " -I$(DMDInstallDir)windows/import ";
64 string	strTargetPath,strTargetFileName,strTargetTypeSwitch,targetTypeDefault = "lib",targetTypeShared = "shared";
65 string	strDCEnv,strDCEnvFile;
66 SysTime sourceLastUpdateTime,targetTime;
67 string	compileType; 
68 
69 bool	bUseSpecialLib =false,bDebug =true,bBuildSpecialLib =false;
70 bool	bCopy =false ,bDisplayBuildStr=false,bDisplayCopyInfo =true;
71 bool	bForce = false,bInitINI =false,bHelp =false;
72 bool 	bAssignTarget =false;
73 
74 //ini
75 string configFile ="dco.ini",configFileLocal = "local.ini";
76 string[string] configKeyValue;
77 bool bGetLocal = false;
78 //ini args
79 string strPackageName,strArgs,strTargetName,strTargetType ="exe",strDC ="dmd",strDCStandardEnvBin ="dmd2\\windows\\bin",strLibs ,strImport,strLflags,strDflags;
80 //targetTypes
81 enum targetTypes {exe,lib,staticLib,dynamicLib,sourceLib,none};
82 string[] targetExt = ["exe","lib","dll","a"];
83 void main(string[] args)
84 {
85 	if(!findDCEnv()) return;
86 	// readInJson();
87 	
88 	if(!checkArgs(args))
89 	{
90 		if(bHelp)
91 		{
92 			ShowUsage();
93 			return;
94 		}
95 
96 		if(bInitINI)
97 		{
98 			initNewConfigFile();
99 			return;
100 		}
101 
102 		if(!findFiles())
103 		{
104 			ShowUsage();
105 			return;
106 		}
107 	}
108 	if(args.length ==1)
109 	{
110 		if(!CheckBinFolderAndCopy()) return;
111     }
112  
113 	if(strPackageName =="")
114 	{
115 		strPackageName = strTargetName;
116 	}
117 
118 	buildExe(args);
119 }
120 
121 bool findDCEnv()
122 {
123 	if(!readConfig(configFile)) return false;
124 	bool bLocal = readConfig(configFileLocal);
125 	string strNoDC = "Not found '"~strDC~"' in your computer,please setup it.",strTemp,strTempFile;
126 	string strDCExe = "\\" ~ strDC.stripRight() ~ ".exe";
127 	string strFireWall = " Maybe FirWall stop checking the " ~ strDCExe ~ ",please stop it.";
128 
129 	auto len = strDCStandardEnvBin.length;
130 
131 	auto path = environment["PATH"];
132 	string[] strDCs = path.split(";");
133 	foreach(s;strDCs)
134 	{
135 		ptrdiff_t i = s.indexOf(strDCStandardEnvBin);
136 		if(i != -1)
137 		{
138 			if(checkDC(s,strDCExe)) break;
139 		}
140 	}
141 
142 	if(strDCEnvFile =="")
143 	{
144 		writeln(strNoDC);
145 		return false;
146 	}
147 	else
148 	{
149 		//writeln(strDC ~ " is " ~ strDCEnvFile);
150 		return true;
151 	}
152 }
153 
154 bool checkDC(string DCPath,string strDCExe)
155 { 
156 	if(exists(DCPath ~ strDCExe))
157 	{ 
158 		strDCEnv = DCPath;
159 		strDCEnvFile =  DCPath ~ strDCExe;
160 
161 		string strTempFile = DCPath ~ "\\dco.exe";
162 		if(exists(strTempFile)) return true;
163 	}
164 	return false;
165 }
166 
167 bool readConfig(string _configFile)
168 { 
169 	try
170 	{ 
171 		string strConfigPath ="",targetType ="",targetName ="";
172 		bool isLocal = (_configFile != configFile);
173  
174 		if(!isLocal)
175 		{
176 			strConfigPath = thisExePath();
177 			strConfigPath = strConfigPath[0..strConfigPath.lastIndexOf("\\")].idup;
178 			strConfigPath ~= "\\" ~ _configFile;
179 
180 			if(!enforce(exists(strConfigPath),"'FireWall' stop to access the '" ~ _configFile ~ "',please stop it."))
181 			{
182 				writeln("dco not found " ~ _configFile ~ ", it will help you to  create a init " ~ _configFile ~ " file ,but you should input something in it.");
183 				initNewConfigFile();
184 				return false;
185 			}  
186 		}
187 		else
188 		{
189 			if("SpecialLib" in configKeyValue) 
190 				configKeyValue["SpecialLib"] = "";
191 			if("importPath" in configKeyValue) 
192 				configKeyValue["importPath"] = "";
193  
194 			strConfigPath = getcwd() ~ "\\" ~ _configFile;
195 			bGetLocal = exists(strConfigPath);
196 			if(!bGetLocal) return true;  //not find ,but can work.
197 		}
198 		auto file = File(strConfigPath); 
199 		scope(failure) file.close();
200 		auto range = file.byLine();
201 		foreach (line; range)
202 		{
203 			if (!line.init && line[0] != '#' && line[0] != ';' && line.indexOf("=") != -1)
204 			{ 
205 				ptrdiff_t i =line.indexOf("=");
206 				configKeyValue[line.strip()[0..i].idup] = line.strip()[i+1..$].idup;
207 			}
208 		}
209 
210 		file.close();
211 
212 		strDC = configKeyValue.get("DC",strDC); 
213 
214 		strDCStandardEnvBin = configKeyValue.get("DCStandardEnvBin",strDCStandardEnvBin); 
215 		SpecialLib = configKeyValue.get("SpecialLib","");
216 		strImport = configKeyValue.get("importPath","");
217 		strLflags = configKeyValue.get("lflags",strConsole); 
218 		strDflags = configKeyValue.get("dfalgs",""); 
219 		strLibs = configKeyValue.get("libs",""); 
220 
221 		if(isLocal)
222 		{
223 			switch(strLflags)
224 			{
225 				case "console":
226 					strLflags = strConsole;
227 					break;
228 				case "win32":
229 					strLflags = strWindows;
230 						break;
231 				case "win64":
232 					strLflags = strWindows64;
233 						break;
234 				default:
235 					break;
236 			}
237 			strTargetLflags = " " ~ strLflags;
238 
239 			if(SpecialLib == "dfl" || SpecialLib == "dgui") bUseSpecialLib = true;
240 
241 			targetType = configKeyValue.get("targetType","default"); 
242 			targetName = configKeyValue.get("targetName",""); 
243 
244 			switch(targetType)
245 			{//targetTypes {exe,lib,staticLib,dynamicLib,sourceLib,none};
246 				case "sourceLib":
247 				case "none":
248 					return false;
249 
250 				case "exe":
251 					strTargetType ="exe";
252 					break;
253 				case "lib":
254 				case "staticLib":
255 					strTargetTypeSwitch =" -lib";
256 					if(strDC.toLower().indexOf("dmd") != -1)
257 					{
258 						strTargetType = "lib";
259 					}
260 					else if(strDC.toLower().indexOf("ldc") != -1)
261 					{
262 						strTargetType = "a";
263 					}
264 					break;
265 				case  "dynamicLib":
266 					strTargetTypeSwitch =" -shared";
267 					if(strDC.toLower().indexOf("dmd") != -1)
268 					{
269 						strTargetType = "dll";
270 					}
271 					else if(strDC.toLower().indexOf("ldc") != -1)
272 					{
273 						strTargetType = "so";
274 					}
275 					break;
276 				default://default
277 					strTargetType ="exe";
278 					break;
279 			}
280 			if(targetName !="")
281 			{
282 				strTargetFileName = getcwd() ~ "\\" ~ targetName;
283 				strTargetName = targetName;
284 				if(targetName.indexOf(".") == -1)
285 				{
286 					strTargetName ~= "." ~ strTargetType; 
287 				}
288 				strOtherArgs ~= " -of" ~ strTargetName;
289 				bAssignTarget = true;
290 			}
291 			compileType = configKeyValue.get("compileType",""); 
292 			if(compileType !="" )
293 			{
294 				strOtherArgs ~= " -m" ~ compileType;
295 			}
296 
297 			buildMode = configKeyValue.get("buildMode",strDebugDefault); 
298 			if(buildMode.indexOf("-") == -1)
299 			{
300 				buildMode = " -" ~ buildMode;
301 			}
302 		}
303 		return true;
304 	}
305 	catch(Exception e) 
306 	{
307 		writeln(" Read ini file err,you should input something in ini file.",e.msg);
308 		return false;
309 	}
310 }
311 
312 bool checkArgs(string[] args)
313 {
314 	string c;
315 	size_t p;
316 	bool bDFile =false;
317 	foreach(int i,arg;args)
318 	{
319 		if(i == 0) continue;
320 		c = toLower(arg);
321 		p = c.indexOf('-');
322 		if(p == -1 || c.indexOf(".d") != -1)
323 		{
324 
325 			strTargetName = c[0..$-1].idup;
326  			strDFile ~= " ";
327 			strDFile ~= c;
328 			bDFile = true;
329 		}
330 		else
331 		{
332 			c = c[p+1 .. $];
333 		}
334  
335 		if(c == "h" || c == "help")//toLower(args[1])
336 		{
337 			bHelp = true;
338 		}
339 		else if(c == "force")
340 		{
341 			bForce = true;
342 		}
343 		else if(c.indexOf("of") != -1)
344 		{
345 			bAssignTarget = true;
346 			strTargetName = c[(c.indexOf("of")+1)..$];
347 		}
348 		else if(strPackageName !="")
349 		{
350 			if(c == strPackageName || c == strPackageName ~ "lib")
351 			{ 
352 				bAssignTarget = true;
353 				bBuildSpecialLib = true;
354 				strTargetTypeSwitch = " -" ~ targetTypeDefault;
355 				strTargetName = c ~ ".lib";
356 			}
357 	    }
358 		else if(c == "ini" || c == "init")
359 		{
360 			bInitINI = true;
361 		}
362 	} 
363 	return bDFile;
364 }
365  
366 bool CheckBinFolderAndCopy() 
367 {
368 	if(checkIsUpToDate())
369 	{
370 		writeln(strTargetName ~" file is up to date.");
371 		return false;
372 	}
373 	return true;
374 }
375 
376 bool checkIsUpToDate()
377 {
378 	getTargetInfo();
379 	if(exists(strTargetFileName))
380 	{
381 		targetTime = getTargetTime(strTargetFileName);
382 
383         if(strTargetFileName.indexOf("dco.exe") != -1)
384         {
385 			if(!checkIsUpToDate(strDCEnvFile ,targetTime))
386 			{
387 				auto files = dirEntries(".","dco.{exe,ini}",SpanMode.shallow);
388 				foreach(d;files)
389 				{
390 					string strcopy ="copy " ~ d ~" " ~ strDCEnv;
391 					writeln(strcopy);
392 					auto pid = enforce(spawnShell(strcopy.dup()),"spawnShell(strcopy.dup()) is err!");
393 					if (wait(pid) != 0)
394 					{
395 						writeln("copy failed.");
396 					}
397 				}
398 				//copy(strTargetFileName,strDCEnvFile);
399 			}
400  	    }
401 
402 		bool bUpToDate = (targetTime >= sourceLastUpdateTime);
403 
404 		if(!bUpToDate || bForce)
405 		{
406 			removeExe(strTargetFileName);
407 		}
408  		return bUpToDate;
409     }
410 
411     return false;
412 }
413 
414 SysTime getTargetTime(string strPathFile)
415 {
416 	return DirEntry(strPathFile).timeLastModified;
417 }
418 
419 void removeExe(string strPathExe)
420 {
421 	if(!findStr(strPathExe,targetExt)) return;
422     if(exists(strPathExe))
423 	{
424 		auto pid = enforce(spawnShell("del " ~ strPathExe.dup()),"del " ~ strPathExe.dup() ~ " Err");
425 		if (wait(pid) != 0)
426         {
427 			writeln(strPathExe ~ ", remove  failed!");
428 			return;
429 		}
430 		else
431 		{
432 			writeln(strPathExe ~ ", remove  ok!");
433 		}
434 	}
435 }
436 
437 bool checkIsUpToDate(string strPathFile,SysTime targettime)
438 {
439 	if(!exists(strPathFile)) return false;
440     auto testFile = DirEntry(strPathFile);
441     auto createTime = testFile.timeLastModified;
442 
443     return (targettime <= createTime);
444 }
445 
446 void buildExe(string[] args)
447 {
448 	string c;
449 	size_t p;
450 
451 	if(bGetLocal) goto build;
452 
453 	foreach(int i,arg;args)
454 	{
455 		if(i ==0) continue;
456 		c = toLower(arg);
457 		p = c.indexOf('-');
458 		if(p != -1)
459 		{
460 			c = c[p+1 .. c.length];
461 
462 			switch(c)
463 			{
464 				case "h","help":
465 					ShowUsage();
466 					break;
467 				case "gui":
468 					strTargetLflags = strWindows;
469 					bUseSpecialLib = true;
470 					strAddArgs = strAddArgsdfl;
471 					break;
472 				case "use":
473 					bUseSpecialLib = true;
474 					strAddArgs = strAddArgsdfl;
475 					break;
476 				case "win","windows","winexe":
477 					strTargetLflags = strWindows;
478 					break;
479 				case "debug":
480 					bDebug = true;
481 					break;
482 				case "release":
483 					bDebug = false;
484 					buildMode = " -" ~ c.idup;
485 					break;
486 
487 				case "console","con","exe":
488 					strTargetLflags = strConsole;
489 					break;
490 				case "all":
491 					bUseSpecialLib = false;
492 					strAddLib = strLibs;
493 					strAddArgs = strAddArgsdfl;
494 					strImport = strImportDefault;
495 					strTargetLflags = strConsole;
496 					break;
497 				case "addlib":
498 					strAddLib = strLibs~" ";
499 					strImport = strImportDefault;
500 					strTargetLflags = strConsole;
501 					break;
502 				case "arg":
503 					strAddArgs = strAddArgsdfl;
504 					break;
505 				case "lib":
506 					strTargetTypeSwitch = " -" ~ targetTypeDefault;
507 					break;
508 				case "dfl","dfllib":
509 					bBuildSpecialLib = true;
510 					strTargetTypeSwitch = " -" ~ targetTypeDefault;
511 					break;
512 				case "copy":
513 					bCopy = true;
514 					break;
515 				case "force":
516 					bForce = true;
517 					break;
518 				case "shared":
519 					strTargetTypeSwitch = " -" ~ targetTypeShared;
520 					break;
521 				default:
522 					if(c == "m64" || c == "m32mscoff")
523 					{ 
524 						compileType =c[1..$];
525 					}
526 					strOtherArgs ~= " ";
527 					strOtherArgs ~= arg;
528 					break;
529     		}
530     	}
531 	}
532 
533 	strTargetLib = bDebug ? SpecialLib ~ "_debug" ~ compileType ~ ".lib" : SpecialLib ~ compileType ~ ".lib" ;
534 
535 	if(bBuildSpecialLib)
536 	{
537 		strOtherArgs ~= " -of" ~ strTargetLib;
538 		strAddLib = strLibs;
539 		strTargetFileName = getcwd() ~ "\\" ~ strTargetLib;
540 	}
541 	else
542 	{
543 		strTargetFileName = getcwd() ~ "\\" ~ strTargetName;
544 	}
545 
546     if(strDflags !="")
547     {
548     	strOtherArgs ~= " ";
549     	strOtherArgs ~= strDflags;
550     }
551     if(strTargetLflags == "" && strLflags !="")
552 	{
553 		strTargetLflags = strLflags;
554 	}
555 	
556 	if(strTargetLflags == "" && strLflags =="")
557 	{
558 		if(bUseSpecialLib) 
559 			strTargetLflags = strWindows;
560 		else
561 			strTargetLflags = strConsole;
562 	}
563 
564 build: 
565 
566 	if(bUseSpecialLib)
567 	{
568 		if(SpecialLib == "dfl")
569 		{
570 			strTargetLib = bDebug ? SpecialLib ~ "_debug" ~ compileType ~ ".lib" : SpecialLib ~ compileType ~ ".lib" ;
571 			strLibs =strWinLibs;
572 		}
573 		if(SpecialLib !="")
574 		{
575 			strAddLib = strLibs ~" " ~ strTargetLib ;
576 		}
577 	}
578 	else
579 	{
580 		strAddLib = strLibs;
581 	}
582 
583 	if(compileType == "64")
584 	{
585 		if(strip(strTargetLflags) !=strip(strConsole))
586 		{
587 			if(strAddLib.indexOf(strip(strWinLibs64)) == -1)
588 			{
589 				strAddLib ~= strWinLibs64;
590 			}
591  
592 		    strTargetLflags = bUseSpecialLib ? strWindows64 : strWindows;
593 		}
594 		else //console x64 not set
595 		{
596 			strTargetLflags= "";
597 		}
598 	} 
599 
600 	buildExe();
601 }
602 
603 void buildExe()
604 {
605 	if(bForce)
606 	{
607 		removeExe(strTargetFileName);
608 	}
609 	strDC ~= " ";
610 	strDC ~= strTargetTypeSwitch;
611 	string strCommon = strOtherArgs ~" " ~ strImportDefault ~ strImport ~ " " ~ strAddLib ~ strTargetLflags ~ strDFile ~ buildMode;
612     string buildstr = strDC ~ strAddArgsdfl ~ strCommon ~ "\r\n";
613 	buildstr = bUseSpecialLib ? buildstr : strDC ~ strCommon;
614 
615 	StopWatch sw;
616 	sw.start();
617 	auto pid =  enforce(spawnShell(buildstr.dup()),"build function is error! ");
618 
619 	if (wait(pid) != 0)
620 	{
621 		writeln("\n"~ buildstr);
622 		writeln("\nCompilation failed:\n", pid);
623 	}
624 	else
625 	{
626 		sw.stop();
627 
628 		writeln(buildstr);
629 		writeln("\nCompile time :" , sw.peek().msecs/1000.0,"secs");
630 
631 		if(bCopy)
632 		{
633 			copyFile();
634 		}
635 	}
636 
637 	writeln("End.");
638 }
639 
640 void copyFile()
641 {
642 	string strcopy;
643 	if(!exists(strTargetFileName)) 
644 	{
645 	 	writeln(strTargetFileName," is not exists,stop copy.");
646 		return;
647 	}
648 
649 	if(strTargetFileName.indexOf("exe") != -1)
650 	{
651 		//copy(strTargetFileName,strDCEnv); //
652 		strcopy = "copy " ~ strTargetFileName~" " ~ strDCEnv;
653 	}
654 	else
655 	{ 
656 		string strDCLibPath = strDCEnv[0..(strDCEnv.length - "bin".length)].idup ~ "lib" ~ compileType; 
657 		//copy(strDCEnv,strDCLibPath);
658 		strcopy = "copy " ~ strTargetFileName ~ " " ~ strDCLibPath;
659 	}
660 	if(bDisplayCopyInfo)
661 	{
662 		writeln(strcopy);
663 	}
664 
665 	auto pid =  enforce(spawnShell(strcopy.dup()),"copyFile() error");
666 	if (wait(pid) != 0)
667 	{
668 		writeln("Copy failed.");
669 	}
670 }
671 
672 bool findFiles()
673 { 
674 	int i = 0;
675 	bool bPackage = false; 
676 	auto packages = dirEntries(".","{package.d,all.d}",SpanMode.depth);
677 	foreach(p; packages){i++;}
678 	bPackage = (i > 0);
679 
680 	auto dFiles = dirEntries(".","*.{d,di}",SpanMode.depth);
681 	int icount =0;
682     SysTime fileTime;
683     DirEntry rootDE ;
684 
685 	foreach(d; dFiles)
686 	{	 
687 	    if(!bAssignTarget)
688 	    {
689 			if(icount == 0)
690 			{
691 				strTargetName = d.name[(d.name.lastIndexOf("\\")+1) .. d.name.lastIndexOf(".")];
692 				strTargetName ~= "." ~ strTargetType; 
693 			}
694 		}
695 		if(icount == 0 )
696 		{
697 			ReadDFile(d,bPackage);
698 		}
699 
700 		if(d.toLower().indexOf("ignore") != -1) continue;
701 
702 		strDFile ~= " ";
703 		strDFile ~= d.name[2 ..$].idup;
704 
705 		//sourceLastUpdateTime 
706 		rootDE = DirEntry(d);
707         if(rootDE.timeLastModified > fileTime)
708         {
709         	fileTime = rootDE.timeLastModified;
710         } 
711         icount++;
712 	}
713     sourceLastUpdateTime = fileTime;
714 
715 	strDFile = strDFile.stripRight().idup;
716 
717 	if(icount <= 0)  
718 	{
719 		writeln("Not found any *.d files in current folder.If there is a 'source' or 'src' folder,dco will find the '*.d' from there.");
720 		return false;
721 	}
722 	bCopy = (strDFile.indexOf("dco.d") != -1) ? true : false;
723 	return true;
724 }
725 
726 void getTargetInfo()
727 { 
728 	string root_path = getcwd();
729     string strPath;
730 	auto dFiles = dirEntries(root_path,strTargetName ~ ".{lib,exe,dll,a}",SpanMode.shallow);
731 	int i =0;
732 	foreach(d;dFiles)
733 	{
734 		i++;
735 		strTargetFileName =d;
736 		strTargetType = d.name[d.name.lastIndexOf(".")+1..$];
737 		break;
738 
739 	}
740 	if(i ==0)
741 	{
742 		if(strTargetName.indexOf("." ~ strTargetType) == -1)
743 		{
744 			strTargetName = strTargetName ~ "." ~ strTargetType;
745 		}
746 		strTargetFileName = root_path ~ "\\" ~ strTargetName;
747 	}
748 	if(!findStr(strTargetFileName,targetExt))
749 	{
750 		writeln("don't known the targetType ",strTargetFileName);
751 	}
752 	return;
753 }
754 
755 bool findStr(string strIn,string[] strFind)
756 {
757 	bool bFind = false;
758 	foreach(str;strFind)
759 	{
760 		if(strIn.indexOf(str) !=-1)
761        {   
762            bFind = true;
763 			break;
764        }
765 	}
766 	return bFind;
767 }
768 
769 void ShowUsage()
770 {
771 	writeln("
772 			dco build tool " ~ strVersion ~ "
773 			written by FrankLIKE.
774 			Usage:
775 			dco [<switches...>] <files...>
776 
777 			for example:     dco  
778 			or: dco app.d 
779 
780 			build for dfl2:	 dco  
781 			or: dco -gui
782 			or: dco *.d -gui
783 			build for other: dco -lib
784 			or: dco *.d -lib
785 			or: dco *.d -release
786 			or: dco *.d -arg -addlib
787 
788 			Switches:
789 			-h	       Print help(usage: -h,or -help).
790 			-copy      Copy new exe or lib to 'windows/bin' or 'lib' Folder. 
791 			-release   Build files's Release version(Default version is 'debug').
792 			-gui       Make a Windows GUI exe without a console(For DFL or Dgui).
793 			-use       Use the Sepetail Lib to create exe with console.
794 			-win       Make a Windows GUI exe without a console
795 			(For any other: the same to -winexe,-windows).
796 			-lib       Build lib files.
797 			-ini       Create the local.ini file for config. 
798 			-init      the same to -ini.
799 			-all       Build files by args,libs(Default no dfl_debug.lib) in Console.
800 			-arg       Build files by args(-de -w -property -X).
801 			-addlib    Build files by add libs(user32.lib ole32.lib oleAut32.lib gdi32.lib 
802 			Comctl32.lib Comdlg32.lib advapi32.lib uuid.lib ws2_32.lib).
803 			-m64       Generate 64bit lib or exe.
804 			-m32mscoff Generate x86 ms coff lib or exe,and please set some info in sc.ini. 
805 
806 			IgnoreFiles:
807 			If you have some files to ignore,please put them in Folder 'ignoreFiles'.
808 			");
809 } 
810 
811 void ReadDFile(string dFile,bool bPackage)
812 { 
813     if(bGetLocal) return;
814 	auto file = File(dFile); 
815 	scope(exit)  file.close();
816 	auto range = file.byLine();
817 	int icount = 0;
818     foreach (line; range)
819     {
820         if (!line.init && line.indexOf("import") != -1)
821         { 
822         	if(line.indexOf("dfl") != -1)
823         	{
824         		bBuildSpecialLib = bPackage;
825         		SpecialLib = "dfl";
826         		bUseSpecialLib = !bPackage;
827 
828 				if(bUseSpecialLib) 
829 					strTargetLflags = strWindows;
830 				else
831 					strTargetLflags = strConsole;
832 				break;
833 			}
834 			else if(line.indexOf("dgui") != -1)
835 			{
836 				strArgs = strAddArgsdfl = " -g -de -w -property -X ";
837 				SpecialLib = "dgui";
838 				bBuildSpecialLib = bPackage;
839 				break;
840 			}
841         }
842         else if(line.indexOf("WinMain") != -1)
843         {
844 			strTargetLflags = strWindows;
845 			break;
846         }
847         icount++;
848         if(icount >100) break;
849     }
850 }
851 
852 void initNewConfigFile()
853 {
854 	string strConfig = configFileLocal;
855 	auto ini = File(strConfig,"w"); 
856 	scope(failure) ini.close();
857 	ini.writeln("DC=" ~ strDC);
858 	ini.writeln("DCStandardEnvBin=" ~ strDCStandardEnvBin);
859  
860 	if(SpecialLib =="")
861 	{
862 		ini.writeln(";SpecialLib=" ~ SpecialLib);
863 		ini.writeln("SpecialLib=");
864 	}
865 	else
866 	{
867 		ini.writeln("SpecialLib=" ~ SpecialLib);
868 	}
869     if(strImportDefault =="")
870 	{
871 		ini.writeln(";importPath=" );
872 		ini.writeln("importPath=");
873 	}
874 	else
875 	{
876 		ini.writeln("importPath=" ~ strImportDefault);
877 	}
878 	ini.writeln(";lflags=console");
879 	ini.writeln("lflags=win32");
880 	ini.writeln(";lflags=win64");
881 
882 	ini.writeln(";dflags=");
883 	ini.writeln(";libs=");
884 
885 	ini.writeln(";targetType=exe//lib//staticLib//dynamicLib//sourceLib//none");
886 	ini.writeln("targetType=exe");
887 	ini.writeln(";targetName=;//    ;'null is auto'");
888 	ini.writeln("targetName=");
889 	ini.writeln(";compileType=;//64//32mscoff");
890 	ini.writeln("compileType=");
891 	ini.writeln(";buildMode=debug;//release");
892 	ini.writeln("buildMode=debug");
893 
894 	ini.close();
895 
896 	auto pid = spawnProcess(["notepad.exe",strConfig]);
897     auto dmd = tryWait(pid);
898 	if (dmd.terminated)
899 	{
900 		if (dmd.status == 0) writeln("open "~ strConfig ~" succeeded!");
901 		else writeln("open "~ strConfig ~" failed");
902 	}
903 	else writeln("Please add your Args...");
904 
905 }
906 
907 void readInJson()
908 {
909 	if(!exists("dub.json") && !exists("package.json") ) return;
910 	/*
911 	strPackageName = configKeyValue.get("name","");
912 	strArgs = configKeyValue.get("args",strAddArgs);
913 	strLibs = configKeyValue.get("libs","");
914 	strTargetName = configKeyValue.get("targetName","");
915 	strTargetType = configKeyValue.get("targetType",strTargetType); 
916 	*/
917 }