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 debug {} else string DEBUG = "";
20 
21 version(DigitalMars)
22 {
23 	string DC = "dmd";
24 	string OUTPUT = "-of";
25 
26 	debug string DEBUG = "-debug -g";
27 
28 	version(CRuntime_DigitalMars)
29 		string PLATFORM = "-m32";
30 	else version(X86)
31 		string PLATFORM = "-m32mscoff";
32 	else version(X86_64)
33 		string PLATFORM = "-m64";
34 
35 	version(CRuntime_DigitalMars) version = DMD32;
36 }
37 else version(LDC)
38 {
39 	string DC = "ldc2";
40 	string OUTPUT = "-od=objects -oq -of";
41 
42 	debug string DEBUG = "-d-debug -g";
43 
44 	version(X86)
45 		string PLATFORM = "-m32";
46 	else version(X86_64)
47 		string PLATFORM = "-m64";
48 }
49 else version(GNU)
50 {
51 	string DC = "gdc";
52 	string OUTPUT = "-o ";
53 
54 	debug string DEBUG = "-fdebug -g";
55 
56 	version(X86)
57 		string PLATFORM = "-m32";
58 	else version(X86_64)
59 		string PLATFORM = "-m64";
60 }
61 else
62 {
63 	static assert(false, "Unsupported compiler");
64 }
65 
66 int main(string[] args)
67 {
68 	version(Posix)
69 	{
70 		writeln("This build script is currently Windows only.");
71 		return(1);
72 	}
73 
74 	getopt(args, "dcflags", &dcflags, "ldflags", &ldflags);
75 	args.popFront();
76 	
77 	foreach ( arg; args )
78 	{
79 		if ( !["gtkd", "gstreamer", "vte", "peas", "all"].canFind(arg) )
80 		{
81 			writefln("Unknown option: %s", arg);
82 			return 1;
83 		}
84 	}
85 	
86 	if ( args.length == 0 )
87 		args = ["gtkd"];
88 		
89 	if ( args.canFind("all") )
90 		args = ["gtkd", "gstreamer", "peas"];
91 	
92 	foreach ( arg; args )
93 	{
94 		switch ( arg )
95 		{
96 			case "gtkd":
97 				build("generated\\gtkd", "gtkd");
98 				break;
99 			case "gstreamer":
100 				build("generated\\gstreamer", "gstreamerd");
101 				break;
102 			case "peas":
103 				build("generated\\peas", "peasd");
104 				break;
105 			default:
106 				assert(false);
107 				break;
108 		}
109 	}
110 	
111 	return(0);
112 }
113 
114 void build(string dir, string lib)
115 {
116 	version(DMD32)
117 	{
118 		if (lib == "gtkd")
119 		{
120 			string[] subDirs = ["atk", "cairo", "gdk", "gdkpixbuf", "gio", "glib", "gobject", "gthread", "graphene", "gtkd", "pango", "harfbuzz", "rsvg"];
121 
122 			foreach(directory; subDirs)
123 				buildObj(dFiles("generated\\gtkd\\"~ directory), directory);
124 
125 			string[] files = dFiles("generated\\gtkd\\gtk").split();
126 			files.chunks((files.length / 4) + 1).enumerate(1).each!((index, value){buildObj(value.join(' '), "gtk"~to!string(index));});
127 
128 			string objects;
129 			foreach(directory; subDirs)
130 				objects ~= directory ~".obj ";
131 			objects ~= "gtk1.obj gtk2.obj gtk3.obj gtk4.obj";
132 
133 			executeShell(format("dmd -lib %s %s%s.lib %s", ldflags, OUTPUT, lib, objects));
134 
135 			foreach(string obj; objects.split())
136 				std.file.remove(obj);
137 		}
138 		else
139 		{
140 			buildObj(dFiles(dir), lib);
141 			executeShell(format("dmd -lib %s %s%s.lib %s.obj", ldflags, OUTPUT, lib, lib));
142 			std.file.remove(lib ~".obj");
143 		}
144 	}
145 	else
146 	{
147 		std.file.write("build.rf", format("%s -c -lib %s %s %s -Igenerated/gtkd %s%s.lib %s", PLATFORM, dcflags, ldflags, DEBUG, OUTPUT ,lib, dFiles(dir)));
148 		auto pid = spawnProcess([DC, "@build.rf"]);
149 
150 		if ( wait(pid) != 0 )
151 			exit(1);
152 	}
153 	
154 	version(LDC)std.file.rmdirRecurse("objects");
155 //	std.file.remove("build.rf");
156 }
157 
158 void buildObj(string files, string objName)
159 {
160 	std.file.write("build.rf", format("-c %s %s -Igenerated/gtkd %s%s.obj %s", dcflags, DEBUG, OUTPUT, objName, files));
161 	auto pid = spawnProcess(["dmd", "@build.rf"]);
162 	if ( wait(pid) != 0 )
163 		exit(1);
164 }
165 
166 string dFiles(string sourceDir)
167 {
168 	string files;
169 	auto entries = dirEntries(sourceDir, SpanMode.breadth);
170 	
171 	foreach ( DirEntry entry; entries )
172 	{
173 		if ( entry.isDir == false && entry.name.extension == ".d" )
174 		{
175 			files ~= entry.name ~ " ";
176 		}
177 	}
178 	
179 	return files;
180 }