September 22, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #19 from Steven Schveighoffer <schveiguy@yahoo.com> ---
(In reply to Steven Schveighoffer from comment #17)
> -c builds .o

Of course, this is wrong :) -c suppresses link.

--
September 22, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #20 from Ketmar Dark <ketmar@ketmar.no-ip.org> ---
(In reply to Steven Schveighoffer from comment #17)
so it's not a "side effect", .di file has to be explicitly asked.

> > and why build tool doesn't know about '.di'?
> I mean, the build tool knows it only as a dependency, not as a target. It has no idea how to build the .di file. The .di file is built as a side effect of building the .o file.
no, it's not a "side effect". and build tool doesn't know how to build .o from .d too. one must provide the rule which builds .o from .d. one must provide the rule which builds .di from .d. simple and easy.

> But as I said, you would need to ensure the project that builds the .di file cannot depend on the .di file, because it doesn't know how to build them, it just does so as a side effect.
if project uses generated files that eventually needs regeneration and it's build system doesn't know about that files, this project's build scripts are foobared. that is exactly the mess that will lead to complete disaster sooner or later.

--
September 22, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #21 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to Steven Schveighoffer from comment #18)
> I would add a stipulation that if the purpose of the compiler invocation is ONLY to build the .di file, then the compiler should rewrite it. So dmd -c -o- -H should still touch the .di file even if it's identical to the existing one.
> 
> Otherwise, this disfavors a build system where the .di is built as a separate step (and causes a continual "rebuild" of a .di file every time the build is called).

Wouldn't that be easily achieved by "rm -rf generated/*.di" at the beginning of that separate step?

--
September 22, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #22 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to Ketmar Dark from comment #20)
> (In reply to Steven Schveighoffer from comment #17)
> so it's not a "side effect", .di file has to be explicitly asked.
> 
> > > and why build tool doesn't know about '.di'?
> > I mean, the build tool knows it only as a dependency, not as a target. It has no idea how to build the .di file. The .di file is built as a side effect of building the .o file.
> no, it's not a "side effect". and build tool doesn't know how to build .o from .d too. one must provide the rule which builds .o from .d. one must provide the rule which builds .di from .d. simple and easy.

Actually it's not that simple and easy. One invocation of the compiler produces both .o and .di files. A common mistake made with rules that generate multiple files is to do https://www.gnu.org/software/make/manual/html_node/Multiple-Targets.html, which is wrong. There are a few better solutions, neither of which trivial. See e g. http://www.cmcrossroads.com/article/rules-multiple-outputs-gnu-make.

--
September 23, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #23 from Steven Schveighoffer <schveiguy@yahoo.com> ---
(In reply to Andrei Alexandrescu from comment #21)

> 
> Wouldn't that be easily achieved by "rm -rf generated/*.di" at the beginning of that separate step?

Sure, but "easily achieved" is not "easily explained" or "easily justified"

It is very counterintuitive to have a tool that is resolving dependencies to require an extra step to update the date of file. Especially one that does not act that way for any other generated files.

I will note, this will break a LOT of existing projects. Including druntime.

(In reply to Ketmar Dark from comment #20)
> (In reply to Steven Schveighoffer from comment #17)
> so it's not a "side effect", .di file has to be explicitly asked.

Perhaps you are getting caught up in terminology. It's not a target the build system is trying to generate. Whatever term you want to use for that, use that.

> no, it's not a "side effect". and build tool doesn't know how to build .o from .d too. one must provide the rule which builds .o from .d. one must provide the rule which builds .di from .d. simple and easy.

It knows how to build the .o because we tell it. E.g.:

%.o : %.d
      dmd -c -H %.d

(please note, not a makefile expert, so the above may not be valid make syntax, but I hope you get the idea)

But my point is, you don't tell it about building the .di file because the build of the .di file is implicit in the rule for the .o.

> 
> > But as I said, you would need to ensure the project that builds the .di file cannot depend on the .di file, because it doesn't know how to build them, it just does so as a side effect.
> if project uses generated files that eventually needs regeneration and it's build system doesn't know about that files, this project's build scripts are foobared. that is exactly the mess that will lead to complete disaster sooner or later.

But your project doesn't know how to build /usr/include/stdio.h, so why should your project care about how some other project's .di file is made?

It requires some manual ordering. For instance, you can't just treat all project files as individuals, you have to build all files for project a first if project b depends on a.

One thing that would make this scheme fail is if one removes the .di file and expects it to regenerate. But I think this is a caveat of an uncommon build system, you just have to live with that.

I will say, I think the enhancement is unusual and counterintuitive. It may be best to enable this mechanism with a special flag. Maybe like -H+

--
September 23, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

Ketmar Dark <ketmar@ketmar.no-ip.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ketmar@ketmar.no-ip.org

--- Comment #24 from Ketmar Dark <ketmar@ketmar.no-ip.org> ---
(In reply to Steven Schveighoffer from comment #23)
> Perhaps you are getting caught up in terminology. It's not a target the build system is trying to generate.
so it should *never* be (re)generated.

> But my point is, you don't tell it about building the .di file because the build of the .di file is implicit in the rule for the .o.
and build system doesn't even know that we are using implicitly regeneration for some files and that other files can depend of this unknown files. it's a very… strange way to using build system.

> But your project doesn't know how to build /usr/include/stdio.h, so why should your project care about how some other project's .di file is made?
i never need to (re)generate /usr/include/stdio.h, it's god-given. and i'm assuming that we are talking about .di files that can be generated by various parts of the project we are trying to build. god-given .di files can be treated just like <stdio.h> — i.e. not mentioned at all. and not silentely regenerated under any circumstances.


> I will say, I think the enhancement is unusual and counterintuitive. It may be best to enable this mechanism with a special flag. Maybe like -H+
hm. if new behavior will not be default one and must be explicitly turned on, i'm all in for this ER, it will not hurt.

--
September 23, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #25 from Steven Schveighoffer <schveiguy@yahoo.com> ---
(In reply to Ketmar Dark from comment #24)
> (In reply to Steven Schveighoffer from comment #23)
> > Perhaps you are getting caught up in terminology. It's not a target the build system is trying to generate.
> so it should *never* be (re)generated.

No, it will only be regenerated if different. But the build system isn't involved in deciding when and where to build it. It just is concerned with the .o, and the compiler builds the .di according to the build line (and these funky rules).

> > But my point is, you don't tell it about building the .di file because the build of the .di file is implicit in the rule for the .o.
> and build system doesn't even know that we are using implicitly regeneration for some files and that other files can depend of this unknown files. it's a very… strange way to using build system.

It's strange, but not the strangest I have seen. I won't say I think it's the *best* way to do this, but the logic seems sound to me.

> 
> > But your project doesn't know how to build /usr/include/stdio.h, so why should your project care about how some other project's .di file is made?
> i never need to (re)generate /usr/include/stdio.h, it's god-given.

An importing project does not know how to generate foreign .di files that it depends on, so they are "god-given" also.

A project typically shouldn't depend on .di files inside itself, it has the .d files, and you lose a lot of compiler nifty things, such as inlining and CTFE, when you use .di files instead of .d

--
September 23, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx

--- Comment #26 from hsteoh@quickfur.ath.cx ---
I agree with Walter. Why should the compiler care if the previous version of the .di file different or not? That's not the compiler's job. If the build tool can't properly handle files that don't change (and I know make doesn't 'cos make sux), then it should be replaced with a saner build tool.

--
September 23, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #27 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to hsteoh from comment #26)
> I agree with Walter. Why should the compiler care if the previous version of the .di file different or not? That's not the compiler's job. If the build tool can't properly handle files that don't change (and I know make doesn't 'cos make sux), then it should be replaced with a saner build tool.

I understand. One way to look at this (which is what motivated the approach) is from the perspective of automating maintenance of C++ xyz.h/xyz.cpp files - which is a noble goal and the stated purpose of .di generation.

When a C++ programmer needs to change the inline/template/interface of a module, they'll change xyz.h. Then the build system will notice the updated timestamp and proceed with building dependent files. For changes to non-inline non-template functions etc, the programmer only touches xyz.cpp and no other dependents are rebuilt.

Switch over to D-land, where the story with xyz.di/xyz.d is similar EXCEPT now the former is automatically taken care of; all the programmer needs to do is update xyz.d and then the .di file will be changed (or not) accordingly.

Touching the .di file only when necessary is the natural automation of a process in which changing the interface vs. the implementation of a module affect different parts of the deliverables.

--
September 23, 2014
https://issues.dlang.org/show_bug.cgi?id=13517

--- Comment #28 from hsteoh@quickfur.ath.cx ---
Relying solely on timestamp to detect change is an antiquated concept that basically only make (and misguided attempts to build on it) suffers from. Modern build systems do not have this problem.

But given that it's not an ideal world (otherwise we wouldn't need to interface with C++ to begin with :-P) one possible workaround is to write your compile rules something along these lines:

sucky.o sucky.di: sucky.d
    $(DMD) $(DFLAGS) sucky.d -ofsucky.o -H -Hfsucky_new.di
    cmp sucky.di sucky_new.di ; if [ $? -ne 0 ] ; then cp sucky_new.di sucky.di
; fi

--