1 module Build;
2 
3 import core.stdc.stdlib: exit;
4 
5 import std.algorithm;
6 import std.array;
7 import std.conv;
8 import std.file;
9 import std.getopt;
10 import std.path;
11 import std.process;
12 import std.range;
13 import std.stdio;
14 import std.string;
15 
16 string dcflags;
17 string ldflags;
18 
19 int main(string[] args)
20 {
21 	version(Posix)
22 	{
23 		writeln("This build script is currently Windows only.");
24 		return(1);
25 	}
26 
27 	getopt(args, "dcflags", &dcflags, "ldflags", &ldflags);
28 	args.popFront();
29 	
30 	foreach ( arg; args )
31 	{
32 		if ( !["gtkd", "gtkdgl", "sv", "gstreamer", "vte", "peas", "all"].canFind(arg) )
33 		{
34 			writefln("Unknown option: %s", arg);
35 			return 1;
36 		}
37 	}
38 	
39 	if ( args.length == 0 )
40 		args = ["gtkd", "sv"];
41 		
42 	if ( args.canFind("all") )
43 		args = ["gtkd", "sv", "gstreamer", "peas"];
44 	
45 	foreach ( arg; args )
46 	{
47 		switch ( arg )
48 		{
49 			case "gtkd":
50 				build("generated\\gtkd", "gtkd");
51 				break;
52 			case "gtkdgl":
53 				build("generated\\gtkdgl", "gtkdgl");
54 				break;
55 			case "sv":
56 				build("generated\\sourceview", "gtkdsv");
57 				break;
58 			case "gstreamer":
59 				build("generated\\gstreamer", "gstreamerd");
60 				break;
61 			case "peas":
62 				build("generated\\peas", "peasd");
63 				break;
64 			default:
65 				assert(false);
66 				break;
67 		}
68 	}
69 	
70 	return(0);
71 }
72 
73 void build(string dir, string lib)
74 {
75 	version(Win64)
76 	{
77 		std.file.write("build.rf", format("-m64 -c -lib %s %s -Igenerated/gtkd -of%s.lib %s", dcflags, ldflags, lib, dFiles(dir)));
78 		auto pid = spawnProcess(["dmd", "@build.rf"]);
79 
80 		if ( wait(pid) != 0 )
81 			exit(1);
82 	}
83 	else
84 	{
85 		if (lib == "gtkd")
86 		{
87 			string[] subDirs = ["atk", "cairo", "gdk", "gdkpixbuf", "gio", "glib", "gobject", "gthread", "gtkc", "gtkd", "pango", "rsvg"];
88 
89 			foreach(directory; subDirs)
90 				buildObj(dFiles("generated\\gtkd\\"~ directory), directory);
91 
92 			string[] files = dFiles("generated\\gtkd\\gtk").split();
93 			files.chunks((files.length / 4) + 1).enumerate(1).each!((index, value){buildObj(value.join(' '), "gtk"~to!string(index));});
94 
95 			string objects;
96 			foreach(directory; subDirs)
97 				objects ~= directory ~".obj ";
98 			objects ~= "gtk1.obj gtk2.obj gtk3.obj gtk4.obj";
99 
100 			executeShell(format("dmd -lib %s -of%s.lib %s", ldflags, lib, objects));
101 
102 			foreach(string obj; objects.split())
103 				std.file.remove(obj);
104 		}
105 		else
106 		{
107 			buildObj(dFiles(dir), lib);
108 			executeShell(format("dmd -lib %s -of%s.lib %s.obj", ldflags, lib, lib));
109 			std.file.remove(lib ~".obj");
110 		}
111 	}
112 	
113 	std.file.remove("build.rf");
114 }
115 
116 void buildObj(string files, string objName)
117 {
118 	std.file.write("build.rf", format("-c %s -Igenerated/gtkd -of%s.obj %s", dcflags, objName, files));
119 	auto pid = spawnProcess(["dmd", "@build.rf"]);
120 	if ( wait(pid) != 0 )
121 		exit(1);
122 }
123 
124 string dFiles(string sourceDir)
125 {
126 	string files;
127 	auto entries = dirEntries(sourceDir, SpanMode.breadth);
128 	
129 	foreach ( DirEntry entry; entries )
130 	{
131 		if ( entry.isDir == false && entry.name.extension == ".d" )
132 		{
133 			files ~= entry.name ~ " ";
134 		}
135 	}
136 	
137 	return files;
138 }