Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project references not always copied even when Private is transitively set to True #1845

Open
chm-tm opened this issue Mar 10, 2017 · 3 comments
Labels
needs-design Requires discussion with the dev team before attempting a fix. triaged

Comments

@chm-tm
Copy link

chm-tm commented Mar 10, 2017

Overview

Take the following solution, with emphasis on references:
References overview
Solid lines denote project references with Private set to True.
Dashed lines denote project references with Private set to False.
Dash-dot lines denote project references with Private undefined.

Issue

With MSBuild 14.0, ClassLibrary0 is not copied to ConsoleApplication6's output directory.
This is consistent for builds from inside Visual Studio 2015, as well as from the command line.

Analysis

Using Kirill Osenkovs MSBuild Structured Log Viewer.
In the build of ConsoleApplication6, MSBuild realizes it needs ClassLibrary0. However, for whatever reasons it cannot find the reference:
build-analysis-1

A partial insight is given by this message when building ClassLibrary2.
build-analysis-2

We now understand and accept that ClassLibrary0 won't be copied to ClassLibarary2.

Note that this means that the Private flag is actually tri-state, which can be quite a surprise for Visual Studio users acustomed to the boolean Copy Local property.

However, this doesn't explain why ClassLibrary0 is not copied to ConsoleApplication6, since there is a complete chain of project references having Private set to True straight from ConsoleApplication6 to ClassLibrary0.

Work-Around

From the analysis, it's quite easy to fix the issue:
Set Private = True for the project reference from ClassLibrary2 to ClassLibrary1.

@Sarabeth-Jaffe-Microsoft Sarabeth-Jaffe-Microsoft added the needs-design Requires discussion with the dev team before attempting a fix. label Mar 10, 2017
@Sarabeth-Jaffe-Microsoft Sarabeth-Jaffe-Microsoft added this to the After 15 milestone Mar 10, 2017
@sebastianslutzky
Copy link

btw, I was testing this sample today and I've noticed that the transitive dependencies are only copied if there is a symbolic reference from a direct dependency.
For example , in the graph from above, if Lib1 has a symbolic ref to Lib0 (e.g. a field such as Lib0.Class1 _myField) then Lib3 ends up with Lib3.dll,Lib1.dll and Lib0.dll.

However, if you comment that line (or declare it as a different type like an interface or System.Object) then Lib3 ends up with Lib3 and Lib1.dll. Lib0.dll doesn't get copied.

I've find this behaviour particularly confusing. It makes it impossible to predict what dependencies are copied by simply looking at dependencies in the project file

@chm-tm
Copy link
Author

chm-tm commented Nov 16, 2017

@sebastianslutzky This is why I've included symbolic references for each project reference. I just didn't want to mix different issues.

radical added a commit to radical/msbuild that referenced this issue Jul 27, 2018
TargetFrameworks on osx have a default fallback search path:

    `/Library/Frameworks/Mono.framework/External/xbuild-frameworks`

This was earlier implemented in mono/msbuild via the app.config, but
then was changed to be specified via the property
`$(TargetFrameworkFallbackSearchPaths)`. And passed to
`GetReferenceAssemblyPaths` task via a new parameter
`TargetFrameworkFallbackSearchPaths`.

This also means that if any user of `GetReferenceAssemblyPaths` does not
use this new parameter, then on osx, msbuild won't be using any fallback
search path. In msbuild's targets files, we pass the new property as
argument for the new GRAP task parameter.

Accordingly, any non-msbuild users(targets) will need to update their
use of GRAP task to get the search path. But this would break any
existing/older users which are not using the new parameter and suddenly
find that projects won't build because of the missing search path.
Existing versions of Xamarin.Android are one example.

To ensure that they can continue working, we internally use the fallback
path if nothing is passed to the task. This can be disabled by setting
`DISABLE_FALLBACK_PATHS_HACK_IN_GRAP_OSX` env var.

