Bug 22904 - Second order dependency are not properly added to MTouch task if Copy Local is set to false.
Summary: Second order dependency are not properly added to MTouch task if Copy Local i...
Alias: None
Product: Visual Studio Extensions
Classification: Xamarin
Component: iOS ()
Version: 3.5
Hardware: PC Windows
: High enhancement
Target Milestone: Future Cycle
Assignee: Bugzilla
Depends on:
Reported: 2014-09-12 01:49 UTC by Virgile Bello
Modified: 2017-06-19 12:39 UTC (History)
7 users (show)

Is this bug a regression?: ---
Last known good build:

Solution that reproduces the problem (10.15 KB, application/octet-stream)
2014-09-12 01:49 UTC, Virgile Bello

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Virgile Bello 2014-09-12 01:49:55 UTC
Created attachment 8015 [details]
Solution that reproduces the problem

Attached is a solution exhibiting the problem:

I have following dependency chain: App1 => ClassLibrary2 => ClassLibrary1
However, I set ClassLibrary2 reference (in App1) as Copy Local = false, and set ClassLibrary2 output folder to App1 folder.

MTouch properly finds ClassLibrary2, but doesn't try to resolve further ClassLibrary1 (command line contains ClassLibrary2.dll but not ClassLibrary1.dll).
However, it is  properly found as a dependency:
3>  Dependency "ClassLibrary1, Version=, Culture=neutral, PublicKeyToken=null". (TaskId:106)
3>      Resolved file path is "c:\users\XXXX\documents\visual studio 2012\Projects\ReferenceError\App1\bin\iPhone\Debug\ClassLibrary1.dll". (TaskId:106)
3>      This reference is not "CopyLocal" because at least one source item had "Private" set to "false" and no source items had "Private" set to "true". (TaskId:106)

Note that such a setup works well on Windows and Android.

This is quite critical in our build pipeline when we distribute our SDK (for Paradox).
We will try to make a workaround in the meantime (by adding missing files manually).
Comment 1 Rajneesh Kumar 2014-09-12 04:47:00 UTC
I have checked this issue and able to reproduce reported behavior. I'll need
confirmation from the developer if this is a bug. Leaving as NEW for now.

Steps I followed:

1. Open attached sample project in VS
2. Check dependency chain App1 => ClassLibrary2 => ClassLibrary1
3. Check ClassLibrary2 reference Copy Local = false in App 1
4. Try to build the project
5. Getting following error

 "Error	1	Failed to resolve assembly: 'ClassLibrary1, Version=, Culture=neutral, PublicKeyToken=null'	C:\Program Files\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets	325	3	App1"

Could you please, let me know if you are facing the same experience as shown in screen cast, if not then let me know what steps should I followed to reproduce this issue ?

Screencast: http://www.screencast.com/t/RLTKreCwhp1

Environment Info:
Microsoft Visual Studio Professional 2012
Version 11.0.61030.00 Update 4
Microsoft .NET Framework
Version 4.5.50938

Installed Version: Professional

LightSwitch for Visual Studio 2012   04938-004-0033001-02837
Microsoft LightSwitch for Visual Studio 2012

Office Developer Tools   04938-004-0033001-02837
Microsoft Office Developer Tools

Team Explorer for Visual Studio 2012   04938-004-0033001-02837
Microsoft Team Explorer for Visual Studio 2012

Visual Basic 2012   04938-004-0033001-02837
Microsoft Visual Basic 2012

Visual C# 2012   04938-004-0033001-02837
Microsoft Visual C# 2012

Visual C++ 2012   04938-004-0033001-02837
Microsoft Visual C++ 2012

Visual F# 2012   04938-004-0033001-02837
Microsoft Visual F# 2012

Visual Studio 2012 Code Analysis Spell Checker   04938-004-0033001-02837
Microsoft® Visual Studio® 2012 Code Analysis Spell Checker

Portions of International CorrectSpell™ spelling correction system © 1993 by Lernout & Hauspie Speech Products N.V. All rights reserved.

The American Heritage® Dictionary of the English Language, Third Edition Copyright © 1992 Houghton Mifflin Company. Electronic version licensed from Lernout & Hauspie Speech Products N.V. All rights reserved.

