How to properly specify DocumentationFile in MsBuild 15 .csproj with multitargeting - msbuild

I am using the latest preview of MsBuild 15 and I have a multitarget project file targeting both net40 and netstandard1.6.
I am struggling with specifying <DocumentationFile> correctly.
For any path I would specify, the resultant xml file after the build will be both in that path and two target output directories.
For instance, if I specify
<DocumentationFile>doc.xml</DocumentationFile>
Then the xml file will be generated both in my project dir and bin\net40 and bin\netstandard1.6.
I need those xml documentation files only in my bin\net40 and bin\netstandard1.6 directories. How can I achieve that?
Also, with the current behavior, it is not clear which documentation file is copied to my project dir, because those xml documents can differ for two targets.
In earlier project versions I used to specify documentation xml path separately for Debug and Release build configurations with paths like bin\Debug\doc.xml, but with the newest MsBuild 15 it is possible to do multitargeting and the number of such paths double if I specify the dir for all possible combinations of target and build configuration.
Is there any generic good way to specify documentation file path once and get it to the right output places only?

From my testing if you specify
<DocumentationFile>bin\Debug\netstandard1.0\MyProjectName.xml</DocumentationFile>
it will create doc file in each multi-targeted folder so it'll create
netstandard1.0\MyProjectName.xml
net45\MyProjectName.xml
netcoreapp1.0\MyProjectName.xml
netstandard2.0\MyProjectName.xml
etc.

Related

TFS 2015 Artifacts always empty upon build

I have created build definition which runs successfully. Now I want to create a release definition on the successful build, for which it is asking for artifacts.
When I tried browsing "Drop" folder, I found it empty.
Below are the images from Copy Files step and Publish build artifacts step.
I also tried instructions from The item MY_ARTIFACT_NAME in container XXX could not be found
But no luck. Please help.
I believe that you should use $(build.sourcesdirectory) (or a path relative to) as the source folder if you want to copy files which are not checked in.
Also, from the documentation of the Copy Files step
The pattern is used to match only file paths, not folder paths. So you should specify patterns such as **\bin\** instead of of **\bin.
Try changing the contents pattern to **\bin\** and see if that helps.

Automatically Compressing Published Files Into a .ZIP File

I am currently using Teamcity to automatically build and publish our solution to a directory specified in the system.PublishProfile property (i.e. C:\Deployment Files).
Is it possible that after publishing TC will automatically .zip them into one file with a custom set file name?
When you define Artifacts paths inside General Settings tabs, you can set:
./out/Deploy => %BuildName%.zip
And, inside Parameters, you can specify the BuildName value.
This will produce a zipped artifact.

UWP APPX1101 errors with 2 unique data files

I'm in the process of converting a rather huge project to a Windows 10 Store app. I've gotten it to compile and now can't get past several APPX1101 errors - "Payload contains two or more files with the same destination path". The files are .xml files part of the project, e.g. "baseDir\Assets\foo\timers.xml" and "baseDir\Assets\bar\timers.xml". Different files and different paths.
The solution and projects are created by CMake (3.72). The cmake files have been modified to support creating a Windows 10 store app platform config.
It appears that the directory tree has been flattened and files are overlapping. But how or why eludes me. Every UWP project I've seen contains an "Assets" folder under the main project but this one does not. I see files such as Logo.png and SplashScreen.png in folder named "Resource Files". The files causing the errors are under the folder named "Assets" which existed before this was a UWP project.
Primarily:
How can I fix this error? Did I misconfigure CMake?
Additionally:
How to avoid directory flattening?
There are a few hundred data files taking up a few hundred megabytes used by the program. Will I need to add each of them to the solution to be packaged?
Updates:
I've gleaned more info but not enough to fully satisfy the question. The directory flattening in the output occurs due to how the files are added to the project via CMake and how the original Windows product was packaged. The XML files are added to the project with a full path in the .vcxproj. The .vcxproj.filters also use a full path to the file and a filter like "Data\foo". The desktop Windows version didn't need to care since it knew where to find it's data relative to the executable and was packaged by an external tool.
I've manually added an "Assets" filter and modified the .vcxproj and .vcxproj.filters files. The .vcxproj file needed a property added to the file's include. This uses relative paths and gets rid of the APPX1101 duplicate error.
.vcxproj
<XML Include="..\Base\Assets\foo\Data\timers.xml">
<Link>Assets\foo\Data\timers.xml</Link>
</XML>
.vcxproj.filters
<XML Include="..\Base\Assets\foo\Data\timers.xml">
<Filter>Assets\foo</Filter>
</XML>
Update 2
From what I can tell, it's not possible to get CMake to add a <Link> to XML and other .vcxproj Include types. I went through the latest CMake source code (3.8rc). The <XML Include> is added to the .vcxproj in cmVisualStudio10TargetGenerator::WriteExtraSource() in cmVisualStudio10TargetGenerator.cxx. Other types have the option to set the flag to add the <Link> but XML and other data types do not have code to set the flag.
The only options I can see are modifying CMake source or reworking the project to add data files using relative paths that match the same <Filter> for the matching Include in the vcxproj.filters file. This is only a problem with CMake. Visual Studio 2015/2017 have no problem adding assets above your tree. The MS UWP examples on GitHub do it to share common data between sample projects.
It's been a while and I'm posting this as an answer in case someone else runs into this problem. I'm not marking it accepted because I find the workaround rather weak. My knowledge of CMake is limited and my understanding of Universal Windows apps even less.
The primary issue is that by design, CMake does not build a relocatable solution. i.e. you can't xcopy a Windows solution to another tree and expect it to work as you would would with one generated from within the Visual Studio IDE.
The second issue is that this was a huge pre-existing project already targeting multiple platforms. And by huge, I mean it ships on a dual layer blu-ray disc. The location of asset files was fixed and was above the location of the CMake build folder. This caused files to be stripped of their path when added to the layout whenever their location was not under the expected assets folder.
There is no way in the current CMake (3.8) to add a <link> tag to the include in the project file. And CMake creates the include tag with the full path to the file not a relative one by design.
The workaround I came up with was to add a step to the batch file that invokes CMake to edit the .vcproj and vcproj.filters files to change the fixed asset paths relative ones and then added another step to create a symbolic link/junction (SysInternals.com) under the build folder to the location where the assets were. The assets now appear as being under the expected asset folder are now added correctly to the layout.
As I said, not ideal but it works. The real solution would be to re-organize all the data but this is not something that can happen for this project when a vast amount of data is generated from different script, tools, sources and contributors.

