Bug 11035 – Bad solution dependencies to C++ projects
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
visuald
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-09-13T14:20:00Z
Last change time
2015-06-09T01:31:22Z
Assigned to
nobody
Creator
r.sagitario
Comments
Comment #0 by r.sagitario — 2013-09-13T14:20:21Z
original report: http://www.dsource.org/projects/visuald/ticket/164
reported 10/27/12 13:07:46 by TurkeyMan for version 0.3.34
bug in Language Service
So I have created a solution with a C++ lib, and a D executable.
Set the solution dependencies so the D exe depends on the C++ lib, and should attempt to link it automatically.
It is a 64bit project, using the new DMD, which should use MS link, and therefore able to link the C++ lib against the D exe.
It does seem to try and link the dependency, but there is a problem:
1>LINK : fatal error LNK1104: cannot open file 'C:\Program Files (x86)\Microsoft Visual Studio 10.0\dist\lib\x64\Fuji_.lib'
It seems to be giving the wrong path and filename to the linker.
The proper path should be: dist\lib\x64\Fuji_$(Configuration).lib relative to the dependent project's $(ProjectDir?).
I'm not sure why it prepended the visual studio path, but it should use the project dir of the dependent library, and also, it didn't resolve the $(Configuration) macro, so half the filename is missing.
Comment 1: 10/28/12 16:10:23 by sagitario
I think you reported it before for Win32 aswell (#134 (Project dependencies don't resolve the filenames correctly (closed))), but now I can reproduce the problem: the enumerator of the VC project outputs yields a standard file name for the target DLL, but for the import library, it doesn't replace the macros.
I'd say this is a bug of the C++ project plugin (and a regression from VS2008). How is poor little Visual D supposed to know how expand all the plethora of macros VC supports?
What happens now is that the macros are expanded in the context of the D project, so using $(ConfigurationName) instead of $(Configuration) and specifying the path relative to some common directory like $(SolutionDir) should work.
Comment 2: 10/28/12 20:33:37 by TurkeyMan
Replying to sagitario (Comment 1 for ticket:164):
> I think you reported it before for Win32 aswell (#134 (Project dependencies don't resolve the filenames correctly (closed))), but now I can reproduce the problem: the enumerator of the VC project outputs yields a standard file name for the target DLL, but for the import library, it doesn't replace the macros.
>
Ah yeah, I did report it before. It was never fixed.
In this case, I'm not linking against an import library for a DLL, I'm linking against a static lib, but I would expect a DLL set as a dependency to link against the import library as you describe.
> I'd say this is a bug of the C++ project plugin (and a regression from VS2008). How is poor little Visual D supposed to know how expand all the plethora of macros VC supports?
>
Why should D need to expand those macros? How does it resolve that filename? Do you inspect the C++ project properties for those strings manually?
> What happens now is that the macros are expanded in the context of the D project, so using $(ConfigurationName) instead of $(Configuration) and specifying the path relative to some common directory like $(SolutionDir) should work.
>
I can't do those things, since those settings are in the C++ project.
Target Name: Fuji_$(Configuration) -> Fuji_Debug.lib
And the C++ project also has the output directory set where it writes the output to.
There is nothing wrong with the C++ project, it builds correctly and all macros expand properly, but when set as a dependency of a D project, the D project just doesn't know where to get the output, and the name is wrong (macro expansion is missing).
How does VisualD resolve the dependency? There must be some logic in VisualD that finds the output path for a dependency that it is set to try and link against?
This can't be addressed from the C++ side, that's working correctly.
Comment 3: 10/29/12 03:36:25 by sagitario
> In this case, I'm not linking against an import library for a DLL, I'm linking against a static lib
>
It's getting worse :p If you have set the import library while the project was configured to be an executable/DLL, the import library is still passed as an output of the project. To get rid of it, you have to switch back to DLL, clear the "Import Library" entry and switch back to static lib.
> Why should D need to expand those macros? How does it resolve that filename? Do you inspect the C++ project properties for those strings manually?
>
Visual D uses the IVSOutput interface to query the outputs of a project (http://msdn.microsoft.com/de-de/library/vstudio/microsoft.visualstudio.shell.interop.ivsoutput_members%28v=vs.100%29.aspx (http://msdn.microsoft.com/de-de/library/vstudio/microsoft.visualstudio.shell.interop.ivsoutput_members%28v=vs.100%29.aspx)), I'm not aware of another way. For a DLL project the VC package returns two items, the target and the import library. The target is properly expanded:
"C:\\Users\\rs\\Documents\\Visual Studio 2012\\Projects\\ConsoleApp2\\Debug\\Project1.dll"
while the second output yields
"c:\\tmp\\$(OutDir)$(TargetName).lib"
where "c:\tmp" happens to be the working directory where I started the VS debug session.
> I can't do those things, since those settings are in the C++ project
>
If the VC package is buggy some workarounds will be necessary. $(ConfigurationName) and $(Configuration) both seem to be supported by VC, so using $(ConfigurationName) will expand to the same string. But I am afraid there is no workaround for the working directory being prepended to the name.
Comment 4: 10/30/12 19:53:56 by TurkeyMan
Okay, perhaps we have some crossed wires. I'm not talking about DLL's at any point - although I think they should also work - they're not my concern.
What path do you see when you set a D project to be dependent on a VC lib project?
In the DLL case that you just illustrated, would it not be reasonable to take the dll path/name, and just change the extension to .lib? At least as a short term work-around. That will be correct most of the time.
It's very weird that the API gives you that tmp path, do you think that's a bug, or somehow intentional?
In my tests $(ConfigurationName?) no longer works. That was the old macro, it was deprecated and replaced with $(Configuration) (along with some other changed macros too).
How do you resolve one and not the other? It must be simple enough to support both?
I wonder if there is a function in the addin API to resolve paths and macros and stuff for you. It's crazy for strings containing those macros to leave the API, and not provide a mechanism to resolve them properly...
Comment 5: 10/31/12 02:48:33 by sagitario
For a VC static library project, the target lib is correct. But if you have specified an import library (an option not visible for the static lib, but only if you switch the configuration type to DLL) it is still passed as an output. Could you verify in the build log that there are actually two libraries from the dependent project on the command line?
I thought $(Configuration) and $(ConfigurationName) were both supported, as they are shown in the list of available macros (at least in VS2012). But I can support them both in Visual D, too.
My guess is that the VC projects use some private C# interface to pass the actual file names around. I'll think about a workaround.
Comment 6: 12/03/12 14:17:37 by sagitario
$(ConfigurationName?) now supported by Visual D, but that doesn't yet help the bad path passed by VC.
Comment #1 by github-bugzilla — 2013-09-16T07:58:26Z
Visual D 0.3.39 now contains a workaround: if the second output of a dependent project contains a '$', then it is ignored, unless it has extension ".lib" and the first output is not a ".lib". In that case, an import library with the same base name as the first output is assumed.
Try it in https://github.com/D-Programming-Language/visuald/releases/tag/v0.3.39-beta1
Comment #4 by r.sagitario — 2014-10-10T14:52:12Z
I guess the workaround in 0.3.39 is what can be done here. Please reopen if it doesn't work for you.