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