diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/build/frankenbuild.d	Mon Jul 06 08:06:28 2009 -0700
@@ -0,0 +1,229 @@
+/**
+ * Hoofbaby -- http://www.dsource.org/projects/hoofbaby
+ * Copyright (C) 2009 Robert Fraser
+ * 
+ * This program is free software; you can redistribute it andor
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+module frankenbuild;
+
+import tango.io.Stdout;
+import tango.sys.Process;
+import tango.io.vfs.model.Vfs;
+import tango.io.vfs.FileFolder;
+import Path = tango.io.Path;
+
+version(Windows) {} else static assert(false, "Build system only works for Windows");
+
+const char[] rebuildPath = "build/rebuild.exe";
+const char[] touchPath = "build/touch.exe";
+const char[] upxPath = "build/upx.exe";
+const char[] mcppPath = "build/mcpp.exe";
+
+//TODO get these paths from registry
+const char[] devenvPath = `"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com"`;
+
+int main(char[][] args)
+{   
+    Stdout.flush(true);
+    
+	if(args.length < 2)
+	{
+		Stdout("ERROR: Must specify a target");
+		return 1;
+	}
+	
+	char[] target = args[1];
+	char[][] extraArgs = args[2..$];
+	
+	char[] cbase;
+	cbase = " -I../src/impl";
+	cbase ~= " -w";
+	cbase ~= " ../deps/libav/gcc.lib ../deps/libav/avutil.lib ../deps/libav/avcodec.lib ../deps/libav/avformat.lib ../deps/libav/swscale.lib";
+    foreach(arg; extraArgs)
+	    cbase ~= " " ~ arg;
+    
+    bool targetFound = false;
+    char[][] cats = [target];
+    bool delegate()[] commands = [];
+    
+    if(cats.contains("all"))
+    {
+        cats ~= "debug";
+        cats ~= "release";
+    }
+	
+	if(cats.contains("debug"))
+	{
+	    targetFound = true;
+	    cats ~= "platif-debug";
+	    char[] cargs = cbase.dup;
+	    cargs ~= " -g";
+	    cargs ~= " -debug -debug=AVBuffer";
+	    cargs ~= " -ofhoofbaby-d/hoofbaby.exe";
+	    cargs ~= " -oqobjs/debug";
+	    cargs ~= " ../src/impl/hoofbaby/app/main.d";
+	    commands ~= { return cpp("../src/platif/platif.h", "../src/impl/hoofbaby/platinum/platif.d"); };
+	    commands ~= { return rebuild(cargs); };
+	}
+	
+	if(cats.contains("release"))
+    {
+        targetFound = true;
+	    cats ~= "platif-release";
+	    char[] cargs = cbase.dup;
+	    cargs ~= " -O -inline";
+	    cargs ~= " -ofhoofbaby/hoofbaby.exe";
+	    cargs ~= " -oqobjs/release";
+	    cargs ~= " ../src/impl/hoofbaby/app/main.d";
+	    commands ~= { return cpp("../src/platif/platif.h", "../src/impl/hoofbaby/platinum/platif.d"); };
+	    commands ~= { return rebuild(cargs); };
+	    commands ~= { return upx("hoofbaby/hoofbaby.exe"); };// D executables are enormous
+    }
+	
+	if(cats.contains("platif-debug"))
+	{
+	    targetFound = true;
+	    char[] cargs = `..\deps\Platinum\Build\Targets\x86-microsoft-win32-vs2008\Platinum.sln /build "Debug|Win32" /project platif`;
+	    commands ~= { return devenv(cargs); };
+	    commands ~= { return rm("./hoofbaby-d", ["*.exp", "*.lib"]); };
+	}
+	
+	if(cats.contains("platif-release"))
+	{
+	    targetFound = true;
+	    char[] cargs = `..\deps\Platinum\Build\Targets\x86-microsoft-win32-vs2008\Platinum.sln /build "Release|Win32" /project platif`;
+	    commands ~= { return devenv(cargs); };
+	    commands ~= { return rm("./hoofbaby", ["*.exp", "*.lib"]); };
+	}
+	
+	if(!targetFound)
+	{
+		Stdout.format("Unknown or invalid target {0}", target).newline;
+		return 1;
+	}
+	
+	commands ~= { return rm(".", ["*.map"]); }; // The builder itself may have created a .map, so run this every time
+    foreach(cmd; commands)
+        if(!cmd())
+            return 1;
+    return 0;
+}
+
+//------------------------------------------------------------------------------
+
+bool contains(T)(T[] a, T b)
+{
+    foreach(c; a)
+        if(b == c)
+            return true;
+    return false;
+}
+
+bool isNewerThan(char[] f1, char[] f2)
+{
+    return Path.exists(f1) && Path.exists(f2) && Path.modified(f1) > Path.modified(f2);
+}
+
+//------------------------------------------------------------------------------
+
+bool exec(char[] program, char[] args, bool print)
+{
+    char[] cmd = program ~ " " ~ args;
+    if(print) Stdout("=> " ~ cmd).newline;
+    if((new Process(true, cmd)).setRedirect(Redirect.None).execute().wait().status)
+        return false;
+    if(print) Stdout.newline;
+    return true;
+}
+
+bool rebuild(char[] args) { return exec(rebuildPath, args, true);     }
+bool devenv(char[] args)  { return exec(devenvPath, args, true);      }
+bool touch(char[] file)   { return exec(touchPath, file, false);      }
+bool upx(char[] file)     { return exec(upxPath, "-9 " ~ file, true); }
+
+bool rm(char[] path, char[][] globs)
+{
+    Stdout.format("=> rm {0} {1}", path, globs).newline;
+    FileFolder folder = new FileFolder(path);
+    foreach(glob; globs)
+    {
+        VfsFiles files = folder.tree.catalog(glob);
+        foreach(file; files)
+            try { file.remove(); } catch(Exception e) { Stdout(e.toString()).newline(); }
+    }
+    Stdout.newline;
+    return true; // Even if we failed to delete stuff, it's okay
+}
+
+bool cp(char[] isrc, char[] idst)
+{
+    bool didCopy = false;
+    
+    void copyFile(char[] src, char[] dst)
+    {
+        if(Path.exists(dst))
+        {
+            if(dst.isNewerThan(src))
+                return;
+            Path.remove(dst);
+        }
+        Path.copy(src, dst);
+        version(Windows) touch(dst); // Windows doesn't change the modification date unless this is done
+        didCopy = true;
+    }
+    
+    void cpr(char[] src, char[] dst)
+    {
+        if(!Path.exists(dst))
+        {
+            Path.createFolder(dst);
+            didCopy = true;
+        }
+        foreach(info; Path.children(src))
+        {
+            char[] srcPath = src ~ "/" ~ info.name;
+            char[] dstPath = dst ~ "/" ~ info.name;
+            if(info.folder)
+                cpr(srcPath, dstPath);
+            else
+                copyFile(srcPath, dstPath);
+        }
+    }
+    
+    try
+    {
+        isrc = Path.standard(isrc);
+        idst = Path.standard(idst);
+        if(Path.isFolder(isrc))
+            cpr(isrc, idst);
+        else
+            copyFile(isrc, idst);
+        if(didCopy)
+            Stdout.format("=> cp {0} {1}", isrc, idst).newline.newline;
+    }
+    catch(Exception e)
+    {
+        Stdout.format("=> cp {0} {1}", isrc, idst).newline;
+        Stdout(e.toString()).newline.newline;
+        return false;
+    }
+    
+    return true;
+}
+
+bool cpp(char[] src, char[] dst, char[] extraParams = "")
+{
+    if(dst.isNewerThan(src))
+        return true;
+    char[] cmd = src ~ " -o " ~ dst ~ " -I../src -D__D -e utf8" ~ extraParams;
+    return exec(mcppPath, cmd, true);
+}