diff --git a/rdmd.d b/rdmd.d index bd82637..ee6f27b 100644 --- a/rdmd.d +++ b/rdmd.d @@ -115,14 +115,6 @@ int main(string[] args) assert(programPos > 0); auto argsBeforeProgram = args[0 .. programPos]; - /* Catch -main and handle it like --main. This needs to be done, because - rdmd compiles the root file independently from the dependencies, but -main - must be present in only one of the calls to dmd. */ - foreach (ref arg; argsBeforeProgram) - { - if (arg == "-main") arg = "--main"; - } - bool bailout; // bailout set by functions called in getopt if // program should exit string[] loop; // set by --loop @@ -244,8 +236,7 @@ int main(string[] args) } // Fetch dependencies - const myDeps = compileRootAndGetDeps(root, workDir, objDir, compilerFlags, - addStubMain); + const myDeps = getDependencies(root, workDir, objDir, compilerFlags); // --makedepend mode. Just print dependencies and exit. if (makeDepend) @@ -303,7 +294,7 @@ int main(string[] args) if (chain(root.only, myDeps.byKey).anyNewerThan(lastBuildTime)) { immutable result = rebuild(root, exe, workDir, objDir, - myDeps, compilerFlags); + myDeps, compilerFlags, addStubMain); if (result) return result; @@ -448,13 +439,13 @@ private void unlockWorkPath() } } -// Rebuild the executable fullExe from root and myDeps, +// Rebuild the executable fullExe starting from modules in myDeps // passing the compiler flags compilerFlags. Generates one large -// object file for the dependencies. +// object file. private int rebuild(string root, string fullExe, string workDir, string objDir, in string[string] myDeps, - string[] compilerFlags) + string[] compilerFlags, bool addStubMain) { version (Windows) fullExe = fullExe.defaultExtension(".exe"); @@ -481,59 +472,46 @@ private int rebuild(string root, string fullExe, } } - immutable fullExeTemp = fullExe ~ ".tmp"; - immutable rootObj = buildPath(objDir, root.baseName(".d") ~ objExt); - immutable depsObj = buildPath(objDir, - root.baseName(".d") ~ ".deps" ~ objExt); + auto fullExeTemp = fullExe ~ ".tmp"; - assert(dryRun || std.file.exists(rootObj), - "should have been created by compileRootAndGetDeps"); - - int result = 0; - string[] objs = [ rootObj ]; - - // compile dependencies - if (myDeps.byValue.any!(o => o !is null)) - // if there is any source dependency at all + string[] buildTodo() { - auto todo = compilerFlags ~ [ - "-c", - "-of" ~ depsObj, - "-I" ~ dirName(root), - ]; + auto todo = compilerFlags + ~ [ "-of"~fullExeTemp ] + ~ [ "-od"~objDir ] + ~ [ "-I"~dirName(root) ] + ~ [ root ]; foreach (k, objectFile; myDeps) { if(objectFile !is null) todo ~= [ k ]; } - - // Different shells and OS functions have different limits, - // but 1024 seems to be the smallest maximum outside of MS-DOS. - enum maxLength = 1024; - auto commandLength = escapeShellCommand(todo).length; - if (commandLength + compiler.length >= maxLength) + // Need to add void main(){}? + if (addStubMain) { - auto rspName = buildPath(workDir, "rdmd.rsp"); - - // DMD uses Windows-style command-line parsing in response files - // regardless of the operating system it's running on. - std.file.write(rspName, - array(map!escapeWindowsArgument(todo)).join(" ")); - - todo = [ "@" ~ rspName ]; + auto stubMain = buildPath(myOwnTmpDir, "stubmain.d"); + std.file.write(stubMain, "void main(){}"); + todo ~= [ stubMain ]; } - - result = run([ compiler ] ~ todo); - objs ~= depsObj; + return todo; } + auto todo = buildTodo(); - // link - if (!result) + // Different shells and OS functions have different limits, + // but 1024 seems to be the smallest maximum outside of MS-DOS. + enum maxLength = 1024; + auto commandLength = escapeShellCommand(todo).length; + if (commandLength + compiler.length >= maxLength) { - string[] cmd = [ compiler ] ~ compilerFlags ~ - [ "-of" ~ fullExeTemp, "-od" ~ objDir ] ~ objs; - result = run(cmd); + auto rspName = buildPath(workDir, "rdmd.rsp"); + + // DMD uses Windows-style command-line parsing in response files + // regardless of the operating system it's running on. + std.file.write(rspName, array(map!escapeWindowsArgument(todo)).join(" ")); + + todo = [ "@"~rspName ]; } + immutable result = run([ compiler ] ~ todo); if (result) { // build failed @@ -595,13 +573,13 @@ private int exec(string[] args) return run(args, null, true); } -// Given module rootModule, compiles it to rdmd.root.o and returns a mapping of -// all dependees .d source filenames to their corresponding .o files sitting in +// Given module rootModule, returns a mapping of all dependees .d +// source filenames to their corresponding .o files sitting in // directory workDir. The mapping is obtained by running dmd -v against // rootModule. -private string[string] compileRootAndGetDeps(string rootModule, string workDir, - string objDir, string[] compilerFlags, bool addStubMain) +private string[string] getDependencies(string rootModule, string workDir, + string objDir, string[] compilerFlags) { immutable depsFilename = buildPath(workDir, "rdmd.deps"); @@ -718,23 +696,10 @@ private string[string] compileRootAndGetDeps(string rootModule, string workDir, immutable rootDir = dirName(rootModule); // Collect dependencies - auto depsGetter = [ compiler ] ~ compilerFlags ~ [ - "-v", - "-c", - "-of" ~ buildPath(objDir, rootModule.baseName(".d") ~ objExt), - rootModule, - "-I" ~ rootDir - ]; - - // Need to add void main(){}? - if (addStubMain) - { - /* TODO: Can be simplified to `depsGetter ~= "-main";` when issue 16440 - is fixed. */ - auto stubMain = buildPath(myOwnTmpDir, "stubmain.d"); - std.file.write(stubMain, "void main(){}"); - depsGetter ~= [ stubMain ]; - } + auto depsGetter = + // "cd "~shellQuote(rootDir)~" && " + [ compiler ] ~ compilerFlags ~ + ["-v", "-o-", rootModule, "-I"~rootDir]; scope(failure) {