-
-
Notifications
You must be signed in to change notification settings - Fork 608
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
Fix issue 16746 - Please output Makefile-style depfiles for ninja and make #6961
Conversation
|
Thanks for your pull request and interest in making D better, @KubaSz! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#6961" |
|
Seems like |
src/ddmd/expression.d
Outdated
| @@ -8413,6 +8413,22 @@ extern (C++) final class ImportExp : UnaExp | |||
| ob.writestring(")"); | |||
| ob.writenl(); | |||
| } | |||
| if (global.params.makeDeps !is null) | |||
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.
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've added an import expression to the test file, this should cover these lines.
FYI, gdc compiled test uses GC allocation, not bump-the-pointer. So this means that there is a genuine logic bug in the implementation. |
src/ddmd/mars.d
Outdated
| depBuffer.writeByte(' '); | ||
| } | ||
| auto depf = File(outpath); | ||
| depf.setbuffer(cast(void*)depBuffer.data, depBuffer.offset); |
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.
This is normally why there's a double free. File is freeing the buffer owned by OutBuffer. You need to tell depf._ref = 1.
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.
Fixed. This is my first encounter with dmd's code, so sorry that I didn't notice the _ref field in File.
src/ddmd/globals.h
Outdated
| @@ -199,6 +203,7 @@ struct Global | |||
| const char *hdr_ext; // for D 'header' import files | |||
| const char *json_ext; // for JSON files | |||
| const char *map_ext; // for .map files | |||
| const char *makedep_ext; // for make-style dependency files | |||
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.
All _ext fields should just go. There is no need for them.
src/ddmd/mars.d
Outdated
| if(global.params.makeDeps !is null) | ||
| error(Loc(), "-M/-MD can only be provided once!"); | ||
| global.params.makeDeps = new Strings(); | ||
| break; |
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.
-MD writes deps to a file implicitly.
src/ddmd/globals.d
Outdated
| @@ -172,6 +172,10 @@ struct Param | |||
| const(char)* moduleDepsFile; // filename for deps output | |||
| OutBuffer* moduleDeps; // contents to be written to deps file | |||
|
|
|||
| const(char)* makeDepsFile; // filename for make-style dependencies output | |||
| const(char)* makeDepsTarget; // the generated make target name | |||
| Array!(const(char)*)* makeDeps; // array of paths that the compiled module(s) depend on | |||
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 wonder if these are strictly needed, or we should start requesting that new driver-only fields be added privately in mars.d so as to not affect other backends.
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.
The makeDeps field could be private, but the File and Target can be useful for other drivers to input their commandline options to dmdfe. I've basically followed what changes the -deps option that was already built into dmd introduced, so that's why I added these fields here.
9303ba1
to
5a5ba85
Compare
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.
Thanks, interesting PR :).
While dmd's command line is weird, it doesn't become better by adopting switches with different conventions. Please make your additions consistent with existing switches.
Furthermore this apparently cannot generate multiple output deps files, we need sth. that also works with multiple source and output files, while also working with parallel compilation (can't write everything into one file).
src/ddmd/mars.d
Outdated
| @@ -147,6 +147,10 @@ Where: | |||
| -J=<directory> look for string imports also in directory | |||
| -L=<linkerflag> pass linkerflag to link | |||
| -lib generate library rather than object files | |||
| -M generate make-style dependency file, generates no other output files | |||
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.
Dmd already has -o- to turn off object file generation.
src/ddmd/mars.d
Outdated
| -M generate make-style dependency file, generates no other output files | ||
| -MD generate make-style dependency file | ||
| -MF=<filename> specifies the dependency output file | ||
| -MT=<name> specifies the name of the target rule in the dependencies file |
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.
This differs quite a lot from dmd's other options, look at -H, -Hd, -Hf, -op, -D.
In particular you want to be able to specify an output folder with -Md and obey -op, and use -Mf instead of -MF.
Please make sure to not mixup dependency and deps file in the explanation.
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.
Not sure how -MT could work for multiple object files in one compilation (not a typical make use-case though possible).
src/ddmd/mars.d
Outdated
| const(char)* mtarget = global.params.makeDepsTarget; | ||
| if (!outpath) | ||
| { | ||
| outpath = FileName.forceExt((*global.params.objfiles)[0], "dep"); |
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.
You're sure there are object files when we run with -o-?
Better generate your own paths.
src/ddmd/mars.d
Outdated
| global.params.makeDeps = new Strings(); | ||
| break; | ||
| case 'F': | ||
| if(p[3] != '=' || p[4] == '\0') |
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.
We do not use = for any of the path arguments, just -Hffile.di for example.
| grep 'makedeps.sh' ${RESULTS_DIR}/compilable/makedeps2.dep || exit 1 | ||
| grep 'makedeps_a.d' ${RESULTS_DIR}/compilable/makedeps2.dep || exit 1 | ||
| grep 'object.d' ${RESULTS_DIR}/compilable/makedeps2.dep || exit 1 | ||
| grep '__entrypoint' ${RESULTS_DIR}/compilable/makedeps2.dep && exit 1 |
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.
You might want to include colon (:) in your grep searches.
5a5ba85
to
b34bb82
Compare
|
Sorry for the long delay in fixing my PR, I had a surgery and needed time to recover. I've pushed the fixes now:
|
fdb975b
to
62a9086
Compare
62a9086
to
9f597ca
Compare
|
I have rebased the PR against the current master branch. |
|
Any news on this? It's kind of important to make splitbuilds work out of the box in Automake, Meson & Co. |
|
Would it be possible for you to re-review this PR? @MartinNowak @ibuclaw |
9f597ca
to
35581f5
Compare
|
Rebased against master. |
src/dmd/globals.d
Outdated
| bool doMakeDeps; // generate make-style dependencies file | ||
| const(char)* makeDepsFile; // filename for make-style dependencies output | ||
| const(char)* makeDepsDir; // directory for make-style dependencies output | ||
| const(char)* makeDepsTarget; // the make target name |
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.
All new public symbols should have Ddoc comments.
src/dmd/globals.d
Outdated
| bool doMakeDeps; // generate make-style dependencies file | ||
| const(char)* makeDepsFile; // filename for make-style dependencies output | ||
| const(char)* makeDepsDir; // directory for make-style dependencies output | ||
| const(char)* makeDepsTarget; // the make target name |
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.
Can these const(char)* fields be made into D strings, i.e. const(char)[]? On the C++ side an ABI compatible struct can be used.
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.
As much as I'd like this to happen, I don't think it's fair to ask a contributor to break the current status quo.
Such a change should be done on its own.
| @@ -381,6 +381,7 @@ extern (C++) final class Module : Package | |||
| Dsymbols* decldefs; // top level declarations for this Module | |||
|
|
|||
| Modules aimports; // all imported modules | |||
| Strings astringImports; // all string-imported files | |||
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.
Perhaps this can be an array of const(char)[] and an ABI compatible struct on the C++ side.
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.
Same comment about the status quo. I'd like to replace the Array aliases as much as the next guy, but I don't think we should put that kind of weight on this PR.
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 also think that this is not really in the scope of this PR, and I think a "standard" way to do it (perhaps with predefined structs for most common array typs) should be defined first and a refactor PR could be done with that in place.
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.
Then it will never happen and at the same time we’re adding more code that needs to change later 😞
src/dmd/mars.d
Outdated
| { | ||
| auto mpath = m.srcfile.toString(); | ||
| // Skip modules already in the table, add self | ||
| if (moduleImportedPaths.insert(mpath.ptr, mpath.length, null) is null) |
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.
Please add an overload to insert that takes const(char)[] instead of a pointer and length.
src/dmd/root/filename.d
Outdated
| @@ -765,6 +765,11 @@ nothrow: | |||
| { | |||
| return str; | |||
| } | |||
|
|
|||
| extern (D) const(char)[] toString() const pure | |||
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.
Can be made nothrow.
src/dmd/root/file.d
Outdated
| extern (D) const(char)[] toString() pure const | ||
| { | ||
| return name.toString(); | ||
| } |
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.
Can be made nothrow.
src/dmd/root/file.d
Outdated
| @@ -66,11 +66,16 @@ nothrow: | |||
| } | |||
| } | |||
|
|
|||
| extern (C++) const(char)* toChars() pure | |||
| extern (C++) const(char)* toChars() pure const | |||
| { | |||
| return name.toChars(); | |||
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.
Can be made nothrow, I assume.
src/dmd/mars.d
Outdated
| { | ||
| // no actual file is created, uses just the path | ||
| File* objfile = m.setOutfile(global.params.objname, global.params.objdir, m.arg, global.obj_ext); | ||
| escapePathSpaces(&mdout, objfile.toChars()); |
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.
Please used the newly added toString method instead.
src/dmd/mars.d
Outdated
| @@ -869,20 +869,109 @@ private int tryMain(size_t argc, const(char)** argv) | |||
|
|
|||
| // inlineScan incrementally run semantic3 of each expanded functions. | |||
| // So deps file generation should be moved after the inlinig stage. | |||
| if (global.params.moduleDeps) | |||
| // inlineScan incrementally run semantic3 of each expanded functions. | |||
| // So deps file generation should be moved after the inlinig stage. | |||
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.
Duplicated comment
src/dmd/mars.d
Outdated
| { | ||
| const(char)* mpath = m.srcfile.toChars(); | ||
| // Skip modules already in the table, add self | ||
| if(moduleImportedPaths.insert(mpath, strlen(mpath), null) is null) |
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.
if (
src/dmd/utils.d
Outdated
| * buf = Buffer to write the escaped path to | ||
| * fname = Path to escape | ||
| */ | ||
| void escapePathSpaces(OutBuffer* buf, const(char)* fname) |
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.
Any chance to move this to filename ?
src/dmd/globals.d
Outdated
| bool doMakeDeps; // generate make-style dependencies file | ||
| const(char)* makeDepsFile; // filename for make-style dependencies output | ||
| const(char)* makeDepsDir; // directory for make-style dependencies output | ||
| const(char)* makeDepsTarget; // the make target name |
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.
As much as I'd like this to happen, I don't think it's fair to ask a contributor to break the current status quo.
Such a change should be done on its own.
| @@ -381,6 +381,7 @@ extern (C++) final class Module : Package | |||
| Dsymbols* decldefs; // top level declarations for this Module | |||
|
|
|||
| Modules aimports; // all imported modules | |||
| Strings astringImports; // all string-imported files | |||
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.
Same comment about the status quo. I'd like to replace the Array aliases as much as the next guy, but I don't think we should put that kind of weight on this PR.
|
This PR would also close the issue I filed. On the whole "why makefile dependencies?" front, I'd like to add this: this is required for ninja to work. Reggae only supports ninja by wrapping dmd and offering the necessary functionality. |
|
I thought I'd added a comment here that dmd has the |
|
I think it is too late now to change the behavior of the -deps switch, quite a few tools seem to rely on its format :( |
src/dmd/root/filename.d
Outdated
|
|
||
| extern (D) const(char)[] toString() const pure nothrow | ||
| { | ||
| return str[0 .. strlen(str)]; |
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.
str can be null
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.
see #8550, which should be a separate PR anyway.
|
So if this is merged, we'll have |
|
The right design is to output the information in a simple format and leave it to tooling to translate to others. Sadly, one little uninspired idea after another, we're here. |
|
And so we arrive at the nightmarish blizzard of switches I so wanted to avoid :-( |
|
Well, at some well-announced point in the future, you could in theory clean up the compiler flags and adjust them to something that you like. |
| // So deps file generation should be moved after the inlinig stage. | ||
| if (global.params.moduleDeps) | ||
| // So deps file generation should be moved after the inlining stage. | ||
| if (global.params.moduleDeps || global.params.doMakeDeps) |
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.
You probably don't want to reuse -deps functionality as it is no longer useful for make. Analysing code via semantic3OnDependencies also reports local imports that are not used when compiling the code without the -deps option. It can also slow down compilation considerably. See discussion in #6748.
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.
That was insightful, thank you. I've moved the semantic3OnDependencies call to be done only for the old -deps switch.
995fa60
to
001608b
Compare
001608b
to
7556d76
Compare
|
What happened to this PR? Can we get this rebased and back to track again? I really wanted to see this go through to improve the building process with ninja. |
|
It's not in a particularly good shape, adds lots of extra switches with partly redundant functionality (#6961 (comment)). |
|
The basic idea to generate makefile compatible output is good though, maybe just add a |
|
Another implementation, #12011, has been merged into master. |
|
Excellent, many thanks to everyone involved! This helps a lot for project with mixed languages and D with buildsystems using ninja and make :-) |

This adds
-M,-Mffile,-Mddirectory,-Mttargetcommandline options akin to C(++) compilers, and implements generation of make depfiles which can be used by buildsystems such as Ninja, Make or Meson.Link to issue: https://issues.dlang.org/show_bug.cgi?id=16746