-
-
Notifications
You must be signed in to change notification settings - Fork 147
rdmd: compile the root module in the same step as getting the dependencies #194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
10ca158
4ab9444
821d038
0e44ee7
4da871d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,6 +114,14 @@ 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 | ||
|
|
@@ -234,7 +242,8 @@ int main(string[] args) | |
| } | ||
|
|
||
| // Fetch dependencies | ||
| const myDeps = getDependencies(root, workDir, objDir, compilerFlags); | ||
| const myDeps = compileRootAndGetDeps(root, workDir, objDir, compilerFlags, | ||
| addStubMain); | ||
|
|
||
| // --makedepend mode. Just print dependencies and exit. | ||
| if (makeDepend) | ||
|
|
@@ -292,7 +301,7 @@ int main(string[] args) | |
| if (chain(root.only, myDeps.byKey).array.anyNewerThan(lastBuildTime)) | ||
| { | ||
| immutable result = rebuild(root, exe, workDir, objDir, | ||
| myDeps, compilerFlags, addStubMain); | ||
| myDeps, compilerFlags); | ||
| if (result) | ||
| return result; | ||
|
|
||
|
|
@@ -437,13 +446,13 @@ private void unlockWorkPath() | |
| } | ||
| } | ||
|
|
||
| // Rebuild the executable fullExe starting from modules in myDeps | ||
| // Rebuild the executable fullExe from root and myDeps, | ||
| // passing the compiler flags compilerFlags. Generates one large | ||
| // object file. | ||
| // object file for the dependencies. | ||
|
|
||
| private int rebuild(string root, string fullExe, | ||
| string workDir, string objDir, in string[string] myDeps, | ||
| string[] compilerFlags, bool addStubMain) | ||
| string[] compilerFlags) | ||
| { | ||
| version (Windows) | ||
| fullExe = fullExe.defaultExtension(".exe"); | ||
|
|
@@ -470,46 +479,59 @@ private int rebuild(string root, string fullExe, | |
| } | ||
| } | ||
|
|
||
| auto fullExeTemp = fullExe ~ ".tmp"; | ||
| immutable fullExeTemp = fullExe ~ ".tmp"; | ||
| immutable rootObj = buildPath(objDir, root.baseName(".d") ~ objExt); | ||
| immutable depsObj = buildPath(objDir, | ||
| root.baseName(".d") ~ ".deps" ~ objExt); | ||
|
|
||
| string[] buildTodo() | ||
| 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 | ||
| { | ||
| auto todo = compilerFlags | ||
| ~ [ "-of"~fullExeTemp ] | ||
| ~ [ "-od"~objDir ] | ||
| ~ [ "-I"~dirName(root) ] | ||
| ~ [ root ]; | ||
| auto todo = compilerFlags ~ [ | ||
| "-c", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah that's the spirit |
||
| "-of" ~ depsObj, | ||
| "-I" ~ dirName(root), | ||
| ]; | ||
| foreach (k, objectFile; myDeps) { | ||
| if(objectFile !is null) | ||
| todo ~= [ k ]; | ||
| } | ||
| // Need to add void main(){}? | ||
| if (addStubMain) | ||
|
|
||
| // 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) | ||
| { | ||
| auto stubMain = buildPath(myOwnTmpDir, "stubmain.d"); | ||
| std.file.write(stubMain, "void main(){}"); | ||
| todo ~= [ stubMain ]; | ||
| 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(" ")); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmmm, this reminds me we should have a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use todo.map!escapeWindowsArgument.joiner(" ").each!(line => std.file.append(rspName, line)));Pseudocoding here. Edit: Update example
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The previous page is sending you to an invalid url (http:///home/vladimir/work/aconfmgr/README.html).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And later: https://github.com/home/vladimir/work/aconfmgr/README.html is also not valid
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, link fixed
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then let's use it!!! |
||
|
|
||
| todo = [ "@" ~ rspName ]; | ||
| } | ||
| return todo; | ||
|
|
||
| result = run([ compiler ] ~ todo); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the base version (see a couple of lines below) removes the temporary build files if an error occurs edit: It might make also sense to remove/clean
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean by "base version". |
||
| objs ~= depsObj; | ||
| } | ||
| auto todo = buildTodo(); | ||
|
|
||
| // 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) | ||
| // link | ||
| if (!result) | ||
| { | ||
| 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 ]; | ||
| string[] cmd = [ compiler ] ~ compilerFlags ~ | ||
| [ "-of" ~ fullExeTemp, "-od" ~ objDir ] ~ objs; | ||
| result = run(cmd); | ||
| } | ||
|
|
||
| immutable result = run([ compiler ] ~ todo); | ||
| if (result) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can just you
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No, the block above may change the value of |
||
| { | ||
| // build failed | ||
|
|
@@ -571,13 +593,13 @@ private int exec(string[] args) | |
| return run(args, null, true); | ||
| } | ||
|
|
||
| // Given module rootModule, returns a mapping of all dependees .d | ||
| // source filenames to their corresponding .o files sitting in | ||
| // 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 | ||
| // directory workDir. The mapping is obtained by running dmd -v against | ||
| // rootModule. | ||
|
|
||
| private string[string] getDependencies(string rootModule, string workDir, | ||
| string objDir, string[] compilerFlags) | ||
| private string[string] compileRootAndGetDeps(string rootModule, string workDir, | ||
| string objDir, string[] compilerFlags, bool addStubMain) | ||
| { | ||
| immutable depsFilename = buildPath(workDir, "rdmd.deps"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit unrelated, but this could also be the cause of the slight runtime difference. At line 640 we can use a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -> #196 |
||
|
|
||
|
|
@@ -694,10 +716,23 @@ private string[string] getDependencies(string rootModule, string workDir, | |
| immutable rootDir = dirName(rootModule); | ||
|
|
||
| // Collect dependencies | ||
| auto depsGetter = | ||
| // "cd "~shellQuote(rootDir)~" && " | ||
| [ compiler ] ~ compilerFlags ~ | ||
| ["-v", "-o-", rootModule, "-I"~rootDir]; | ||
| 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 ]; | ||
| } | ||
|
|
||
| scope(failure) | ||
| { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like that trick 👍 (I filtered for it for the additional source compilation)