comparison src/build/frankenbuild.d @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children e6cf9f26d0e7
comparison
equal deleted inserted replaced
-1:000000000000 0:3425707ddbf6
1 /**
2 * Hoofbaby -- http://www.dsource.org/projects/hoofbaby
3 * Copyright (C) 2009 Robert Fraser
4 *
5 * This program is free software; you can redistribute it andor
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 module frankenbuild;
17
18 import tango.io.Stdout;
19 import tango.sys.Process;
20 import tango.io.vfs.model.Vfs;
21 import tango.io.vfs.FileFolder;
22 import Path = tango.io.Path;
23
24 version(Windows) {} else static assert(false, "Build system only works for Windows");
25
26 const char[] rebuildPath = "build/rebuild.exe";
27 const char[] touchPath = "build/touch.exe";
28 const char[] upxPath = "build/upx.exe";
29 const char[] mcppPath = "build/mcpp.exe";
30
31 //TODO get these paths from registry
32 const char[] devenvPath = `"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com"`;
33
34 int main(char[][] args)
35 {
36 Stdout.flush(true);
37
38 if(args.length < 2)
39 {
40 Stdout("ERROR: Must specify a target");
41 return 1;
42 }
43
44 char[] target = args[1];
45 char[][] extraArgs = args[2..$];
46
47 char[] cbase;
48 cbase = " -I../src/impl";
49 cbase ~= " -w";
50 cbase ~= " ../deps/libav/gcc.lib ../deps/libav/avutil.lib ../deps/libav/avcodec.lib ../deps/libav/avformat.lib ../deps/libav/swscale.lib";
51 foreach(arg; extraArgs)
52 cbase ~= " " ~ arg;
53
54 bool targetFound = false;
55 char[][] cats = [target];
56 bool delegate()[] commands = [];
57
58 if(cats.contains("all"))
59 {
60 cats ~= "debug";
61 cats ~= "release";
62 }
63
64 if(cats.contains("debug"))
65 {
66 targetFound = true;
67 cats ~= "platif-debug";
68 char[] cargs = cbase.dup;
69 cargs ~= " -g";
70 cargs ~= " -debug -debug=AVBuffer";
71 cargs ~= " -ofhoofbaby-d/hoofbaby.exe";
72 cargs ~= " -oqobjs/debug";
73 cargs ~= " ../src/impl/hoofbaby/app/main.d";
74 commands ~= { return cpp("../src/platif/platif.h", "../src/impl/hoofbaby/platinum/platif.d"); };
75 commands ~= { return rebuild(cargs); };
76 }
77
78 if(cats.contains("release"))
79 {
80 targetFound = true;
81 cats ~= "platif-release";
82 char[] cargs = cbase.dup;
83 cargs ~= " -O -inline";
84 cargs ~= " -ofhoofbaby/hoofbaby.exe";
85 cargs ~= " -oqobjs/release";
86 cargs ~= " ../src/impl/hoofbaby/app/main.d";
87 commands ~= { return cpp("../src/platif/platif.h", "../src/impl/hoofbaby/platinum/platif.d"); };
88 commands ~= { return rebuild(cargs); };
89 commands ~= { return upx("hoofbaby/hoofbaby.exe"); };// D executables are enormous
90 }
91
92 if(cats.contains("platif-debug"))
93 {
94 targetFound = true;
95 char[] cargs = `..\deps\Platinum\Build\Targets\x86-microsoft-win32-vs2008\Platinum.sln /build "Debug|Win32" /project platif`;
96 commands ~= { return devenv(cargs); };
97 commands ~= { return rm("./hoofbaby-d", ["*.exp", "*.lib"]); };
98 }
99
100 if(cats.contains("platif-release"))
101 {
102 targetFound = true;
103 char[] cargs = `..\deps\Platinum\Build\Targets\x86-microsoft-win32-vs2008\Platinum.sln /build "Release|Win32" /project platif`;
104 commands ~= { return devenv(cargs); };
105 commands ~= { return rm("./hoofbaby", ["*.exp", "*.lib"]); };
106 }
107
108 if(!targetFound)
109 {
110 Stdout.format("Unknown or invalid target {0}", target).newline;
111 return 1;
112 }
113
114 commands ~= { return rm(".", ["*.map"]); }; // The builder itself may have created a .map, so run this every time
115 foreach(cmd; commands)
116 if(!cmd())
117 return 1;
118 return 0;
119 }
120
121 //------------------------------------------------------------------------------
122
123 bool contains(T)(T[] a, T b)
124 {
125 foreach(c; a)
126 if(b == c)
127 return true;
128 return false;
129 }
130
131 bool isNewerThan(char[] f1, char[] f2)
132 {
133 return Path.exists(f1) && Path.exists(f2) && Path.modified(f1) > Path.modified(f2);
134 }
135
136 //------------------------------------------------------------------------------
137
138 bool exec(char[] program, char[] args, bool print)
139 {
140 char[] cmd = program ~ " " ~ args;
141 if(print) Stdout("=> " ~ cmd).newline;
142 if((new Process(true, cmd)).setRedirect(Redirect.None).execute().wait().status)
143 return false;
144 if(print) Stdout.newline;
145 return true;
146 }
147
148 bool rebuild(char[] args) { return exec(rebuildPath, args, true); }
149 bool devenv(char[] args) { return exec(devenvPath, args, true); }
150 bool touch(char[] file) { return exec(touchPath, file, false); }
151 bool upx(char[] file) { return exec(upxPath, "-9 " ~ file, true); }
152
153 bool rm(char[] path, char[][] globs)
154 {
155 Stdout.format("=> rm {0} {1}", path, globs).newline;
156 FileFolder folder = new FileFolder(path);
157 foreach(glob; globs)
158 {
159 VfsFiles files = folder.tree.catalog(glob);
160 foreach(file; files)
161 try { file.remove(); } catch(Exception e) { Stdout(e.toString()).newline(); }
162 }
163 Stdout.newline;
164 return true; // Even if we failed to delete stuff, it's okay
165 }
166
167 bool cp(char[] isrc, char[] idst)
168 {
169 bool didCopy = false;
170
171 void copyFile(char[] src, char[] dst)
172 {
173 if(Path.exists(dst))
174 {
175 if(dst.isNewerThan(src))
176 return;
177 Path.remove(dst);
178 }
179 Path.copy(src, dst);
180 version(Windows) touch(dst); // Windows doesn't change the modification date unless this is done
181 didCopy = true;
182 }
183
184 void cpr(char[] src, char[] dst)
185 {
186 if(!Path.exists(dst))
187 {
188 Path.createFolder(dst);
189 didCopy = true;
190 }
191 foreach(info; Path.children(src))
192 {
193 char[] srcPath = src ~ "/" ~ info.name;
194 char[] dstPath = dst ~ "/" ~ info.name;
195 if(info.folder)
196 cpr(srcPath, dstPath);
197 else
198 copyFile(srcPath, dstPath);
199 }
200 }
201
202 try
203 {
204 isrc = Path.standard(isrc);
205 idst = Path.standard(idst);
206 if(Path.isFolder(isrc))
207 cpr(isrc, idst);
208 else
209 copyFile(isrc, idst);
210 if(didCopy)
211 Stdout.format("=> cp {0} {1}", isrc, idst).newline.newline;
212 }
213 catch(Exception e)
214 {
215 Stdout.format("=> cp {0} {1}", isrc, idst).newline;
216 Stdout(e.toString()).newline.newline;
217 return false;
218 }
219
220 return true;
221 }
222
223 bool cpp(char[] src, char[] dst, char[] extraParams = "")
224 {
225 if(dst.isNewerThan(src))
226 return true;
227 char[] cmd = src ~ " -o " ~ dst ~ " -I../src -D__D -e utf8" ~ extraParams;
228 return exec(mcppPath, cmd, true);
229 }