comparison builder.d @ 132:bc5baa585b32

Updated to dmd 2.060
author David Bryant <bagnose@gmail.com>
date Thu, 02 Aug 2012 15:32:43 +0930
parents 1da160a2c373
children 9e1a313d8003
comparison
equal deleted inserted replaced
130:1bc3475624d3 132:bc5baa585b32
123 long modified_time(string path) { 123 long modified_time(string path) {
124 SysTime fileStatusChangeTime, fileAccessTime, fileModificationTime; 124 SysTime fileStatusChangeTime, fileAccessTime, fileModificationTime;
125 if (!exists(path)) { 125 if (!exists(path)) {
126 return 0; 126 return 0;
127 } 127 }
128 getTimesPosix(path, fileStatusChangeTime, fileAccessTime, fileModificationTime); 128 getTimes(path, fileAccessTime, fileModificationTime);
129 return fileStatusChangeTime.stdTime; 129 return fileModificationTime.stdTime;
130 } 130 }
131 131
132 132
133 // 133 //
134 // A string formatter that allows progressive composition 134 // A string formatter that allows progressive composition
189 // within the project, so we can write code that it works for. 189 // within the project, so we can write code that it works for.
190 // 190 //
191 void parseForImport(char[] line) { 191 void parseForImport(char[] line) {
192 static string[] leaders = ["private ", "public ", "static ", "import "]; 192 static string[] leaders = ["private ", "public ", "static ", "import "];
193 bool found; 193 bool found;
194 auto stripped = stripl(line); 194 auto stripped = stripLeft(line);
195 if (stripped.length > 8) { 195 if (stripped.length > 8) {
196 foreach (i, leader ; leaders) { 196 foreach (i, leader ; leaders) {
197 if (stripped[0..leader.length] == leader) { 197 if (stripped[0..leader.length] == leader) {
198 // this is a possibility - look for import token 198 // this is a possibility - look for import token
199 scope char[][] tokens = split(stripped); 199 scope char[][] tokens = split(stripped);
326 this(string path) { 326 this(string path) {
327 super("directory", path); 327 super("directory", path);
328 mTime = mPath.exists ? 1 : 0; 328 mTime = mPath.exists ? 1 : 0;
329 329
330 // this directory depends on its parent directory chain 330 // this directory depends on its parent directory chain
331 string parent_path = path.dirname; 331 string parent_path = path.dirName;
332 if (parent_path.length > 0 && parent_path[0] != '.' && parent_path != "/") { 332 if (parent_path.length > 0 && parent_path[0] != '.' && parent_path != "/") {
333 Item* parent = parent_path in mItems; 333 Item* parent = parent_path in mItems;
334 if (parent) { 334 if (parent) {
335 assert(cast(DirectoryItem *)parent); 335 assert(cast(DirectoryItem *)parent);
336 addDepends(*parent); 336 addDepends(*parent);
385 member.addDepends(other); 385 member.addDepends(other);
386 } 386 }
387 } 387 }
388 388
389 // and all other group's higher-level groups until common ancestor 389 // and all other group's higher-level groups until common ancestor
390 string other_parent_path = other.mPath.dirname; 390 string other_parent_path = other.mPath.dirName;
391 if (other_parent_path != "." && 391 if (other_parent_path != "." &&
392 other_parent_path.length < mPath.length && 392 other_parent_path.length < mPath.length &&
393 mPath[0..other_parent_path.length] != other_parent_path) 393 mPath[0..other_parent_path.length] != other_parent_path)
394 { 394 {
395 GroupItem* other_parent = other_parent_path in mGroups; 395 GroupItem* other_parent = other_parent_path in mGroups;
418 super(kind, path); 418 super(kind, path);
419 mGroup = group; 419 mGroup = group;
420 group.addMember(this); 420 group.addMember(this);
421 421
422 // this file depends on on its parent directory 422 // this file depends on on its parent directory
423 string parent_path = path.dirname; 423 string parent_path = path.dirName;
424 Item* parent = parent_path in mItems; 424 Item* parent = parent_path in mItems;
425 if (parent) { 425 if (parent) {
426 assert(cast(DirectoryItem *)parent); 426 assert(cast(DirectoryItem *)parent);
427 addDepends(*parent); 427 addDepends(*parent);
428 } 428 }
441 SourceItem[string] mImports; // the source items this one imports 441 SourceItem[string] mImports; // the source items this one imports
442 ObjectItem mObject; // the object item to be built from this source 442 ObjectItem mObject; // the object item to be built from this source
443 443
444 this(string path, GroupItem group) { 444 this(string path, GroupItem group) {
445 super("source", path, group); 445 super("source", path, group);
446 if (!isfile(path)) error(format("source file %s not found", path)); 446 if (!isFile(path)) error(format("source file %s not found", path));
447 } 447 }
448 448
449 // set the object item 449 // set the object item
450 void set_object(ObjectItem obj) { 450 void set_object(ObjectItem obj) {
451 mObject = obj; 451 mObject = obj;
513 // an object file is built from its source 513 // an object file is built from its source
514 override void build() { 514 override void build() {
515 writefln("Object %s", mPath); 515 writefln("Object %s", mPath);
516 scope cmd = new StringFormatter; 516 scope cmd = new StringFormatter;
517 517
518 cmd.format("dmd -m32 -c"); 518 cmd.format("dmd -m64 -c");
519 foreach (path; Global.bundlePaths) { 519 foreach (path; Global.bundlePaths) {
520 cmd.format(" -I%s", path); 520 cmd.format(" -I%s", path);
521 } 521 }
522 cmd.format(" -od%s %s", dirname(mPath), mSource.mPath); 522 cmd.format(" -od%s %s", dirName(mPath), mSource.mPath);
523 cmd.format(" @%s", Global.optionsPath); 523 cmd.format(" @%s", Global.optionsPath);
524 524
525 //writefln("cmd: %s", cmd.str);
525 if (std.process.system(cmd.str)) { 526 if (std.process.system(cmd.str)) {
526 writefln("%s", cmd.str); 527 writefln("%s", cmd.str);
527 error(format("build of %s failed", mPath)); 528 error(format("build of %s failed", mPath));
528 } 529 }
529 } 530 }
550 auto obj = cast(ObjectItem) item; 551 auto obj = cast(ObjectItem) item;
551 if (obj) { 552 if (obj) {
552 cmd.format(" %s", obj.mPath); 553 cmd.format(" %s", obj.mPath);
553 } 554 }
554 } 555 }
556 //writefln("cmd: %s", cmd.str);
555 if (std.process.system(cmd.str)) { 557 if (std.process.system(cmd.str)) {
556 writefln("%s", cmd.str); 558 writefln("%s", cmd.str);
557 error("command failed"); 559 error("command failed");
558 } 560 }
559 } 561 }
599 // the object needs, transitively 601 // the object needs, transitively
600 override void build() { 602 override void build() {
601 writefln("Program %s", mPath); 603 writefln("Program %s", mPath);
602 scope cmd = new StringFormatter(); 604 scope cmd = new StringFormatter();
603 605
604 cmd.format("dmd -m32 -L-L%s", std.path.join(Global.buildPath, "lib")); 606 cmd.format("dmd -m64 -L-L%s", buildPath(Global.buildPath, "lib"));
605 cmd.format(" -of%s %s", mPath, mObject.mPath); 607 cmd.format(" -of%s %s", mPath, mObject.mPath);
606 608
607 // add the libraries we need 609 // add the libraries we need
608 LibraryItem[] libs; 610 LibraryItem[] libs;
609 foreach (item; mDepends) { 611 foreach (item; mDepends) {
615 foreach_reverse (lib; libs) { 617 foreach_reverse (lib; libs) {
616 cmd.format(" -L-l%s", lib.mName); 618 cmd.format(" -L-l%s", lib.mName);
617 } 619 }
618 cmd.format(" @%s", Global.optionsPath); 620 cmd.format(" @%s", Global.optionsPath);
619 621
622 //writefln("cmd: %s", cmd.str);
620 if (std.process.system(cmd.str)) { 623 if (std.process.system(cmd.str)) {
621 writefln("%s", cmd.str); 624 writefln("%s", cmd.str);
622 error("command failed"); 625 error("command failed");
623 } 626 }
624 } 627 }
644 } 647 }
645 scope cmd = new StringFormatter(); 648 scope cmd = new StringFormatter();
646 scope tmpPath = mPath ~ ".failed"; 649 scope tmpPath = mPath ~ ".failed";
647 cmd.format("%s > %s 2>&1", mProgram.mPath, tmpPath); 650 cmd.format("%s > %s 2>&1", mProgram.mPath, tmpPath);
648 651
652 //writefln("cmd: %s", cmd.str);
649 if (std.process.system(cmd.str)) { 653 if (std.process.system(cmd.str)) {
650 // failed 654 // failed
651 writefln(" failed"); 655 writefln(" failed");
652 writefln("%s", cmd.str); 656 writefln("%s", cmd.str);
653 error("test failed"); 657 error("test failed");
692 assert(parent); 696 assert(parent);
693 mName = name; 697 mName = name;
694 mParent = parent; 698 mParent = parent;
695 if (parent.mName.length) { 699 if (parent.mName.length) {
696 // child of non-root 700 // child of non-root
697 mSlashName = parent.mSlashName ~ sep ~ mName; 701 mSlashName = parent.mSlashName ~ "/" ~ mName;
698 mDotName = parent.mDotName ~ "." ~ mName; 702 mDotName = parent.mDotName ~ "." ~ mName;
699 } 703 }
700 else { 704 else {
701 // child of the root 705 // child of the root
702 mSlashName = mName; 706 mSlashName = mName;
743 ObjectItem mObject; 747 ObjectItem mObject;
744 FileItem mClump; // library or program item this module contributes to 748 FileItem mClump; // library or program item this module contributes to
745 749
746 this(string name, string path, Node parent, GroupItem group) { 750 this(string name, string path, Node parent, GroupItem group) {
747 super(name, parent); 751 super(name, parent);
748 string obj_path = std.path.join(Global.buildPath, "obj", mSlashName ~ ".o"); 752 string obj_path = buildPath(Global.buildPath, "obj", mSlashName ~ ".o");
749 mSource = new SourceItem(path, group); 753 mSource = new SourceItem(path, group);
750 mObject = new ObjectItem(obj_path, mSource, group); 754 mObject = new ObjectItem(obj_path, mSource, group);
751 mSource.set_object(mObject); 755 mSource.set_object(mObject);
752 //writefln("loaded Module %s from %s", mDotName, mSource.mPath); 756 //writefln("loaded Module %s from %s", mDotName, mSource.mPath);
753 } 757 }
810 ResultItem mResult; 814 ResultItem mResult;
811 815
812 this(string name, string path, Node parent, bool test, GroupItem group) { 816 this(string name, string path, Node parent, bool test, GroupItem group) {
813 super(name, path, parent, group); 817 super(name, path, parent, group);
814 if (test) { 818 if (test) {
815 mProgram = new ProgramItem(std.path.join(Global.buildPath, "test", mSlashName), mObject, group); 819 mProgram = new ProgramItem(buildPath(Global.buildPath, "test", mSlashName), mObject, group);
816 mResult = new ResultItem(std.path.join(Global.buildPath, "test", mSlashName ~ ".result"), mProgram, group); 820 mResult = new ResultItem(buildPath(Global.buildPath, "test", mSlashName ~ ".result"), mProgram, group);
817 } 821 }
818 else { 822 else {
819 mProgram = new ProgramItem(std.path.join(Global.buildPath, "bin", mName), mObject, group); 823 mProgram = new ProgramItem(buildPath(Global.buildPath, "bin", mName), mObject, group);
820 } 824 }
821 setClump(mProgram); 825 setClump(mProgram);
822 //writefln("loaded Program %s", mProgram.mPath); 826 //writefln("loaded Program %s", mProgram.mPath);
823 } 827 }
824 } 828 }
837 mGroup = new GroupItem(mSlashName); 841 mGroup = new GroupItem(mSlashName);
838 842
839 string lib_name = replace(mDotName, ".", "_"); 843 string lib_name = replace(mDotName, ".", "_");
840 844
841 // examine all the children of the package's directory 845 // examine all the children of the package's directory
842 foreach (string child; listdir(path)) { 846 foreach (string child; dirEntries(path, SpanMode.shallow)) {
843 string p = std.path.join(path, child); 847 child = baseName(child);
848 string p = buildPath(path, child);
844 if (child[0] != '.') { 849 if (child[0] != '.') {
845 850
846 if (isfile(p)) { 851 if (isFile(p)) {
847 852
848 if (child.length > 2 && child[$-2..$] == ".d") { 853 if (child.length > 2 && child[$-2..$] == ".d") {
849 // a library module 854 // a library module
850 if (!mLibrary) { 855 if (!mLibrary) {
851 mLibrary = new LibraryItem(std.path.join(Global.buildPath, "lib", "lib" ~ lib_name ~ ".a"), 856 mLibrary = new LibraryItem(buildPath(Global.buildPath, "lib", "lib" ~ lib_name ~ ".a"),
852 lib_name, mGroup); 857 lib_name, mGroup);
853 } 858 }
854 Module m = new Module(getName(child), p, this, mGroup); 859 Module m = new Module(stripExtension(child), p, this, mGroup);
855 m.setClump(mLibrary); 860 m.setClump(mLibrary);
856 } 861 }
857 } 862 }
858 863
859 else if (isdir(p)) { 864 else if (isDir(p)) {
860 865
861 if (child == "build-tool") { 866 if (child == "build-tool") {
862 // reserved for build-tool 867 // reserved for build-tool
863 } 868 }
864 else if (child == "doc") { 869 else if (child == "doc") {
867 else if (child == "data") { 872 else if (child == "data") {
868 // TODO 873 // TODO
869 } 874 }
870 else if (child == "test") { 875 else if (child == "test") {
871 // test programs 876 // test programs
872 foreach (string grandchild; listdir(p)) { 877 foreach (string grandchild; dirEntries(p, SpanMode.shallow)) {
873 string p2 = std.path.join(p, grandchild); 878 grandchild = baseName(grandchild);
879 string p2 = buildPath(p, grandchild);
874 if (grandchild[0] != '.' && 880 if (grandchild[0] != '.' &&
875 isfile(p2) && 881 isFile(p2) &&
876 grandchild.length > 2 && 882 grandchild.length > 2 &&
877 grandchild[$-2..$] == ".d") 883 grandchild[$-2..$] == ".d")
878 { 884 {
879 Exe exe = new Exe(getName(grandchild), p2, this, true, mGroup); 885 Exe exe = new Exe(stripExtension(grandchild), p2, this, true, mGroup);
880 } 886 }
881 } 887 }
882 } 888 }
883 else if (child == "prog") { 889 else if (child == "prog") {
884 // deliverable programs 890 // deliverable programs
885 foreach (string grandchild; listdir(p)) { 891 foreach (string grandchild; dirEntries(p, SpanMode.shallow)) {
886 string p2 = std.path.join(p, grandchild); 892 grandchild = baseName(grandchild);
893 string p2 = buildPath(p, grandchild);
887 if (child[0] != '.' && 894 if (child[0] != '.' &&
888 isfile(p2) && 895 isFile(p2) &&
889 grandchild.length > 2 && 896 grandchild.length > 2 &&
890 grandchild[$-2..$] == ".d") 897 grandchild[$-2..$] == ".d")
891 { 898 {
892 Exe exe = new Exe(getName(grandchild), p2, this, false, mGroup); 899 Exe exe = new Exe(stripExtension(grandchild), p2, this, false, mGroup);
893 } 900 }
894 } 901 }
895 } 902 }
896 else { 903 else {
897 // a child package 904 // a child package
948 void load(string path) { 955 void load(string path) {
949 //writefln("loading bundle from %s", path); 956 //writefln("loading bundle from %s", path);
950 957
951 // add path to Global for use when compiling 958 // add path to Global for use when compiling
952 Global.bundlePaths ~= path; 959 Global.bundlePaths ~= path;
953 Global.optionsPath = std.path.join(path, "options"); 960 Global.optionsPath = buildPath(path, "options");
954 961
955 // 962 //
956 // load bundles specified in the uses file - lines are bundle paths relative to path 963 // load bundles specified in the uses file - lines are bundle paths relative to path
957 // 964 //
958 string uses_path = std.path.join(path, "uses"); 965 string uses_path = buildPath(path, "uses");
959 if (exists(uses_path) && isfile(uses_path)) { 966 if (exists(uses_path) && isFile(uses_path)) {
960 //writefln("reading uses file: %s", uses_path); 967 //writefln("reading uses file: %s", uses_path);
961 scope file = new BufferedFile(uses_path); 968 scope file = new BufferedFile(uses_path);
962 foreach (char[] line; file) { 969 foreach (char[] line; file) {
963 load(std.path.join(path, line.idup)); 970 load(buildPath(path, line.idup));
964 } 971 }
965 } 972 }
966 973
967 // 974 //
968 // load local products 975 // load local products
969 // 976 //
970 foreach (string name; listdir(path)) { 977 foreach (string name; dirEntries(path, SpanMode.shallow)) {
978 name = baseName(name);
971 if (name[0] != '.' && name != "nobuild") { 979 if (name[0] != '.' && name != "nobuild") {
972 string p = std.path.join(path, name); 980 string p = buildPath(path, name);
973 if (isdir(p)) { 981 if (isDir(p)) {
974 foreach (node; mChildren) { 982 foreach (node; mChildren) {
975 Product existing = cast(Product)node; 983 Product existing = cast(Product)node;
976 if (existing && existing.mName == name) { 984 if (existing && existing.mName == name) {
977 error(format("product %s has two paths: %s and %s", 985 error(format("product %s has two paths: %s and %s",
978 name, p, existing.mPath)); 986 name, p, existing.mPath));