Visual Studio 2012 SharePoint Developer Tools   04938-004-0033001-02837
Microsoft Visual Studio 2012 SharePoint Developer Tools

ASP.NET and Web Tools   2012.3.41009
Microsoft Web Developer Tools contains the following components:
Support for creating and opening ASP.NET web projects
Browser Link: A communication channel between Visual Studio and browsers
Editor extensions for HTML, CSS, and JavaScript
Page Inspector: Inspection tool for ASP.NET web projects
Scaffolding: A framework for building and running code generators
Server Explorer extensions for Windows Azure Web Sites
Web publishing: Extensions for publishing ASP.NET web projects to hosting providers, on-premises servers, or Windows Azure

NuGet Package Manager   2.8.50313.31
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

PreEmptive Analytics Visualizer   1.0
Microsoft Visual Studio extension to visualize aggregated summaries from the PreEmptive Analytics product.

SQL Server Data Tools   11.1.20627.00
Microsoft SQL Server Data Tools

Workflow Manager Tools 1.0   1.0
This package contains the necessary Visual Studio integration components for Workflow Manager.

Xamarin (3f0c2c501a1c42ac9d362dd1970c001bdce7ce6b)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android
Comment 2 Virgile Bello 2014-09-12 06:02:07 UTC
Yes, I confirm, this is the same issue I face.

It started happening after upgrading from Xamarin 3.3 to Xamarin 3.5.
Comment 3 Daniel Cazzulino 2014-09-12 10:40:22 UTC
Hi Virgile,

there is a substantial difference between Android and Windows builds, since those run fully local, so anything you copy by any means (including pre-post build event scripts) will "just work" because the CLR will find whatever other binaries you drop in the output path. 

The situation is radically different for iOS, where the build (mtouch actually) is remote, so we need to know what files need to be copied over at the MSBuild level. 

I have to ask why you need ClassLibrary2 as CopyLocal=false if the end goal is for it to be included in the output? It's certainly a weird usage of the dependency checking that MS targets already do for you (i.e. you'd need to do also set the output path to the one of the consuming app for all transitive project dependencies from that one, which seems like a waste and honestly not something I've seen in practice at all). This is specially troublesome if you have multiple apps consuming ClassLibrary2, since you can only specify ONE target output path.

I need to understand the scenario better before considering this a bug on our side, since up front it doesn't look like one.

Comment 4 Virgile Bello 2014-09-12 12:13:27 UTC
Use case is that we output multiple assemblies in a single directory to avoid unnecessary copies (to build our engine, and also games).

Rationale: Let's say you have 10 assemblies and each assembly depend on each other forming a chain, you easily ends up in a system where each project add one assembly dependency on top of previous dependencies, so you end up copying 10 + 9 + 8 + .. + 1 assemblies (in obj folder), which is O(n^2) copies. They are quite useless compared to a system where everything is output in a shared relative folder.

In this particular case, we have 2 game assemblies (.exe and .dll). .dll one depends on engine, and .exe uses .dll one (with copy local false -- both of them output in same directory). Since .dll import engine assemblies, it properly imports engine assemblies but not indirect ones.

Same would happen when building unit test in our engine (global folder).

Since your system already picks the given assembly if available in same folder (with CopyLocal == false), it should be able to process its dependencies easily if they are also available in the same folder (as was the case with Xamarin 3.3).

This is a scenario that works fine on any other platform (Windows, Android, WinRT, etc...).

I hope you understand and can consider this scenario!
Let me know if you need any more details.

Worst case we have workaround (CopyLocal to false, or manually adding second-order dependencies in our target file), but it would definitely make our life easier if it worked similar to other platforms.
Comment 6 Daniel Cazzulino 2017-02-14 19:08:20 UTC
After careful evaluation of this scenario, I think the only reasonable thing to do is for you to actually add the assemblies from the shared artifacts folder as references to your iOS app, so that our MSBuild tasks can properly push those to the mac.

Since all Mac-side tools run on a remote disk location, there simply isn't a magic way we can know what to copy and what not to, unless it's visible to MSBuild. One way this can be done in a generic fashion on your side it to have a targets file imported in your app (or in its .csproj directly) that adds those as follows:

<Target Name="AddExtraReferences" AfterTargets="ResolveAssemblyReferences">
     <ReferencePath Include="..\..\SharedBin\*.dll" />

Or the like.