Fixes dotnet/android#1845
radical added a commit to mono/msbuild that referenced this issue Aug 1, 2018
TargetFrameworks on osx have a default fallback search path:

    `/Library/Frameworks/Mono.framework/External/xbuild-frameworks`

This was earlier implemented in mono/msbuild via the app.config, but
then was changed to be specified via the property
`$(TargetFrameworkFallbackSearchPaths)`. And passed to
`GetReferenceAssemblyPaths` task via a new parameter
`TargetFrameworkFallbackSearchPaths`.

This also means that if any user of `GetReferenceAssemblyPaths` does not
use this new parameter, then on osx, msbuild won't be using any fallback
search path. In msbuild's targets files, we pass the new property as
argument for the new GRAP task parameter.

Accordingly, any non-msbuild users(targets) will need to update their
use of GRAP task to get the search path. But this would break any
existing/older users which are not using the new parameter and suddenly
find that projects won't build because of the missing search path.
Existing versions of Xamarin.Android are one example.

To ensure that they can continue working, we internally use the fallback
path if nothing is passed to the task. This can be disabled by setting
`DISABLE_FALLBACK_PATHS_HACK_IN_GRAP_OSX` env var.

Fixes dotnet/android#1845
radical added a commit to radical/msbuild that referenced this issue Aug 28, 2018
TargetFrameworks on osx have a default fallback search path:

    `/Library/Frameworks/Mono.framework/External/xbuild-frameworks`

This was earlier implemented in mono/msbuild via the app.config, but
then was changed to be specified via the property
`$(TargetFrameworkFallbackSearchPaths)`. And passed to
`GetReferenceAssemblyPaths` task via a new parameter
`TargetFrameworkFallbackSearchPaths`.

This also means that if any user of `GetReferenceAssemblyPaths` does not
use this new parameter, then on osx, msbuild won't be using any fallback
search path. In msbuild's targets files, we pass the new property as
argument for the new GRAP task parameter.

Accordingly, any non-msbuild users(targets) will need to update their
use of GRAP task to get the search path. But this would break any
existing/older users which are not using the new parameter and suddenly
find that projects won't build because of the missing search path.
Existing versions of Xamarin.Android are one example.

To ensure that they can continue working, we internally use the fallback
path if nothing is passed to the task. This can be disabled by setting
`DISABLE_FALLBACK_PATHS_HACK_IN_GRAP_OSX` env var.

Fixes dotnet/android#1845

(cherry picked from commit 8af44c5)
radical added a commit to mono/msbuild that referenced this issue Aug 28, 2018
TargetFrameworks on osx have a default fallback search path:

    `/Library/Frameworks/Mono.framework/External/xbuild-frameworks`

This was earlier implemented in mono/msbuild via the app.config, but
then was changed to be specified via the property
`$(TargetFrameworkFallbackSearchPaths)`. And passed to
`GetReferenceAssemblyPaths` task via a new parameter
`TargetFrameworkFallbackSearchPaths`.

This also means that if any user of `GetReferenceAssemblyPaths` does not
use this new parameter, then on osx, msbuild won't be using any fallback
search path. In msbuild's targets files, we pass the new property as
argument for the new GRAP task parameter.

Accordingly, any non-msbuild users(targets) will need to update their
use of GRAP task to get the search path. But this would break any
existing/older users which are not using the new parameter and suddenly
find that projects won't build because of the missing search path.
Existing versions of Xamarin.Android are one example.

To ensure that they can continue working, we internally use the fallback
path if nothing is passed to the task. This can be disabled by setting
`DISABLE_FALLBACK_PATHS_HACK_IN_GRAP_OSX` env var.

Fixes dotnet/android#1845

(cherry picked from commit 8af44c5)
@Nirmal4G
Copy link
Contributor

I've hit this as well. Thanks for the workaround!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-design Requires discussion with the dev team before attempting a fix. triaged
Projects
None yet
Development

No branches or pull requests

5 participants