Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding same "*.dll" reference to multiple projects in the same Solution

I have a Visual Studio 2008 .NET C++/CLI Solution. My solution consists of many sub projects. I define a custom build directory for each project and called it "Output".

My solution:

  • MyFirstProject (*.exe)
  • MySecondPrject (*.dll)
  • ...
  • MyNthProject (*.dll)

Each of the sub project use Log4.net.So I create a directory (called LogBinary) and put log4.net DLL in that folder. Then to use log4net I add this DLL as a reference to each of my project.

But when I try to compile my main project (*.exe) I got tons of warning (over 400).

Just an example:

Warning 110 warning C4945: 'AbsoluteTimeDateFormatter' : cannot import symbol from 'somepath\log4net.dll': as 'log4net::DateFormatter::AbsoluteTimeDateFormatter' has already been imported from another assembly 'log4net'"somepath\log4net.dll"

Lots of warnings with:

has already been imported from another assembly

Why do I get these warnings? Does anybody have a solution to add same DLL to multiple projects (except using GAC)?

like image 893
NoviceAndNovice Avatar asked Jan 14 '11 14:01

NoviceAndNovice


3 Answers

I had the same problem again today.
First of all, thanks to Jon Cage and the linked article in his post on this thread, see above (or below). +1!!! It solved my problem.

But because I hate things like toggle them as appropriate for your case, which means nothing but trial and error, I did some tests as I have 2 solutions with a good number of C++/CLI projects in each.

Here's my advice and explanation for it:
For all 'self created' assemblies (that have 'copy local' set to true):

"Common Properties" -> "Framework and References" -> "References" -> Select a Reference.
On the Property Sheet on the right -> "Build Properties" -> "Use Dependencies In Build"
-- (copied from the linked msdn forum article of Jon Cage's post)

Set this parameter Use Dependencies In Build to "false" by unchecking.
It works as 'reference forwarding', see example below.

TECHNICAL BACKGROUND:
-> means 'references'
method 1:
in my solution SwCore:
A.1.1 network->tools, A.1.2 network->basics.
A.2.1 tools->basics.
A.3.1 drives->basics, A.3.2 drives->tools, A.3.3 drives->network
A.4.1 ...
with "Use Dependencies In Build" set to true, the reference A.1.2 can be omitted, as it is included in A.2.1.
all files are created in swcore\release\
== problem:
in solution DDI:
B.1.1 DDI_hardware->DDI_job, B.1.2 DDI_hardware->drives
B.2.1 DDI_job->basics, B.2.2 DDI_job->tools, B.2.3 DDI_job->job
DDI_job is created in DDI\Release\ and with "U.D.InBuild" set to true, it includes basics.
DDI_hardware is created... and with "U.D.InBuild" set to true, it includes DDI_job->basics.
DDI_hardware also references basics from SwCore\Release\
==>> double reference to basics and others. VS sees 2 files and can not realize that it is the same content.

method 2:
A.1.1 network->tools, A.1.2 network->basics.
A.2.1 tools->basics.
with "U.D.InBuild" set to FALSE, the reference A.1.2 can NOT be omitted, because it is not forwarded from A.2.1.
== works, because no assembly will contain other deeper dependencies, so there won't be conflicts.

BTW: This forces you to specifiy all necessary references for each project, so you also have an overview what you are using in your project.

Last info: I can not tell for sure, if my explanation is correct. Maybe s.o. else can confirm.

like image 163
Tobias Knauss Avatar answered Sep 28 '22 00:09

Tobias Knauss


Change reference on the projects, set all "copy local ..." properties to false.

Source : http://developertips.blogspot.com/2008/07/ccli-warning-c4945.html

like image 29
Dustin Davis Avatar answered Sep 27 '22 23:09

Dustin Davis


I finally found a solution to this problem which doesn't feel like a hack. I found the answer in a response from 'pyro_serv` on the msdn social site:

The fix is to use the "Use Dependencies In Build" and "Use In Build" flags on each VC project references (via the VC properties sheet), and toggle them as appropriate for your case to resolve this error.

So for the OP's example which looks something like this:

Solution -> Log4.net
Solution -> Proj1
Solution -> Proj1 -> Log4.net
Solution -> Proj2
Solution -> Proj2 -> Log4.net
...

The way to avoid the warnings is to set Use Dependencies in Build to false for all of the references to Proj1,Proj2,..,Projn.

I've just verified this with a demo solution and it works great - I can't believe how simple the solution is and how much time I've wasted to find it!

like image 23
Jon Cage Avatar answered Sep 28 '22 01:09

Jon Cage