Bug 6249 - Assets not included in package when IntermediateOutputPath is specified to an absolute path.
Summary: Assets not included in package when IntermediateOutputPath is specified to an...
Status: RESOLVED FEATURE
Alias: None
Product: Android
Classification: Xamarin
Component: MSBuild ()
Version: 4.2.x
Hardware: PC Windows
: High normal
Target Milestone: ---
Assignee: Atsushi Eno
URL:
Depends on:
Blocks:
 
Reported: 2012-07-24 06:11 UTC by Andreas
Modified: 2013-07-25 02:39 UTC (History)
3 users (show)

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

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 or GitHub 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:
Status:
RESOLVED FEATURE

Description Andreas 2012-07-24 06:11:16 UTC
You should be able to simple reproduce this by trying to build a application-package from command line and specifying a absolute path for the IntermediateOutputPath.

E.g. this command-line creates a package without any assets included:
msbuild Soloplan.InTouch.M4A.sln /target:Rebuild  /p:Configuration=Release /p:Outdir=c:\project.net\Soloplan\inTouch\rel\ /p:BaseIntermediateOutputPath=c:\project.net\soloplan\intouch\inter\ /P:IntermediateOutputPath=c:\project.net\soloplan\intouch\inter\

While this creates the package as expected:
msbuild Soloplan.InTouch.M4A.sln /target:Rebuild /p:Configuration=Release /p:Outdir=c:\project.net\Soloplan\inTouch\rel\ /p:BaseIntermediateOutputPath=inter\ /P:IntermediateOutputPath=inter\

The problem occurs only on our build server where we try to isolate builds by specifying a IntermediateOutputhPath (and to be also able do a simple/effective cleanup because we've separated source files and build artifacts).

Thanks for your assistance and please don't hesitate to contact me if you need
more information or I could be of any further assistance.

Best regards,

Andreas
Comment 1 Andreas 2012-07-24 06:59:27 UTC
Don't know if this is sufficient - but maybe it is just enough to remove "$(ProjectDir)" in Novell.MonoDroid.Common.targets on line 744 (the part where aapt gets called)?
Comment 2 Jonathan Pryor 2012-07-31 16:30:24 UTC
Thank you for the bug report. That is exactly the issue -- it should be $(MonoAndroidAssetsDirIntermediate), not $(ProjectDir)\$(MonoAndroidAssetsDirIntermediate).

Fixed in cc9cbf2e, and should be part of the 4.2.6 release.
Comment 3 Andreas 2012-09-20 03:52:04 UTC
Sure that the change made it in 4.2.6 release? Line 770 still contains "AssetDirectory="$(ProjectDir)$(MonoAndroidAssetsDirIntermediate)".
Comment 4 Jonathan Pryor 2012-09-20 11:24:38 UTC
the final 4.2.6 release was more of a "4.2.5.1" hotfix release (which is why the 4.2.6 release notes don't mention this bug). Sorry.

The 4.2.7 release should contain this fix. :-)
Comment 5 Andreas 2012-11-02 03:36:27 UTC
This isn't included in 4.2.7 - but as release notes indicating there is hope for 4.2.8.
Comment 6 Andreas 2013-07-23 09:01:13 UTC
There is still a problem with assets and intermediatepath in Xamarin.Android 4.6.8 that has to do with the incremental build feature:

If you create a solution with two android application both having a assets with same name - then the first assets makes it into both packages.

This is because _GenerateAndroidAssetsDir is skipped for the second package build.

I worked around this issue by just commenting out the inputs/outputs of the skipped target:

Xamarin.Android.Common.targets line 441:
<Target Name="_GenerateAndroidAssetsDir">
	<!--Inputs="$(MSBuildAllProjects);@(AndroidAsset)"
	Outputs="@(_AndroidAssetsDest)"-->
	<MakeDir Directories="$(MonoAndroidAssetsDirIntermediate)" />
	<Copy SourceFiles="@(AndroidAsset)" DestinationFiles="@(_AndroidAssetsDest)" SkipUnchangedFiles="true" />
	<RemoveUnknownFiles Files="@(_AndroidAssetsDest)" Directory="$(MonoAndroidAssetsDirIntermediate)" RemoveDirectories="true" />
	<Touch Files="@(_AndroidAssetsDest)" />
</Target>

I hope this has no other side-effects ;-)

