By default, code analysis is only done for projects which are compiled. So when I run MSBuild from the command line, it runs code analysis only for the first time. On subsequent calls, code analysis is skipped.
Background: I want to evaluate CA rules and see how many warnings there would be in our code when turning on a rule. For that I don't want to recompile everything - which takes some time - but just re-run the code analysis. How can you achieve this?
I am using Visual Studio 2013 and MSBuild 12.0.
Even explicitely switching on code analysis does not help:
msbuild DesktopBuild.proj /p:RunCodeAnalysis=true
It seems that
del /s *.lastcodeanalysissucceeded
msbuild DesktopBuild.proj /p:RunCodeAnalysis=true
seems to work. The first step causes code analysis to "forget" about the previous runs and the second step forces it to run for every project, even if code analysis is not enabled in a project. If running this repeatedly, the already compiled projects won't be compiled again, only the code analysis is re-run.
Simply set CodeAnalysisGenerateSuccessFile to false in the project file.
<PropertyGroup>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisGenerateSuccessFile>false</CodeAnalysisGenerateSuccessFile>
</PropertyGroup>
I would try using FxCopCmd.exe, it can be usually found in C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Static Analysis Tools\FxCop. It's used by CodeAnalysis in Visual Studio, you should be able to use it with proper parameters.
Related
I have a MSBuild .proj file that is executed by various people on various machines in the usual way, like msbuild.exe thingummy.proj The C# projects it compiles include .Net 4.5 features, so if you compile it with an early MSBuild that does not know about later .Nets, you'll get the "Invalid token '=' in class, struct, or interface member declaration" sorts of messages that are well documented elsewhere. (e.g. Invalid Token Errors when using MSBuild via Command Line but not on Visual Studio )
The immediate fix is to update your MSBuild to latest and make sure you are using the version of MSBuild that you think you are. But it would be a kindness to users if instead of getting an abstruse "Invalid token..." message (which is a bit "go figure..."), it instead said something like "MSBuild v16 or later required (yours is v4.7)" or something like that.
So what I am looking for is a MinimumMSBuildVersionRequired parameter or something like that to put at the top of my msbuild thingummy.proj file, so that at the start of the build process, MSBuild tests to see if the MSBuild that is running this script is new enough. I've looked all over but can't find a suitable candidate for that.
Is there a such a parameter that I can set in my .proj MSBuild script? Or some other workaround to give informative messages when running with inadequate MSBuild version?
OK, with thanks to input from #pavelanikhouski , this works:
At the top of my script, I add this:
<Project InitialTargets="MyInitialChecks" ...
'InitialTargets' is magic (must be exactly that). 'MyInitialChecks' is whatever I choose as the name of my checker target.
And then I add a checker target that looks like this:
<Target Name="MyInitialChecks" >
<Error Condition="$(MSBuildToolsVersion) < 15.0"
Text="The version of MSBuild being used for this build (v$(MSBuildToolsVersion)) is too early. v15.0 or later is required." />
</Target>
That does it up to and including Visual Studio 2017 and MSBuildToolsVersion v15.0.
As Pavel has pointed out, all bets are off when it comes to VS2019, because that no longer reports a MSBuildToolsVersion. See https://developercommunity.visualstudio.com/content/problem/404485/vs2019-msbuildtoolsversion-is-not-a-version.html
I am using Visual Stduio 2015 Community Edition. I have loaded a C# project and want to configure it to use shadow building, so that source files are not messed up with any binaries or intermediate build files. Tried to set the [output]/[intermediate output] directory paths of the C# project using the VS UI - the only UI-editable output path is the "bin" one and it doesn't accept MSBuild macros. Then I've unloaded the project and manually edited it. Also set the IntermediateOutputPath which is not available in the VS UI when using C# project, but when using C++ one all such kind of directories are editable.
Currently, the OutputPath is set to:
<OutputPath>$(SolutionDir)..\build_$(SolutionName)_$(Configuration)_$(Platform)\$(ProjectName)</OutputPath>
$(ProjectName) is empty for some reason. Tried $(TargetName) (it is not correct to use it but just for the test) but it is empty, too. Any suggestions?
Do not try to import Microsoft.CSharp.targets - like suggested in another answer.
First of all - it will lead to additional warning like
Warning MSB4011: "Microsoft.CSharp.targets" cannot be imported again. ...
But additionally to that if you try to edit pre-/post- build Visual studio will crash.
(Observed in Visual studio 2019, 16.7.7 version)
Better to use $(MSBuildProjectName) macro instead of $(ProjectName) - works identically.
The problem is that some of the MSBuild properties like ProjectName are set after the following line in your .csproj file.
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
After this line you can access all variables.
I have a project with maybe 200+ projects in it. It's an old bird. To make local builds faster, I ran a diagnostic build. Seems resolving assembly and project references is taking msbuild awhile. VS seems to do this fast, is there a way to get MSBuild to use a cache for these references, or to somehow resolve it faster?
It seems MSBuild wouldn't need to resolve the assembly reference(s) this often with an incremental build, right?
Is there a way to get MSBuild to report its internal dependency tree for this?
VS uses the same MSBuild engine to perform the build, so whatever performance you observe from VS, you should be able to achieve by starting build from command line using MSBuild.exe.
There are couple of points to keep in mind, that might explain difference in build speed between VS and command line:
If you build "Project Only" in VS, i.e. right click on the project node, select "Build Project (this)" from "Project Only" menu, then the build skips building any referenced projects. This is the fastest way to do incremental build, but you have to know ahead of time that all dependencies are up-to-date.
If you want to replicate this from command line, just pass parameter BuildProjectReferences=false. E.g:
msbuild myproject.csproj /p:BuildProjectReferences=false
The defaults for VS might be set for multi-proc build, which in many cases greatly increases build speed. However on command line, the defaults are always to perform single-proc build, so that would appear much slower than VS. Always pass in /m to the msbuild command line. E.g.:
msbuild MySolution.sln /m
I created a project in VS 2010. I want to convert it into VS 2013. When I build it, there is an error:
CA0053 Error Running Code Analysis CA0053 : Unable to load rule assembly 'c:\program files\microsoft visual studio 10.0\team tools\static analysis tools\fxcop\rules\globalizationrules.dll': Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
I disabled the "Enable Code Analysis in Build" and run, then it doesn't give me an error.
What is the importance of Enabling Code Analysis?
What will happen if disable the Code Analysis?
The CA0053 error you get is a known issue when converting from VS 2010 to VS 2012/13. I have listed up how to fix just that issue here: http://geekswithblogs.net/terje/archive/2012/08/18/how-to-fix-the-ca0053-error-in-code-analysis-in.aspx
The underlying cause is that your project is bound to the specific version, and should be version independent, caused by using an absolute path to the VS 2010 binaries.
You can change that in the project file, as described in the post.
If you want to do it manually, the basic steps are:
Open the project file (.csproj) in a text editor
Locate the lines for <CodeAnalysisRuleDirectories> and <CodeAnalysisRuleSetDirectories>
Replace them with the lines
shown here
<CodeAnalysisRuleDirectories>$(DevEnvDir)\..\..\Team Tools\Static Analysis Tools\FxCop\Rules</CodeAnalysisRuleDirectories>
and
<CodeAnalysisRuleSetDirectories>$(DevEnvDir)\..\..\Team Tools\Static Analysis Tools\Rule Sets</CodeAnalysisRuleSetDirectories>
As noted in the blog post, in many cases it seems you also can just delete the lines. You can try that first, if that doesn't work, do step 3 above.
What is the importance of Enabling Code Analysis?
So that your code gets analyzed.
What will happen if disable the Code Analysis?
Your code won't be analyzed.
Code analysis gives you hints about your code. It is a style and security check for the code you write.
See for more info MSDN: Code Analysis for Managed Code Overview and MSDN: Analyzing Managed Code Quality by Using Code Analysis.
When using Visual Stdio 2008, you can make a C++ project build with an internal tool rather than having the IDE invoke MSVC directly. This improves the consistency of builds across platforms if a cross-platform build system is used.
However, I cannot figure out how to do the same as a C# project. It would be possible to simply register it as a native project with C# sources, however, you lose some of the advantages gained through having a C# project. More importantly, it will mean that allowing a project to build both directly and with an external tool (which is sadly necessary) will require two separate projects, rather than merely creating an alternate build configuration to invoke the external tool.
Does anyone know if it's possible to prevent Visual Studio from invoking csc by itself and instead call an external tool?
EDIT: Apparently there has some misunderstanding. The goal here is not to compile anything outside of Visual Studio. Instead, it's to allow Visual Studio to serve as the IDE but not the build system. There is already a (Scons-based) build system capable of compiling the C# and C++ sources, and Visual Studio has been configured to invoke Scons for compilation of C++ projects. I'm trying to configure it so that when you hit the 'Build' button, it will invoke Scons for the C# projects as well as the C++ ones.
Edit: Your question is still answered using MSBuild(if you are simply looking to compile outside the IDE). The IDE(Visual Studios) is simply a "fancy" way of constructing the build files that are built by MSBuild. Visual Studios isn't building the files, it simply is invoking MSBuild which ships with the .NET Framework 2.0 and up which compiles your code based on the project file that you create. If Scons can read and process an MSBuild file then I'm sure you can invoke it to build your project. But considering the fact that C# is a Microsoft language, I think you will be hard-pressed to find a value-add in not using MSBuild since I'd assume both the language and build tool are very tuned to work together. - End Edit
You can use MSBuild to compile your C# project. If you open your .csproj file in a text editor you will see that it is a MSBuild file. If you want to write some C# outside of the IDE you can construct a build file using the .csproj file as a starting point and invoke MSBuild to compile your apps. The IDE is just a way of abstracting the editing of the MSBuild file away for you.
If you are really industrious you can create a set of custom tasks to do things in your custom build process like move files around and versioning. MSBuild Community Tasks are a great example of using custom code to do task for you during MSBuild.
Given all the other answers, what MSBuild does when either VS or MSBuild perform a build can be found in the Targets files that ship with .Net. These can be be found in the FrameWork directory on your system. In my case:
C:\Windows\Microsoft.NET\Framework64\v3.5
Contains Microsoft.Common.targets among others. This file contains the following snippit:
<!--
============================================================
Build
The main build entry point.
============================================================
-->
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Outputs="$(TargetPath)"/>
This means that redifining this Target you can make MSBuild an VS do anything you want. The top of the mentioned file contains an important messagge:
Microsoft.Common.targets
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.
This file defines the steps in the standard build process for .NET projects. It
contains all the steps that are common among the different .NET languages, such as
Visual Basic, C#, and Visual J#.
My suggestion would be to read all you can about MSBuild and it's build file syntax and try redifining the Build target in your project(s). My impression is that after reading up on MSBuild you'll probably find an easier way to meet your requierements. You can find an example of redifining a Target like this in one of the answers of this so question .
Edit:
How to redefine a target?
Redefining is essentially defining the same target 'after' it has been defined. So for instance in your .*proj file(s) define a Build Task after the <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> line that imports all targets needed to in this case build a C# project. An example could be
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="BeforeBuild"
Outputs="$(TargetPath)">
<Exec Command="nmake" />
</Target>
I found a question in the same direction here, where it is suggested to edit the registry. I am pretty sure there is no other way to change the compiler used by Visual Studio because there is no trace of csc.exe in any solution, config, csproj file or whatsoever, nor in the Visual Studio 9.0 folder / subfolders within the Program Files dir.
Registry locations can be found in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\74ACAA9F1F0087E4882A06A5E18D7D32
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\9055DA7481CC1024CB23A6109FD8FC9B
but those keys may differ dependng on your installation. Conclusion: changing the compiler used by VS seems next to impossible.
Addition: The following MSDN article deals with the same question for an custom C++ compiler, and Ed Dore's answer seems to confirm my theory that there's no way to choose an custom compiler for use within VS.
Under 'Tools' > 'External Tools' you should be able to define an outside tool to do activities for you. The Command should be the path to the executible for your external tool.
Hope this helps some.
You don't have to maintain different project files to build using an external tool. MSBuild is designed to build using the same project files that Visual Studio uses.
Here's an article that describes it.
Customize Your Builds in Visual Studio Using the Standalone MSBuild Tool
It's for VS2005, but should apply to VS2008 as well.
Looking through the answers, it seems clear to me that integrating scons into Visual Studio in a way that is compatible with the debugger and so on is not going to happen...
An option you might to consider, and I understand you don't want to change build systems, but bear with me, is to use a meta-build system, ie 'cmake'. http://www.cmake.org/
Cmake doeesn't actually build the project. What it does is to create build files for you, that you can use to build the project, and on Windows, the build files it creates for you are: Visual Studio project files. You can simply load those directly into your IDE, and compile, and use normally!
CMake is I feel very easy to use, and provides a high level of transparence and maintainability.
The exact same CMakeLists.txt files on linux will causes linux makefiles to be generated.
On mingw, they can generate mingw makefiles.
There are numerous generators available within cmake. The list is here:
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_Generators
http://springrts.com is a huge opensource rts game that used to use scons as its cross-platform build system and now uses cmake.
I understand that you don't really want to have to change build systems, so it is a medium to long term solution.
Cmake is in any case one more option, to add to those of using a custom build tool, or using msbuild, or running the scons build from the commandline by hand.
Edit your project file and update the CscToolPath keys to point to the directory containing your tool and add CscToolExe keys that holds the name of the directory:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|.NET 3.5' ">
.
.
.
<CscToolPath>path\to\custom\tool\directory</CscToolPath>
<CscToolExe>exe name</CscToolExe>
.
.
.
</PropertyGroup>
I have not tested this, and the CscToolExe key may cause problems, in which case I would simply rename the external tool executable to "csc.exe".
You can build your solution from the command line like this:
C:\WINDOWS\Microsoft.NET\Framework\v3.5>msbuild.exe "C:\path\Your Solution.sln"