view src/build/frankenbuild.d @ 9:05c88622db6b default tip

- Adhoc transcoder now doesn't rely on Platinum - Moved the adhoc transcoder to the main source tree; it can be moved back into test once it's more stable
author fraserofthenight
date Tue, 14 Jul 2009 22:04:05 -0700
parents 270343d824ae
children
line wrap: on
line source

/**
 * 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("transcode"))
    {
    	targetFound = true;
	    char[] cargs = cbase.dup;
	    cargs ~= " -g";
	    cargs ~= " -debug -debug=AVBuffer";
	    cargs ~= " -ofhoofbaby-d/transcode.exe";
	    cargs ~= " -I../src/test";
	    cargs ~= " -oqobjs/transcode";
	    cargs ~= " ../src/impl/hoofbaby/app/transcode.d";
	    commands ~= { return rebuild(cargs); };
    }
	
	/+ if(cats.contains("debug"))
	{
	    targetFound = true;
	    cats ~= "platif-debug";
	    char[] cargs = cbase.dup;
	    cargs ~= " -g";
	    cargs ~= " -debug -debug=AVBuffer";
    	cargs ~= " -version=UPnP";
	    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 ~= " -version=UPnP";
	    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);
}