To reproduce my problem just create one solution with two applications, both having a assets with same filename. Then just build the solution from the command line with:

msbuild AndroidApplication1.sln /p:intermediateoutputpath=c:\temp\AndroidApplication1\temp\ /p:outdir=c:\temp\AndroidApplication1\out\ /verbosity:detailed

If you take a look at the log you'll notice that the second GenerateAndroidAssetsDir is skipped.

Please let me know if I was unclear or if you'll need more information to track down this problem. Thanks in advance, Andreas.
Comment 7 Jonathan Pryor 2013-07-23 10:24:05 UTC
@Andreas: I don't think that setting $(IntermediateOutputPath) at the solution level is supported, as various bits of our build system assume/require that $(IntermediateOutputPath) is a per-project value (as various project-specific resources will be copied into that directory).

Eno: is the above diagnosis correct?
Comment 8 Atsushi Eno 2013-07-23 10:43:03 UTC
jonp: yes. Also, we may assume that property being relative paths. You can specify it only when it works. We are not going to change it only to allow absolute paths as making such changes and thus bringing potential bugs to normal users is not acceptable.
Comment 9 Andreas 2013-07-24 01:46:29 UTC
Many thanks for your clarification. To be honest I really hope that you will support a fixed IntermediateOutputPath in a future version, since I still believe that this is the only (clean) way a CI server can separate the source files from binary build artifacts. But once again - thanks! 

P.S.: For now I will stay with my workaround - if I notice any other strange things I will note them here.
Comment 10 Jonathan Pryor 2013-07-24 13:40:25 UTC
The problem isn't $(IntermediateOutputPath) per-se; the problem is having all projects share the same $(IntermediateOutputPath) value.

This would be ugly, but it should be possible in a CI environment to "manually" build each project separately with a different $(IntermediateOutputPath) value, instead of building the solution with $(IntermediateOutputPath) set.

Alternatively (and entirely untested!), perhaps you can set $(IntermediateOutputPath) so that it has a per-project value, e.g. set $(IntermediateOutputPath) so that it contains $(AssemblyName)?

> msbuild Soloplan.InTouch.M4A.sln /target:Rebuild  /p:Configuration=Release
/p:Outdir=c:\project.net\Soloplan\inTouch\rel
'/p:BaseIntermediateOutputPath=c:\project.net\soloplan\intouch\inter\$(AssemblyName)\'
'/P:IntermediateOutputPath=c:\project.net\soloplan\intouch\inter\$(AssemblyName)\' 

If that doesn't work on the command line (again, untested!), it _should_ work if you edit your .csproj files to set $(IntermediateOutputPath) with another indirection:

    <PropertyGroup>
        <CIIntermediatePath>$(IntermediateOutputPath)</CIIntermediatePath>
        <IntermediateOutputPath>$(CIIntermediatePath)\$(AssemblyName)</IntermediateOutputPath>
        <BaseIntermediateOutputPath>$(CIIntermediatePath)\$(AssemblyName)</BaseIntermediateOutputPath>
    </PropertyGroup>

You should then be able to:

> msbuild Soloplan.InTouch.M4A.sln /target:Rebuild  /p:Configuration=Release
/p:Outdir=c:\project.net\Soloplan\inTouch\rel
/p:CIIntermediatePath=c:\project.net\soloplan\intouch\inter\
Comment 11 Andreas 2013-07-25 02:39:09 UTC
@Jonathan: Thanks for your tips - finally I've implemented a similar solution - specifying a BaseIntermediateOutputPath in the command line and overwriting the IntermediateOutputPath property just in my two Xamarin/Android application projects.