Visual Studio ASP.NET Web API Precompiled files placed in a different folder with TFS

I have an asp.net web api project whose output needs to be packaged in a setup project using wix.
I would like to precompile the site. The problem is that the precompilation process generates variable file names (ie. *.compiled files in particular).
I also would like to build the setup in a TFS build.
It seems that my only option is to generate a .wxs file wihtin the prebuild step of the wix project.
The .wxs files source paths are using $(var._My_Web_Project_.TargetDir). This seems to be translated to a Sources based directory.
I'm using paraffin to do that already and it works perfectly fine when building the solution with visual studio.
When building the solution through a TFS build, the .compiled files are copied to a Binaries folder, whereas all the other related web site files are copied to a Sources based directory.
The build errors are like the following :
The system cannot find the file 'd:\BuildAgents\___basedir___\Binaries\___web_project_dir\_PublishedWebSites\___site___\bin\textsample.cshtml.c6fb271c.compiled'.
The file is indeed in the Sources directory.
'd:\BuildAgents\___basedir___\Sources\___web_project_dir\_PublishedWebSites\___site___\bin\textsample.cshtml.c6fb271c.compiled'
I think I somehow need to redefine the aspnet_compiler output or something like this, but can't figure out how to do that.
The msbuild command line arguments are the follwing:
/p:GenerateProjectSpecificOutputFolder=true /p:VisualStudioVersion=14.0 /p:DeployOnBuild=true /p:PublishProfile=local /p:CleanWebProjectOutputDir=False /verbosity:d
EDIT 1: I'm using XAML build.
Any help appreciated.
EDIT 2:
With the new task based build, it works as is (no need to use an additional Copy Files task).
The aspnet_compiler output the .compiled files in the correct folder :
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v / -p D:\BuildAgents\vNext\_work\1\s\Softs\__Solution__\__Web_Project\obj\Release\AspnetCompileMerge\Source -c D:\BuildAgents\vNext\_work\1\s\Softs\__Solution__\__Web_Project__\obj\Release\AspnetCompileMerge\TempBuildDir
In the new tasks based build system, it's easy to copy files from a source folder to a target folder with Copy Files task.
Source Folder: Folder that contains the files you want to copy.
Contents: Specify minimatch pattern filters (one on each line) that you want to apply to the list of files to be copied.
Target Folder: Folder where the files will be copied. In most cases you specify this folder using a variable.

How do I set up the MSBuild script to use the outdirectory's set in the csproj files while building the entire solution?

I'm not sure how I can get the MSBuild script to use the outputpath, outputdirectory values from the CSproj files. I've seen examples where I set the outputpath in the MSscript but that dumps the all the output in one big folder. I want the individual projects to have their own output paths and MSbuild to build the solution in such a way that the output for the projects and created in the corresponding output directories. Thanks.
There is not an easy way. One option is to extend MSBuild and have it copy the output from each project to a common folder.
If you look at the Microsoft.Common.Targets file in the c:\Windows\Microsoft.Net\Framework\v4.*\ you can see how it does load a custom targets file at both the beginning and end of that folder. If you add a Custom.After.Microsoft.Common.Targets to the C:\Program Files (x86)\MSBuild\v4\ folder you can have it load a file say $(SolutionDir)\Solution.targets. This will allow you to extend each solution differently and you can add any custom actions you want inside every solution that applies to every project. I use this and it works great.
Thanks for your answers guys. I found a way to run the solution without giving a specific output folder. I had to fix the output folder path to /bin in the csprojs and then running MSbuild with the solution was able to pick up those paths from the csprojs and build the output into those folders.