I created a build target in a project file (App.Tests.csproj) that imports a project:
<Import Project ="$(Location)\Special.Tasks"/>
These tasks only exist on our build server, that location does not exist on our developers work station. The build target will ever only be run from the build server.
My problem is that when I try to open the sln (containing the project with the build target) on a workstation without the Special.Tasks the project won't load.
I don't want to distribute the Special.Tasks to each workstation.
Is there any way to tell MSBuild or Visual Studio to load even if an import fails?
Just add condition to the Import target
<Import Project ="$(Location)\Special.Tasks"
Condition="Exists('$(Location)\Special.Tasks')"/>
Related
I have a project that imports a certain targets file from a Nuget package. Even though I use PackageReferences I am forced to import this file manually.
(See my other question for details - How are we supposed to execute package build targets in the new world where nuget packages are consumed through msbuild PackageReference?)
This targets file injects chromedriver.exe into the Content item group with CopyToOutputDirectory = PreserveNewest.
I observe a situation where chromedriver.exe is not copied to the bin folder when running msbuild /t:"Restore;Build", but it is copied when running the two targets separately - msbuild /t:Restore; msbuild /t:Build.
Can anyone explain how this happens?
(I killed a good portion of the day learning the difference on my skin, want to know how come?)
Restore changes the imported project files in the obj\ directory.
For this to take effect, the project file needs to be re-evaluated entirely, which does not happen when you run the Restore and Build targets in the same invocation.
Use the -restore command line switch for MSBuild to run a Restore before the other specified targets in the same command line call. MSBuild will run the Restore, empty its XML caches and re-evaluate the project again when running the requested build.
Our continuous delivery set-up, until recently, was delivering Service Fabric packages using the following command:
msbuild SFApp.sfproj /t:Package
This was necessary because the target Package is unavailable at the solution level. I.e. The command
msbuild SFSolution.sln /t:Package
Fails, as the target does not exist.
As our dependency mesh grows, it gets to a point in which most interfaces projects will not build without a solution file (to work around the "OutputPath does not exist" red herring). There seems to be a way to do that according to this answer. Unfortunately, while targets like Clean work…
msbuild SFSolution.sln /t:SFApplication:Clean
(…snip…)
Build succeeded.
0 Warning(s)
0 Error(s)
…the target Package won't!
msbuild SFSolution.sln /t:SFApplication:Package
(…snip…)
Build FAILED.
"SFSolution.sln" (SFApplication:Package target) (1) -> SFSolution.sln.metaproj :
error MSB4057: The target "SFApplication:Package" does not exist in the
project. [SFSolution.sln]
0 Warning(s)
1 Error(s)
(Solution/project folders/names omitted/paraphrased for clarity. I can provide the actual logs if necessary.)
So the question is: how could I, using the Command Line, build one project using the Package target and the solution file?
Or how can I otherwise package a Service Fabric application from the command line?
It's bad idea to compile sfproj file(and any other project file) without sln, because it can bring wrong content to its output from referenced projects. Only solution has a knowledge about what project to compile in what configuration.
To make Package similar to "Right Click->Package" in VS:
Just add to your sfproj the following target
<Target Name="ForcePackageTarget" AfterTargets="Build" Condition="'$(ForcePackageTarget)' =='true'">
<CallTarget Targets="Package"/>
</Target>
And then running normal build on solution you may trigger the package step by /p:ForcePackageTarget=true :
msbuild yoursolution.sln /t:Build /p:ForcePackageTarget=true /p:Configuration=Release /p:Platform=x64
Actually it performs two-in-one steps, build and package, with respect to Solution Configurations on all referenced projects
MSBuild only supports a small set of target names that can be specified at the solution level. As you've discovered, Package is not one of them. You'll need to execute two separate calls to MSBuild: one which builds the solution and one which calls the Package target on the sfproj. The Package target of an sfproj has a dependency on the Build target so it will ensure that the sfproj and its project dependencies are built.
I had the same problem and fixed it by changing the Platform in the failing projects to explicitly build for x64.
Click Build > Configuration Manager and make sure that the assemblies are compiled for the x64 platform, that should also set the Output Paths in the corresponding .csproj files.
The actual command line action that is being executed is this:
"C:\Program Files (x86)\MSBuild\14.0\bin\amd64\msbuild.exe" "C:\agent\_work\1\s\Project\SFProject.sfproj" /t:Package /p:platform="x64" /p:configuration="release" /p:VisualStudioVersion="14.0"
Use the below script.
C:\Program Files (x86)\Microsoft Visual Studio 14.0> msbuild "Fabric.sfproj" /t:Package /p:Configuration=Release
Service fabric requires Target to be set in x64 platform,
So change all you reference projects target to x64 platform.
you can do this by using configuration properties of your solution. If x64 is not listed in 'Configuration Properties' click configuration manager in the same window and under platform column for the required project add new project platform as x64.
Hope this works for you.
We have had the exact same problem as you had and I have been looking around for a solution all over the web and did some experiments. Those are the steps that worked for us:
Don't manually add a target anywhere as suggested by other answers on StackOverflow. Not necessary. Especially in a CI environment, you want to build the projects separately anyways.
Prepare the projects in the Solution: Change the target platform for all projects to x64
Build the application
msbuild.exe SFAplication.xproj /p:Configuration=Release /target:rebuild
Package the App
msbuild.exe SFAplication.sfproj /p:Configuration=Release /target:Package
I try to integrate StyleCop in a Visual Studio solution. Installing StyleCop on each machine of each developer is something I would prefer to avoid. The suggestion I've seen several times (example) is to include the binaries of StyleCop within the project, storing them in version control.
I did that. It works on my machine, but fails on a different machine where StyleCop is not installed. After uninstalling StyleCop on my machine, it doesn't work there either.
The error message is the following:
Severity Code Description Project File Line
Error The "StyleCopTask" task could not be loaded from the assembly C:\Program Files (x86)\MSBuild..\StyleCop 4.7\StyleCop.dll. Could not load file or assembly 'file:///C:\Program Files (x86)\StyleCop 4.7\StyleCop.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. Demo
This is what I included in every .csproj file:
<Import Project="$(SolutionDir)\externs\Microsoft.StyleCop\StyleCop.targets" />
The directory C:\demo\externs\Microsoft.StyleCop contains:
The copy of all the files from C:\Program Files (x86)\StyleCop 4.7,
The copy of C:\Program Files (x86)\MSBuild\StyleCop\v4.7\StyleCop.Targets.
What's wrong?
It appears that StyleCop.Targets contains an absolute path:
<UsingTask
AssemblyFile="$(MSBuildExtensionsPath)\..\StyleCop 4.7\StyleCop.dll"
TaskName="StyleCopTask"/>
In order to be able to use StyleCop on machines where the application is not installed, change this path to something similar to:
<UsingTask
AssemblyFile="$(SolutionDir)\externs\Microsoft.StyleCop\StyleCop.dll"
TaskName="StyleCopTask"/>
I am newbie to TFS.
I am trying to automate process of build upon checking in the code in TFS.
I setup a Controller and an Agent. I created a new build definition and set a "build" and "drop" folder on c:.
I check in the code, expecting to see the generated dll files in "drop" folders. There's none, just "logs" folder. The "binaries" folder in "build" folder is also empty. Apparently the binaries are not being generated at all. How can I have MSBuild to generate the dll files?
They are generated when I compile the website locally on my development machine under "bin\" folder. The solution is comprised of two separate projects: "core" and "web" where "core" is referenced within "web".
Any thoughts?
What is the Summary showing of your build that ran? Or are there errors in your build? You can check the log of the build by opening the build in Visual Studio and then click View Log.
I'm not able to build solution incrementally. I checked diagnostic log and I found that every project containing workflows are always rebuild because of this:
Input file ".NETFramework,Version=v3.5" does not exist.
Workflows are always recompiled, new temporary files are created and project is build again.
Building target "WorkflowCompilation" completely.
Input file ".NETFramework,Version=v3.5" does not exist.
Using "CompileWorkflowTask" task from assembly "System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35".
Task "CompileWorkflowTask"
No files found with '.xoml' extension in the set of input files.
Generated temporary code file: C:\Users\Ludwo\AppData\Local\Temp\uwdnm5th.cs
Workflow markup validations completed with 0 errors and 0 warnings.
Done executing task "CompileWorkflowTask".
Done building target "WorkflowCompilation" in project "Delta.Workflow.Common.Merged.csproj".
Target "CoreCompile" in file "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.targets" from project "h:\Prj\R4x\M\CountrySystems\Delta\Common\Delta.Workflow.Common\Delta.Workflow.Common.Merged.csproj" (target "Compile" depends on it):
Building target "CoreCompile" completely.
Input file "C:\Users\Ludwo\AppData\Local\Temp\uwdnm5th.cs" is newer than output file "obj\Debug\Delta.Workflow.Common.pdb".
I'm building my projects using MSBuild 4.0. My projects are set to build with v3.5 TargetFrameworkVersion, unit tests projects are build with TargetFrameworkVersion set to v4.0. I tried to build it on different PC but the result is still the same. I also played with references in my projects. It seems to be like v4.0/v3.5 conflict, but I don't know how to fix it. Any ideas?
I found it. The root cause is wrong version of Workflow.targets file imported inside my workflow (.csproj) projects. Workflow.targets for .NET v4.0 was imported instead of v3.5. It should be related to projects upgrade from VS2008 to VS2010 I did some time ago.
I changed Workflow.targets Import from
<Import Project="$(MSBuildToolsPath)\Workflow.targets"/>
to
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.targets" />
Hope it helps someone...