Bug 18641 – VisualD - First 5 minutes - Improve experience adding .d files to existing C++ projects
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
visuald
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2018-03-20T19:00:23Z
Last change time
2018-05-06T19:04:55Z
Assigned to
No Owner
Creator
Manu
Comments
Comment #0 by turkeyman — 2018-03-20T19:00:23Z
I have a colleague who just tried out D for the first time.
He's a gamedev, so coming from VS, and expects a very high bar for quality.
He offered me some feedback which I think it worth passing on.
I wonder if there's any way we can improve the experience of adding .d files to an existing C++ project.
Currently it will compile the file as expected, but there will be a flood of link errors.
There are 2 things the user needs to do: add the link path to find the dlib, and add the dlib.
These 2 tasks are slightly complicated, and a new user will probably fail: the libs all have different filenames depending on the architecture, and 32bit has 2 variants, and most users will not know which one to pick, or why.
I'd suggest that at very least, Installing VisualD should amend the global library search paths for each architecture to include the D lib paths, so at least the user doesn't need to add the proper lib directory to their project. Users don't need to add paths to the MSC runtime libs.
Then we only have the user adding the lib, which has awkward filenames... I wonder if we can make a compile option (and enable it by default) that will embed a link reference to the proper phobos lib in the object file (like VC++ object files to do their respective CRT).
If D object files have a ref to the proper dlib filename, and the lib paths were known to msbuild by default, then the user wouldn't need to do anything, and it would all just work!
Naturally, a reference to a dlib should be omitted in -betterc.
Comment #1 by r.sagitario — 2018-04-24T07:00:36Z
The runtime library link comments are usually added to the object file that contains main(), but this falls short in your case of building a static library. Adding it elsewhere into the library doesn't help because there is no guarantee that it will be dragged in by the linker.
So far, I've been trying not to interfere with projects that don't use D at all. Adding D files to a C++ project already modifies linker search paths, but doesn't add the runtime libraries. I guess that would be better.
With static libraries this gets a bit more complicated as these settings must be propagated to the actual link step in a different project.
Comment #2 by turkeyman — 2018-04-24T19:01:40Z
Why don't we just amend the global C/C++ props and include the D lib paths the same as MS does for CRT paths? I don't think anyone will mind ;)
The link comment thing is interesting. Why only in main? MSC definitely includes the runtime lib reference in every single .obj file it emits (unless compiling with /Zl). I feel like we should do the same thing.
Have you had experience where the linker ignores it?
> With static libraries this gets a bit more complicated as these settings must be propagated to the actual link step in a different project.
What does MSC do?
I feel like we should probably just match MSC's patterns verbatim, with respect to link paths, embedding library references, etc.
Comment #3 by r.sagitario — 2018-04-25T06:18:02Z
(In reply to Manu from comment #2)
> Why don't we just amend the global C/C++ props and include the D lib paths
> the same as MS does for CRT paths? I don't think anyone will mind ;)
That's probably fine for the phobos library, but the dmd/ldc releases also come with curl.lib, that might interfere with other people libs.
> The link comment thing is interesting. Why only in main? MSC definitely
> includes the runtime lib reference in every single .obj file it emits
> (unless compiling with /Zl). I feel like we should do the same thing.
> Have you had experience where the linker ignores it?
A static library created with dmd is made up of object files for every function and data object (not 100% sure about the latter). Every one of these will have to include the phobos reference ("/DEFAULTLIB:phobos64.lib") making for a gigantic combined command line. Not sure this is desirable.
>
>
> > With static libraries this gets a bit more complicated as these settings must be propagated to the actual link step in a different project.
>
> What does MSC do?
> I feel like we should probably just match MSC's patterns verbatim, with
> respect to link paths, embedding library references, etc.
MSC uses the internal linker directives, but the granularity is higher as there is only one object file per source file.
I managed to pass the libraries to the linker when you add a D file (without main) to the project that does the link.
For a static library with D modules, this needs to be propagated to the linker. I think it is feasible as msbuild does something similar (extract info from another project) with the library file names.
Comment #4 by turkeyman — 2018-04-25T06:36:57Z
Okay, well I think you know much better than me at this point.
I don't understand what you mean by "each C++ file produces one .obj file" but D is different? The D compiler just emits as many .obj files as compiler invocations... why are there many more than that?
Comment #5 by r.sagitario — 2018-04-25T06:58:55Z
(In reply to Manu from comment #4)
> I don't understand what you mean by "each C++ file produces one .obj file"
> but D is different? The D compiler just emits as many .obj files as compiler
> invocations... why are there many more than that?
That happens if you are building a library to allow filtering out functions that are never called. You can see these object files on disk when compiling with "-c -multiobj".
Comment #6 by turkeyman — 2018-04-25T07:29:12Z
Ohhh wow. Interesting hack!
Does C++ do anything like that?
What sort of functions are generated but never called?
I kinda imagine that generating a function would imply you intend to call it... what other mechanisms generate functions but don't call them? Does CTFE emit a lot of these?
It sounds like this is a problem that could be addressed in DMD... like, it should be able to keep a record of whether each function was generated by a mechanism that should or shouldn't add it to the object's symbol table?
(In reply to Manu from comment #6)
> Ohhh wow. Interesting hack!
> Does C++ do anything like that?
There is "function level linkage" which puts each function in a COMDAT but that is done by dmd anyway. I suspect using object files instead helps to split the DATA segment, too.
>
> What sort of functions are generated but never called?
> I kinda imagine that generating a function would imply you intend to call
> it... what other mechanisms generate functions but don't call them? Does
> CTFE emit a lot of these?
In a library there can be many function never being called. C solved this by putting every function in its own source file, but that's sometimes almost impossible in D, e.g. for struct member functions.
>
> It sounds like this is a problem that could be addressed in DMD... like, it
> should be able to keep a record of whether each function was generated by a
> mechanism that should or shouldn't add it to the object's symbol table?
That would be great, but it's a different issue, e.g. https://issues.dlang.org/show_bug.cgi?id=18238 or https://issues.dlang.org/show_bug.cgi?id=18774
Comment #9 by turkeyman — 2018-04-30T07:37:22Z
What fix for this issue did you add to that new build?
Comment #10 by turkeyman — 2018-04-30T07:37:36Z
I'm not sure what to test for... :)
Comment #11 by r.sagitario — 2018-04-30T08:19:57Z
You should now be able to add a D file to a project and it should compile and link without any additional settings. That includes adding it to a static library and the link being in a C++ only project.