{"action":"created","comment":{"url":"https://api.github.com/repos/dlang/dmd/pulls/comments/190956727","pull_request_review_id":123449342,"id":190956727,"diff_hunk":"@@ -0,0 +1,1105 @@\n+#!/usr/bin/env rdmd\n+/**\n+DMD builder\n+\n+Usage:\n+  ./build.d dmd\n+*/\n+\n+import std.algorithm, std.conv, std.datetime, std.exception, std.file, std.format,\n+       std.getopt, std.parallelism, std.path, std.process, std.range, std.stdio, std.string;\n+import core.stdc.stdlib : exit;\n+\n+const srcDir = __FILE_FULL_PATH__.dirName.buildNormalizedPath;\n+shared bool verbose; // output verbose logging\n+shared bool force; // always build everything (ignores timestamp checking)\n+\n+__gshared string[string] env;\n+__gshared string[][string] flags;\n+__gshared typeof(sourceFiles()) sources;\n+\n+void main(string[] args)\n+{\n+    int jobs = totalCPUs;\n+    auto res = getopt(args,\n+        \"j|jobs\", \"Specifies the number of jobs (commands) to run simultaneously (default: %d)\".format(totalCPUs), &jobs,\n+        \"v\", \"Verbose command output\", (cast(bool*) &verbose),\n+        \"f\", \"Force run (ignore timestamps and always run all tests)\", (cast(bool*) &force),\n+    );\n+    if (res.helpWanted)\n+    {\n+        defaultGetoptPrinter(`./build.d <targets>...\n+\n+Examples:\n+\n+    ./run.d dmd                                                  # build DMD\n+    ./run.d unittest                                             # runs internal unittests\n+    ./run.d clean                                                # remove all generated files\n+\n+Options:\n+`, res.options);\n+        \"\\nSee the README.md for a more in-depth explanation of the test-runner.\".writeln;\n+        return;\n+    }\n+\n+    // parse arguments\n+    args.popFront;\n+    args2Environment(args);\n+\n+    // bootstrap all needed environment variables\n+    env = getEnvironment;\n+\n+    // get all sources\n+    sources = sourceFiles;\n+\n+    // default target\n+    if (!args.length)\n+        args = [\"all\"];\n+\n+    auto targets = args\n+        .predefinedTargets // preprocess\n+        .array;\n+\n+    if (targets.length > 0)\n+    {\n+        if (verbose)\n+        {\n+            log(\"================================================================================\");\n+            foreach (key, value; env)\n+                log(\"%s=%s\", key, value);\n+            log(\"================================================================================\");\n+        }\n+    }\n+}\n+\n+////////////////////////////////////////////////////////////////////////////////\n+// D build rules\n+////////////////////////////////////////////////////////////////////////////////\n+\n+// TODO: this is probably not needed anymore\n+auto newDelete()\n+{\n+    Rule rule = {\n+        target: env[\"G\"].buildPath(\"newdelete\").objName,\n+        sources: [env[\"ROOT\"].buildPath(\"newdelete.c\")],\n+        command: [env[\"HOST_CXX\"], \"-c\", \"-o$@\", \"$<\"]\n+    };\n+    return rule;\n+}\n+\n+auto lexer()\n+{\n+    Rule rule = {\n+        target: env[\"G\"].buildPath(\"lexer\").libName,\n+        sources: sources.lexer.chain(sources.lexerRoot).array,\n+        command: [\n+            env[\"HOST_DMD_RUN\"],\n+            \"-of$@\",\n+            \"-lib\",\n+            \"-J\"~env[\"G\"], \"-J../res\",\n+            \"-L-lstdc++\",\n+        ].chain(flags[\"DFLAGS\"], \"$<\".only).array\n+    };\n+    return rule;\n+}\n+\n+auto dmdConf()\n+{\n+    // TODO: add support for Windows\n+    string exportDynamic;\n+    version(OSX) {} else\n+        exportDynamic = \" -L--export-dynamic\";\n+\n+    auto conf = `[Environment32]\n+DFLAGS=-I%@P%/../../../../../druntime/import -I%@P%/../../../../../phobos -L-L%@P%/../../../../../phobos/generated/$(OS)/$(BUILD)/32{exportDynamic}\n+\n+[Environment64]\n+DFLAGS=-I%@P%/../../../../../druntime/import -I%@P%/../../../../../phobos -L-L%@P%/../../../../../phobos/generated/$(OS)/$(BUILD)/64{exportDynamic} -fPIC`.replace(\"{exportDynamic}\", exportDynamic);\n+\n+    auto target = env[\"G\"].buildPath(\"dmd.conf\");\n+    Rule rule = {\n+        target: target,\n+        commandFun: (){\n+            conf.toFile(target);\n+            return true;\n+        }\n+    };\n+    return rule;\n+}\n+\n+// opTabGen generates a few C++ files\n+auto opTabGen()\n+{\n+    auto opTabFiles = [\"debtab.c\", \"optab.c\", \"cdxxx.c\", \"elxxx.c\", \"fltables.c\", \"tytab.c\"];\n+    auto opTabFilesBin = opTabFiles.map!(e => env[\"G\"].buildPath(e)).array;\n+    auto opTabBin = env[\"G\"].buildPath(\"optabgen\").exeName;\n+    auto opTabSourceFile = env[\"C\"].buildPath(\"optabgen.c\");\n+    Rule rule = {\n+        targets: opTabFilesBin,\n+        sources: [opTabSourceFile],\n+        commandFun: (){\n+            auto args = [env[\"HOST_CXX\"], \"-I\"~env[\"TK\"], opTabSourceFile, \"-o\", opTabBin];\n+            args ~= flags[\"CXXFLAGS\"];\n+            run(args).writeln;\n+            [opTabBin].run.writeln;\n+            foreach (s, t; opTabFiles.lockstep(opTabFilesBin))\n+                s.rename(t);\n+            return true;\n+        }\n+    };\n+    return rule;\n+}\n+\n+// Build the C++ part of the backend\n+auto buildCXX(string obj, string fileName)\n+{\n+    Rule rule = {\n+        target: obj,\n+        sources: [fileName],\n+        name: \"(CC) BACK_OBJS %s\".format(fileName),\n+        command: [env[\"HOST_CXX\"], \"-c\", \"-o$@\"].chain(flags[\"CXXFLAGS\"], flags[\"BACK_FLAGS\"], \"$<\".only).array\n+    };\n+    //args ~= env[\"MMD\"];\n+    return rule;\n+}\n+\n+// Build the D part of the backend\n+auto dBackend()\n+{\n+    Rule rule = {\n+        target: env[\"G\"].buildPath(\"dbackend\").objName,\n+        sources: sources.backend,\n+        name: \" (CC) D_BACK_OBJS %-(%s %)\".format(sources.backend),\n+        command: [\n+            env[\"HOST_DMD_RUN\"],\n+            \"-c\",\n+            \"-of$@\",\n+            \"-betterC\",\n+            \"$<\"\n+        ]\n+    };\n+    return rule;\n+}\n+\n+auto cxxBackend()\n+{\n+    Rule[] rules;\n+    foreach (obj; sources.backendObjects)\n+        rules ~= buildCXX(obj, env[\"C\"].buildPath(obj.baseName.stripExtension ~ \".c\"));\n+\n+    return rules;\n+}\n+\n+auto buildBackend()\n+{\n+    opTabGen.run;\n+\n+    Rule[] rules = cxxBackend();\n+    rules ~= dBackend;\n+    foreach (rule; rules.parallel(1))\n+        rule.run;\n+\n+    // Pack the backend\n+    Rule rule = {\n+        sources: sources.backendObjects.chain(env[\"G\"].buildPath(\"dbackend\").objName.only).array,\n+        target: env[\"G\"].buildPath(\"backend\").libName,\n+        command: [env[\"AR\"], \"rcs\", \"$@\", \"$<\"],\n+    };\n+    rule.run;\n+    return rule;\n+}\n+\n+auto buildStringFiles()\n+{\n+    const versionFile = env[\"G\"].buildPath(\"VERSION\");\n+    Rule versionRule = {\n+        target: versionFile,\n+        commandFun: (){\n+            [\"git\", \"describe\", \"--dirty\"].execute.output.toFile(versionFile);\n+            return true;\n+        }\n+    };\n+    const sysconfDirFile = env[\"G\"].buildPath(\"SYSCONFDIR.imp\");\n+    Rule sysconfDirRule = {\n+        target: sysconfDirFile,\n+        commandFun: (){\n+            env[\"SYSCONFDIR\"].toFile(sysconfDirFile);\n+            return true;\n+        }\n+    };\n+    return [versionRule, sysconfDirRule];\n+}\n+\n+auto buildDMD()\n+{\n+    Rule[] rules = buildStringFiles();\n+    foreach (rule; rules.parallel(1))\n+        rule.run;\n+    rules = [lexer, newDelete, dmdConf];\n+    foreach (ref rule; rules.parallel(1))\n+        rule.run;\n+    auto backend = buildBackend();\n+\n+    // Main DMD build rule\n+    Rule rule = {\n+        // newdelete.o + lexer.a + backend.a\n+        sources: sources.dmd.chain(sources.root, rules[0].targets, rules[1].targets, backend.targets).array,\n+        target: env[\"G\"].buildPath(\"dmd\").exeName,\n+        command: [\n+            env[\"HOST_DMD_RUN\"],\n+            \"-of$@\",\n+            \"-vtls\",\n+            \"-J\"~env[\"G\"],\n+            \"-J../res\",\n+            \"-L-lstdc++\",\n+        ].chain(flags[\"DFLAGS\"], \"$<\".only).array\n+    };\n+    rule.run;\n+}\n+\n+/**\n+Goes through the target list and replaces short-hand targets with their expanded version.\n+Special targets:\n+- clean -> removes generated directory + immediately stops the builder\n+*/\n+auto predefinedTargets(string[] targets)\n+{\n+    Appender!(string[]) newTargets;\n+    foreach (t; targets)\n+    {\n+        t = t.buildNormalizedPath; // remove trailing slashes\n+        switch (t)\n+        {\n+            case \"auto-tester-build\":\n+                \"TODO: auto-tester-all\".writeln; // TODO\n+                break;\n+\n+            case \"toolchain-info\":\n+                \"TODO: info\".writeln; // TODO\n+                break;\n+\n+            case \"unittest\":\n+                \"TODO: unittest\".writeln; // TODO\n+                break;\n+\n+            case \"cxx-unittest\":\n+                \"TODO: cxx-unittest\".writeln; // TODO\n+                break;\n+\n+            case \"check-examples\":\n+                \"TODO: cxx-unittest\".writeln; // TODO\n+                break;\n+\n+            case \"build-examples\":\n+                \"TODO: build-examples\".writeln; // TODO\n+                break;\n+\n+            case \"checkwhitespace\":\n+                \"TODO: checkwhitespace\".writeln; // TODO\n+                break;\n+\n+            case \"html\":\n+                \"TODO: html\".writeln; // TODO\n+                break;\n+\n+            case \"install\":\n+                \"TODO: install\".writeln; // TODO\n+                break;\n+\n+            case \"man\":\n+                \"TODO: man\".writeln; // TODO\n+                break;\n+\n+            dmd:\n+            case \"dmd\":\n+                buildDMD();\n+                break;\n+\n+            case \"clean\":\n+                env[\"G\"].rmdirRecurse;\n+                exit(0);\n+                break;\n+\n+            default:\n+            case \"all\":\n+                goto dmd;\n+                break;\n+        }\n+    }\n+    return newTargets.data;\n+}\n+\n+// Sets the environment variables\n+string[string] getEnvironment()\n+{\n+    string[string] env;\n+\n+    env.getDefault(\"TARGET_CPU\", \"X86\");\n+    auto os = env.getDefault(\"OS\", detectOS);\n+    auto build = env.getDefault(\"BUILD\", \"release\");\n+    enforce(build.among(\"release\", \"debug\"), \"BUILD must be 'debug' or 'release'\");\n+\n+    // detect Model\n+    auto model = env.getDefault(\"MODEL\", detectModel);\n+    env[\"MODEL_FLAG\"] = \"-m\" ~ env[\"MODEL\"];\n+\n+    // PIC\n+    version(Posix)\n+    {\n+        // default to PIC on x86_64, use PIC=1/0 to en-/disable PIC.\n+        // Note that shared libraries and C files are always compiled with PIC.\n+        bool pic;\n+        version(X86_64)\n+            pic = true;\n+        else version(X86)\n+            pic = false;\n+        if (environment.get(\"PIC\", \"0\") == \"1\")\n+            pic = true;\n+\n+        env[\"PIC_FLAG\"]  = pic ? \"-fPIC\" : \"\";\n+    }\n+    else\n+    {\n+        env[\"PIC_FLAG\"] = \"\";\n+    }\n+\n+    env.getDefault(\"GIT_HOME\", \"https://github.com/dlang\");\n+    env.getDefault(\"SYSCONFDIR\", \"/etc\");\n+    env.getDefault(\"TMP\", \"/tmp\"); // TODO: allow environment variables\n+    env.getDefault(\"PGO_DIR\", srcDir.buildPath(\"pgo\"));\n+    auto d = env.getDefault(\"D\", \"dmd\");\n+    env.getDefault(\"C\", d.buildPath(\"backend\"));\n+    env.getDefault(\"TK\", d.buildPath(\"tk\"));\n+    env.getDefault(\"ROOT\", d.buildPath(\"root\"));\n+    env.getDefault(\"EX\", d.buildPath(\"examples\"));\n+    auto generated = env.getDefault(\"GENERATED\", srcDir.dirName.buildPath(\"generated\"));\n+    auto g = env.getDefault(\"G\", generated.buildPath(os, build, model));\n+    mkdirRecurse(g);\n+\n+    env.getDefault(\"HOST_CXX\", \"c++\");\n+    env.getDefault(\"AR\", \"ar\");\n+    env.getDefault(\"GIT\", \"git\");\n+    auto cxxVersion = execute([env[\"HOST_CXX\"], \"--version\"]).output;\n+    env.getDefault(\"CXX_KIND\", !cxxVersion.find(\"gcc\", \"Free Software\")[0].empty ? \"g++\" : \"clang++\");\n+\n+    env.getDefault(\"HOST_DMD\", \"dmd\");\n+\n+    // TODO: auto-bootstrapping\n+    if (env.getDefault(\"AUTO_BOOTSTRAP\", \"0\") != \"0\")\n+    {\n+        auto hostDMDVer = \"2.074.1\";\n+        writefln(\"Using Bootstrap compiler: %s\", hostDMDVer);\n+        auto hostDMDRoot = env[\"G\"].buildPath(\"host_dmd-\"~hostDMDVer);\n+        auto hostDMDBase = hostDMDVer~\".\"~os;\n+        auto hostDMDURL = \"http://downloads.dlang.org/releases/2.x/\"~hostDMDVer~\"/dmd.\"~hostDMDBase;\n+        env[\"HOST_DMD\"] = hostDMDRoot.buildPath(\"dmd2\", os, os == \"osx\" ? \"bin\" : \"bin\"~model, \"dmd\");\n+        env[\"HOST_DMD_PATH\"] = env[\"HOST_DMD\"];\n+        // TODO: use dmd.conf from the host too (in case there's a global or user-level dmd.conf)\n+        env[\"HOST_DMD_RUN\"] = env[\"HOST_DMD\"];\n+        if (!env[\"HOST_DMD\"].exists)\n+        {\n+            writefln(\"Downloaded DMD %s\", hostDMDVer);\n+            auto curlFlags = \"-fsSL --retry 5 --retry-max-time 120 --connect-timeout 5 --speed-time 30 --speed-limit 1024\";\n+            hostDMDRoot.mkdirRecurse;\n+            (\"curl \" ~ curlFlags ~ \" \" ~ hostDMDURL~\".tar.xz | tar -C \"~hostDMDRoot~\" -Jxf - || rm -rf \"~hostDMDRoot).spawnShell.wait;\n+        }\n+    }\n+    else\n+    {\n+        env[\"HOST_DMD_PATH\"] = [\"which\", env[\"HOST_DMD\"]].execute.output;\n+        env[\"HOST_DMD_RUN\"] = env[\"HOST_DMD\"];\n+    }\n+\n+    if (!env[\"HOST_DMD\"].exists)\n+    {\n+        stderr.writefln(\"No DMD compiler is installed. Try AUTO_BOOTSTRAP=1 or manually set the D host compiler with HOST_DMD\");\n+        exit(1);\n+    }\n+\n+    auto hostDMDVersion = [env[\"HOST_DMD_RUN\"], \"--version\"].execute.output;\n+    if (hostDMDVersion.find(\"DMD\"))\n+        env[\"HOST_DMD_KIND\"] = \"dmd\";\n+    else if (hostDMDVersion.find(\"LDC\"))\n+        env[\"HOST_DMD_KIND\"] = \"ldc\";\n+    else if (!hostDMDVersion.find(\"GDC\", \"gdmd\")[0].empty)\n+        env[\"HOST_DMD_KIND\"] = \"gdc\";\n+    else\n+        enforce(0, \"Invalid Host DMD found: \" ~ hostDMDVersion);\n+\n+    env.getDefault(\"ENABLE_WARNINGS\", \"0\");\n+    string[] warnings;\n+    if (env[\"ENABLE_WARNINGS\"] != \"0\")\n+    {\n+        warnings = [\"-Wall\", \"-Wextra\", \"-Werror\",\n+\t        \"-Wno-attributes\",\n+\t        \"-Wno-char-subscripts\",\n+\t        \"-Wno-deprecated\",\n+\t        \"-Wno-empty-body\",\n+\t        \"-Wno-format\",\n+\t        \"-Wno-missing-braces\",\n+\t        \"-Wno-missing-field-initializers\",\n+\t        \"-Wno-overloaded-virtual\",\n+\t        \"-Wno-parentheses\",\n+\t        \"-Wno-reorder\",\n+\t        \"-Wno-return-type\",\n+\t        \"-Wno-sign-compare\",\n+\t        \"-Wno-strict-aliasing\",\n+\t        \"-Wno-switch\",\n+\t        \"-Wno-type-limits\",\n+\t        \"-Wno-unknown-pragmas\",\n+\t        \"-Wno-unused-function\",\n+\t        \"-Wno-unused-label\",\n+\t        \"-Wno-unused-parameter\",\n+\t        \"-Wno-unused-value\",\n+\t        \"-Wno-unused-variable\",\n+\t    ];\n+        if (env[\"CXX_KIND\"] == \"g++\")\n+            warnings ~= [\n+\t            \"-Wno-logical-op\",\n+\t            \"-Wno-narrowing\",\n+\t            \"-Wno-unused-but-set-variable\",\n+\t            \"-Wno-uninitialized\",\n+\t            \"-Wno-class-memaccess\",\n+\t            \"-Wno-implicit-fallthrough\",\n+\t        ];\n+        else if (env[\"CXX_KIND\"] == \"clang++\")\n+            warnings ~= \"-Wno-logical-op-parentheses\";\n+    }\n+    else\n+    {\n+        warnings = [\"-Wno-deprecated\", \"-Wstrict-aliasing\", \"-Werror\"];\n+    }\n+\n+    auto targetCPU = \"X86\";\n+    auto cxxFlags = warnings;\n+    cxxFlags ~= [\n+        \"-fno-exceptions\", \"-fno-rtti\",\n+        \"-D__pascal=\", \"-DMARS=1\", \"-DTARGET_\" ~ os.toUpper ~ \"=1\",\n+        \"-DDM_TARGET_CPU_\" ~ targetCPU ~ \"=1\",\n+        env[\"MODEL_FLAG\"],\n+        env[\"PIC_FLAG\"],\n+    ];\n+    if (env[\"CXX_KIND\"] == \"g++\")\n+        cxxFlags ~= [\"-std=gnu++98\"];\n+    if (env[\"CXX_KIND\"] == \"clang++\")\n+        cxxFlags ~= [\"-xc++\"];\n+\n+    flags[\"CXXFLAGS\"] = cxxFlags;\n+\n+    // TODO: allow adding new flags from the environment\n+    string[] dflags;\n+    flags[\"DFLAGS\"] ~= [\"-version=MARS\", \"-w\", \"-de\", env[\"PIC_FLAG\"], env[\"MODEL_FLAG\"]];\n+    // TODO: add different ENABLE modes\n+\n+    // TODO: remove unused\n+    flags[\"DMD_FLAGS\"] = [\"-I\"~env[\"D\"], \"-I\"~env[\"ROOT\"], \"-Wuninitialized\"];\n+    flags[\"GLUE_FLAGS\"] = [\"-I\"~env[\"D\"], \"-I\"~env[\"ROOT\"], \"-I\"~env[\"TK\"], \"-I\"~env[\"C\"]];\n+    flags[\"BACK_FLAGS\"] = [\"-I\"~env[\"ROOT\"], \"-I\"~env[\"TK\"], \"-I\"~env[\"C\"], \"-I\"~env[\"G\"], \"-I\"~env[\"D\"], \"-DDMDV2=1\"];\n+    flags[\"ROOT_FLAGS\"] = [\"-I\"~env[\"ROOT\"]];\n+\n+    // TODO: add support for dObjc\n+    auto dObjc = false;\n+    version(OSX) version(X86_64)\n+        dObjc = true;\n+\n+    return env;\n+}\n+\n+////////////////////////////////////////////////////////////////////////////////\n+// D source files\n+////////////////////////////////////////////////////////////////////////////////\n+\n+auto sourceFiles()\n+{\n+    struct Sources\n+    {\n+        // TODO: remove unused file lists\n+        string[] frontend, lexer, lexerRoot, root, glue, dmd, backend;\n+        string[] backendHeaders, tkHeaders, backendC, tkC,\n+            backendObjects, opTabGenObjects;\n+        string[] glueSrc; // documentation only\n+    }\n+    string targetCH;\n+    string[] targetObjs;\n+    if (env[\"TARGET_CPU\"] == \"X86\")\n+    {\n+        targetCH = \"code_x86.h\";\n+        targetObjs = [\"cg87\", \"cgxmm\", \"cgsched\", \"cod1\", \"cod2\", \"cod3\", \"cod4\", \"ptrntab\"];\n+    }\n+    else if (env[\"TARGET_CPU\"] == \"stub\")\n+    {\n+        targetCH = \"code_stub.h\";\n+        targetObjs = [\"platform_stub\"];\n+    }\n+    else\n+    {\n+        assert(0, \"Unknown TARGET_CPU: \" ~ env[\"TARGET_CPU\"]);\n+    }\n+    Sources sources = {\n+        frontend: [\n+\t        \"arraytypes\",","path":"src/build.d","position":540,"original_position":540,"commit_id":"c4cf309ee7ced0b285e6c5bde757d71de08c3e21","original_commit_id":"c4cf309ee7ced0b285e6c5bde757d71de08c3e21","user":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars3.githubusercontent.com/u/4370550?v=4","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"body":"I tried to stay as close as possible to the Makefile, but in general there's no big reason not search for them though  there are a few dead files which are in the codebase, but never used.","created_at":"2018-05-25T17:12:15Z","updated_at":"2018-05-25T17:12:15Z","html_url":"https://github.com/dlang/dmd/pull/8293#discussion_r190956727","pull_request_url":"https://api.github.com/repos/dlang/dmd/pulls/8293","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/dlang/dmd/pulls/comments/190956727"},"html":{"href":"https://github.com/dlang/dmd/pull/8293#discussion_r190956727"},"pull_request":{"href":"https://api.github.com/repos/dlang/dmd/pulls/8293"}},"in_reply_to_id":190917541},"pull_request":{"url":"https://api.github.com/repos/dlang/dmd/pulls/8293","id":190570786,"html_url":"https://github.com/dlang/dmd/pull/8293","diff_url":"https://github.com/dlang/dmd/pull/8293.diff","patch_url":"https://github.com/dlang/dmd/pull/8293.patch","issue_url":"https://api.github.com/repos/dlang/dmd/issues/8293","number":8293,"state":"open","locked":false,"title":"[WIP] Initial pure D builder","user":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars3.githubusercontent.com/u/4370550?v=4","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"body":"(inspired by @JinShil's [recent dream on the NG](https://forum.dlang.org/post/dwnirthzzwtzmxypvizp@forum.dlang.org) about being able to build DMD easily on any platform)\r\n\r\nSimilarly to the `test/run.d`, this allows building DMD from source without depending on the Makefile.\r\nAt the moment it's a simplistic translation of more or the less the bare minimum of the `posix.mak` which is needed to build DMD, but the following is intended (not in this PR though):\r\n- support all OS (getting rid of the win32/win64.mak files is a major motivation)\r\n- allow this script to be used by dub (this should allow to build/expose full DMD via DUB)\r\n- target compatibility with the posix.mak Makefile (i.e. all targets that are supported in posix.mak should be supported here)\r\n\r\nI opened this PR to avoid duplicated efforts and give others already a sneak-peek at this.\r\nThis already compiles DMD on Linux and even supports partial and parallel compilation (almost as good the Make build).\r\n\r\nI kept the rule system as simplistic as possible to avoid adding a huge chunk of code that we would have to maintain + it's not really needed here anyhow.\r\nAlso the builder script got quite long, because instead of using one text blob for the source files, I used single lines for each file to avoid the merge conflicts that sometimes happen (though I have no strong feeling on this style).\r\n\r\nWhy such a naive approach and not cmake, ninja, reggae, ...?\r\n-----------------------------------------------------------------------------------\r\n\r\nThere has never been a consensus on which third-party build system should be used.\r\nUsing a pure D script avoids any further dependencies and after all, D should be powerful to handle any task!\r\nAlso the dependency flow is rather simplistic here. The backend and lexer need to be built before the main DMD built, but they can be built in parallel once the initial dependencies have been generated.\r\n\r\nBut the Makefile is working so nicely\r\n------------------------------------------------\r\n\r\nWell, I guess I'm one of the very few persons who understands the `posix.mak` (it looks more scary than it is), but I doubt many others do.\r\nAlso we there have been numerous complaints about the more or less unmaintained win32.mak and win64.mak files.\r\nFor now, like `run.d` this is an experiment and only intended to slowly replace the Makefiles once it has been thoroughly tested.\r\n\r\nBut isn't depending on D another dependency?\r\n--------------------------------------------------------------\r\n\r\nNope, D requires a host D compiler since 2015. The Makefile comes with an AUTO_BOOTSTRAP option to automatically download a D compiler. While I added support for this in `build.d` too (it makes sense when you want to lock the D compiler version to a specific one), it's only of limited help to someone on a fresh machine without a D compiler.\r\nImho we can expect a D compiler dev to have a working D installation, but if this AUTO_BOOTSTRAP option is convenient for some (I think the Jenkins CI uses it), we could opt to add a small Bash bootstrapping script around it (or keep this part of the Makefile).\r\n\r\nWhat's missing from this PR?\r\n---------------------------------------\r\n\r\n- [ ] more testing\r\n- [ ] triple-check that the same build flags are used as in posix.mak\r\n- [ ] improve the dependency checker to mirror posix.mak, e.g.\r\n  - add rebuild dependencies like e.g. a change to header files currently doesn't trigger a rebuild\r\n  - builder.d should be a default rebuild dependency to all files\r\n- [ ] check whether support a `void` commandFun makes sense (and catch exceptions coming from commandFun)\r\n\r\nWhat won't be part of this PR?\r\n----------------------------------------\r\n\r\nI don't plan to support Windows nor all targets of posix.mak in this initial PR.","created_at":"2018-05-25T12:17:55Z","updated_at":"2018-05-25T17:12:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f06f3eaaa674ade591cad1e709895bce2571f8d0","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":639748221,"url":"https://api.github.com/repos/dlang/dmd/labels/WIP","name":"WIP","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/dlang/dmd/pulls/8293/commits","review_comments_url":"https://api.github.com/repos/dlang/dmd/pulls/8293/comments","review_comment_url":"https://api.github.com/repos/dlang/dmd/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dlang/dmd/issues/8293/comments","statuses_url":"https://api.github.com/repos/dlang/dmd/statuses/c4cf309ee7ced0b285e6c5bde757d71de08c3e21","head":{"label":"wilzbach:build","ref":"build","sha":"c4cf309ee7ced0b285e6c5bde757d71de08c3e21","user":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars3.githubusercontent.com/u/4370550?v=4","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"repo":{"id":55034525,"name":"dmd","full_name":"wilzbach/dmd","owner":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars3.githubusercontent.com/u/4370550?v=4","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wilzbach/dmd","description":"dmd D Programming Language compiler","fork":true,"url":"https://api.github.com/repos/wilzbach/dmd","forks_url":"https://api.github.com/repos/wilzbach/dmd/forks","keys_url":"https://api.github.com/repos/wilzbach/dmd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wilzbach/dmd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wilzbach/dmd/teams","hooks_url":"https://api.github.com/repos/wilzbach/dmd/hooks","issue_events_url":"https://api.github.com/repos/wilzbach/dmd/issues/events{/number}","events_url":"https://api.github.com/repos/wilzbach/dmd/events","assignees_url":"https://api.github.com/repos/wilzbach/dmd/assignees{/user}","branches_url":"https://api.github.com/repos/wilzbach/dmd/branches{/branch}","tags_url":"https://api.github.com/repos/wilzbach/dmd/tags","blobs_url":"https://api.github.com/repos/wilzbach/dmd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wilzbach/dmd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wilzbach/dmd/git/refs{/sha}","trees_url":"https://api.github.com/repos/wilzbach/dmd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wilzbach/dmd/statuses/{sha}","languages_url":"https://api.github.com/repos/wilzbach/dmd/languages","stargazers_url":"https://api.github.com/repos/wilzbach/dmd/stargazers","contributors_url":"https://api.github.com/repos/wilzbach/dmd/contributors","subscribers_url":"https://api.github.com/repos/wilzbach/dmd/subscribers","subscription_url":"https://api.github.com/repos/wilzbach/dmd/subscription","commits_url":"https://api.github.com/repos/wilzbach/dmd/commits{/sha}","git_commits_url":"https://api.github.com/repos/wilzbach/dmd/git/commits{/sha}","comments_url":"https://api.github.com/repos/wilzbach/dmd/comments{/number}","issue_comment_url":"https://api.github.com/repos/wilzbach/dmd/issues/comments{/number}","contents_url":"https://api.github.com/repos/wilzbach/dmd/contents/{+path}","compare_url":"https://api.github.com/repos/wilzbach/dmd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wilzbach/dmd/merges","archive_url":"https://api.github.com/repos/wilzbach/dmd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wilzbach/dmd/downloads","issues_url":"https://api.github.com/repos/wilzbach/dmd/issues{/number}","pulls_url":"https://api.github.com/repos/wilzbach/dmd/pulls{/number}","milestones_url":"https://api.github.com/repos/wilzbach/dmd/milestones{/number}","notifications_url":"https://api.github.com/repos/wilzbach/dmd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wilzbach/dmd/labels{/name}","releases_url":"https://api.github.com/repos/wilzbach/dmd/releases{/id}","deployments_url":"https://api.github.com/repos/wilzbach/dmd/deployments","created_at":"2016-03-30T05:15:54Z","updated_at":"2018-05-25T06:10:44Z","pushed_at":"2018-05-25T12:50:05Z","git_url":"git://github.com/wilzbach/dmd.git","ssh_url":"git@github.com:wilzbach/dmd.git","clone_url":"https://github.com/wilzbach/dmd.git","svn_url":"https://github.com/wilzbach/dmd","homepage":"dlang.org","size":88191,"stargazers_count":1,"watchers_count":1,"language":"D","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"bsl-1.0","name":"Boost Software License 1.0","spdx_id":"BSL-1.0","url":"https://api.github.com/licenses/bsl-1.0"},"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"dlang:master","ref":"master","sha":"9e85900b11d316fa73dfeaf3a334fcf8ee264a6d","user":{"login":"dlang","id":565913,"avatar_url":"https://avatars3.githubusercontent.com/u/565913?v=4","gravatar_id":"","url":"https://api.github.com/users/dlang","html_url":"https://github.com/dlang","followers_url":"https://api.github.com/users/dlang/followers","following_url":"https://api.github.com/users/dlang/following{/other_user}","gists_url":"https://api.github.com/users/dlang/gists{/gist_id}","starred_url":"https://api.github.com/users/dlang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dlang/subscriptions","organizations_url":"https://api.github.com/users/dlang/orgs","repos_url":"https://api.github.com/users/dlang/repos","events_url":"https://api.github.com/users/dlang/events{/privacy}","received_events_url":"https://api.github.com/users/dlang/received_events","type":"Organization","site_admin":false},"repo":{"id":1257070,"name":"dmd","full_name":"dlang/dmd","owner":{"login":"dlang","id":565913,"avatar_url":"https://avatars3.githubusercontent.com/u/565913?v=4","gravatar_id":"","url":"https://api.github.com/users/dlang","html_url":"https://github.com/dlang","followers_url":"https://api.github.com/users/dlang/followers","following_url":"https://api.github.com/users/dlang/following{/other_user}","gists_url":"https://api.github.com/users/dlang/gists{/gist_id}","starred_url":"https://api.github.com/users/dlang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dlang/subscriptions","organizations_url":"https://api.github.com/users/dlang/orgs","repos_url":"https://api.github.com/users/dlang/repos","events_url":"https://api.github.com/users/dlang/events{/privacy}","received_events_url":"https://api.github.com/users/dlang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dlang/dmd","description":"dmd D Programming Language compiler","fork":false,"url":"https://api.github.com/repos/dlang/dmd","forks_url":"https://api.github.com/repos/dlang/dmd/forks","keys_url":"https://api.github.com/repos/dlang/dmd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dlang/dmd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dlang/dmd/teams","hooks_url":"https://api.github.com/repos/dlang/dmd/hooks","issue_events_url":"https://api.github.com/repos/dlang/dmd/issues/events{/number}","events_url":"https://api.github.com/repos/dlang/dmd/events","assignees_url":"https://api.github.com/repos/dlang/dmd/assignees{/user}","branches_url":"https://api.github.com/repos/dlang/dmd/branches{/branch}","tags_url":"https://api.github.com/repos/dlang/dmd/tags","blobs_url":"https://api.github.com/repos/dlang/dmd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dlang/dmd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dlang/dmd/git/refs{/sha}","trees_url":"https://api.github.com/repos/dlang/dmd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dlang/dmd/statuses/{sha}","languages_url":"https://api.github.com/repos/dlang/dmd/languages","stargazers_url":"https://api.github.com/repos/dlang/dmd/stargazers","contributors_url":"https://api.github.com/repos/dlang/dmd/contributors","subscribers_url":"https://api.github.com/repos/dlang/dmd/subscribers","subscription_url":"https://api.github.com/repos/dlang/dmd/subscription","commits_url":"https://api.github.com/repos/dlang/dmd/commits{/sha}","git_commits_url":"https://api.github.com/repos/dlang/dmd/git/commits{/sha}","comments_url":"https://api.github.com/repos/dlang/dmd/comments{/number}","issue_comment_url":"https://api.github.com/repos/dlang/dmd/issues/comments{/number}","contents_url":"https://api.github.com/repos/dlang/dmd/contents/{+path}","compare_url":"https://api.github.com/repos/dlang/dmd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dlang/dmd/merges","archive_url":"https://api.github.com/repos/dlang/dmd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dlang/dmd/downloads","issues_url":"https://api.github.com/repos/dlang/dmd/issues{/number}","pulls_url":"https://api.github.com/repos/dlang/dmd/pulls{/number}","milestones_url":"https://api.github.com/repos/dlang/dmd/milestones{/number}","notifications_url":"https://api.github.com/repos/dlang/dmd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dlang/dmd/labels{/name}","releases_url":"https://api.github.com/repos/dlang/dmd/releases{/id}","deployments_url":"https://api.github.com/repos/dlang/dmd/deployments","created_at":"2011-01-15T06:53:53Z","updated_at":"2018-05-25T11:35:01Z","pushed_at":"2018-05-25T12:50:06Z","git_url":"git://github.com/dlang/dmd.git","ssh_url":"git@github.com:dlang/dmd.git","clone_url":"https://github.com/dlang/dmd.git","svn_url":"https://github.com/dlang/dmd","homepage":"dlang.org","size":89257,"stargazers_count":1795,"watchers_count":1795,"language":"D","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":450,"mirror_url":null,"archived":false,"open_issues_count":142,"license":{"key":"bsl-1.0","name":"Boost Software License 1.0","spdx_id":"BSL-1.0","url":"https://api.github.com/licenses/bsl-1.0"},"forks":450,"open_issues":142,"watchers":1795,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dlang/dmd/pulls/8293"},"html":{"href":"https://github.com/dlang/dmd/pull/8293"},"issue":{"href":"https://api.github.com/repos/dlang/dmd/issues/8293"},"comments":{"href":"https://api.github.com/repos/dlang/dmd/issues/8293/comments"},"review_comments":{"href":"https://api.github.com/repos/dlang/dmd/pulls/8293/comments"},"review_comment":{"href":"https://api.github.com/repos/dlang/dmd/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dlang/dmd/pulls/8293/commits"},"statuses":{"href":"https://api.github.com/repos/dlang/dmd/statuses/c4cf309ee7ced0b285e6c5bde757d71de08c3e21"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"wilzbach"}}