If I run the code analysis in Visual Studio 2022 (on a c++ project) I get a XML and a SARIF file for every code file.
No I try to run the code analysis with MSBuild 2022:
MSBuild.exe solution.sln -p:Configuration=Release /p:RunCodeAnalysis=true
But with this call I only get the code analysis XML files and no SARIF files.
Any idea how to force MSBuild to create the SARIF files?
Try to use following command line:
cl.exe <file/project path> /analyze:autolog:ext .nativecodeanalysis.sarif
Or
cl.exe <file/project path> /analyze:autolog:ext .sarif
Though MSBuild.exe invokes cl.exe to compile, it seems creating a .sarif file is only available for directly using cl.exe and its command.
Here’s the related document: Analysis log options
/analyze:autolog:ext extension
Overrides the default extension of the analysis log files, and uses extension instead. If you use the .sarif extension, the log file uses the SARIF format instead of the default XML format.
https://docs.microsoft.com/en-us/answers/questions/512275/what-to-do-with-static-code-analysis-result-xml-fi.html describes a solution:
Add a Directory.build.props file to your Visual Studio solution:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>$(ClOptions) %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
</Project>
Now I can extend my MSBuild Command line on my CI-Server (TeamCity):
/p:RunCodeAnalysis=true /p:ClOptions="/analyze:log%20MyApp.nativecodeanalysis.combined.sarif" (I had to replace the whitespace with %20).
And one SARIF file is generated, or if you want one SARIF file for every code file:
/p:RunCodeAnalysis=true /p:CaOptions="/analyze:log:format:sarif"
If you want to add additional command line switches you have to separate it with %20:
/p:CaOptions=/analyze:log:format:sarif%20/analyze:log:compilerwarnings
BUT: If I activate Clang-Tidy in my Visual Studio project I get the error CLANGTIDY : error : no such file or directory: '/analyze:log' [clang-diagnostic-error] and CLANGTIDY : error : unable to handle compilation, expected exactly one compiler job in ... - Does someone has an idea about that (except disabling Clang-Tidy)?
Related
I'm generating MSBuild files (.csproj) using CMake.
At some time, I need to open the generated .csproj using Visual Studio, to do some debug and rebuild, etc...
I need my CMakeLists file to insert the following lines to the .csproj file:
<Target Name="AfterClean">
<Exec Command="..\my_clean_script.sh" />
</Target>
So, my_clean_script.sh is executed when I clean the project from Visual Studio to clean some external dependencies files (not part of the project) created by my CMakeLists file.
Any way to do that?
Thanks
try to use file(APPEND <filename> <content>...) ?
ref: https://cmake.org/cmake/help/latest/command/file.html#writing ?
add_custom_target(NSISTest_Preprocess SOURCES precompress.nsi)
add_custom_command(TARGET NSISTest_Preprocess POST_BUILD
COMMAND "${NSIS_PATH}" "...\\precompress.nsi")
The output name of the installer is defined in the nsi script. Now I'd like to simply run the installer. How do I specify what is supposed to happen when I use 'Debug->Start Debugging' or 'Debug->Start Without Debugging' in Visual Studio 2010?
I tried the CreateLaunchers.cmake script, which generates .user files, but I think it only works with add_executable.
I also tried target properties ARCHIVE_OUTPUT_NAME, LIBRARY_OUTPUT_NAME, RUNTIME_OUTPUT_NAME, but none of them have any effect.
The .user settings approach also works for custom targets. You could just add - if the path is known - the installer's .exe as a command the debugger should call with 'Debug->Start Debugging'.
VS2010Test-Debug.vcxproj.user.in
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommand>${_my_installer_path}</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
CMakeLists.txt
...
if (MSVC_VERSION GREATER 1599 AND
NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/NSISTest_Preprocess.vcxproj.user")
file(TO_NATIVE_PATH "[your installer's path goes here]" _my_installer_path)
configure_file(
"VS2010Test-Debug.vcxproj.user.in"
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/NSISTest_Preprocess.vcxproj.user"
)
file(
COPY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/NSISTest_Preprocess.vcxproj.user"
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}"
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
endif()
Background
I only copy/configure the file when it's not present, because VS does not handle outside changes to .user files very well
I have to make sure all file access rights are set properly, because your SCM may set a read-only flag (which is maintained by configure_file())
References
Setting the Visual Studio Debugger path using CMake
I'm trying to configure the YUICompressor.NET in my Visual Studio project.
As I've understood, I have to create a .proj file and add it to my solution. After that, I need to create a post-build event that will build this .proj file and I'll get my desired output (minified js/css files).
So, I have:
This .proj contains:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/MsBuild/2003">
<UsingTask TaskName="CssCompressorTask" AssemblyFile="\..\packages\YUICompressor.NET.MSBuild.2.7.0.0\lib\NET20\Yahoo.Yui.Compressor.Build.MsBuild.dll" />
<UsingTask TaskName="JavaScriptCompressorTask" AssemblyFile="\..\packages\YUICompressor.NET.MSBuild.2.7.0.0\lib\NET20\Yahoo.Yui.Compressor.Build.MsBuild.dll" />
<Target Name="Minify">
<ItemGroup>
<!-- Single files, listed in order of dependency -->
<CssFiles Include="Content\*.css"/>
<JavaScriptFiles Include="Scripts\*.js"/>
</ItemGroup>
<CssCompressorTask
SourceFiles="#(CssFiles)"
OutputFile="Content\min.css"
/>
<JavaScriptCompressorTask
SourceFiles="#(JavaScriptFiles)"
OutputFile="Scripts\min.js"
/>
</Target>
</Project>
I'm trying to build it as the following:
I'm getting the following error:
The command "msbuild C:\Users\Me\Desktop\MvcApplicationExample\MvcApplicationExample\YuiCompressorMsBuild.proj" exited with code 9009.
This error suggests that "msbuild" is not a valid command. So, how should I build this type of project? (I've followed this tutorial: youtube)
Thanks for any help.
As you said maybe the visual studio cannot find the MSBuild command, try with the following command instead
"$(MSBuildBinPath)\msbuild.exe"
That uses the complete path to msbuild.
Update (For futures references)
As the comment by Steve Medley, you should not forget the encapsulating quotes.
vfabre is correct to use $(MSBuildBinPath)\msbuild.exe but missing one thing. you should encapsulate that in quotes as there will 99.99% of the time be a space in the file path to msbuild
Well, one thing that might be a problem is that you want it as a Post-build event but it's set for the Pre-build command line.
I am trying to create a msbuild/VS2010 .targets file for flex, so that I can use .l files in Visual Studio 2010. So far, I have produced this:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<LFiles Include="$(MSBuildProjectDirectory)\**\*.l"/>
</ItemGroup>
<Target Name="Flex"
BeforeTargets="ClCompile"
Inputs="#(LFiles)"
Outputs="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')"
Returns="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')">
<Exec Command="flex.exe "-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c" "%(LFiles.FullPath)" 2>&1 | sed -e "s/. line \([0-9]\+\)/(\1)/" | sed -e s/\"//g"/>
</Target>
</Project>
I added this file to my project, using the Build Customizations... dialog. I then added my .l file, scan.l, and built the project - scan.l was created in the expected place, suggesting that the file name transformations are working. Next, I added scan.c to the project, and built the project again. The generated .c file compiled correctly, and the project linked. So it seems that things are basically working.
My expectation was that Visual Studio would then invoke flex if the .l file changes. The target's Inputs attribute includes the .l file, and its Outputs attribute includes the .c file, and Visual Studio can check whether the input is newer than the output. But in fact, this doesn't happen. If I just change the .l file and rebuild, Visual Studio tells me everything is up to date.
If I delete the .c file and build the project, the .c file is regenerated, just as I'd expect. But if I just change the .l file and build the project, nothing happens. In fact, in this case, msbuild doesn't even seem to run! If I delete the build log before building, Visual Studio tells me that everything is up to date, and no new build log is produced. This makes it rather hard for me to work out what might be going on.
This is my first go with msbuild, so I am probably doing something wrong. But what?
(N.B. my targets file might fall over with multiple .l files, or suffer from some other flaw(s) unrelated to the dependency checking issue - I am not bothered about any of this at this stage.)
To figure out the fix, I realised I could create a Visual Studio 2008 project with a .rules file, load it into Visual Studio 2010, let Visual Studio 2010 convert it automatically, and examine the result. So I did that.
To fix the problem, add an XML file with the same base name as the targets file. This one will do for this example:
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:transformCallback="Microsoft.Cpp.Dev10.ConvertPropertyCallback">
<ItemType
Name="Flex"
DisplayName="Flex" />
<FileExtension
Name="*.l"
ContentType="Flex" />
<ContentType
Name="Flex"
DisplayName="Flex"
ItemType="Flex" />
</ProjectSchemaDefinitions>
Next, refer to this file in the ItemGroup section. The .targets file is pretty small so here's the new version in its entirety:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml"></PropertyPageSchema>
<LFiles Include="$(MSBuildProjectDirectory)\**\*.l"/>
</ItemGroup>
<Target Name="Flex"
BeforeTargets="ClCompile"
Inputs="#(LFiles)"
Outputs="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')"
Returns="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')">
<Exec Command="flex.exe "-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c" "%(LFiles.FullPath)" 2>&1 | sed -e "s/. line \([0-9]\+\)/(\1)/" | sed -e s/\"//g"/>
</Target>
</Project>
Now reload the project, and visit the properties for the .l file. Select the new Flex option from the Item Type dropdown. This seems to prod Visual Studio into taking a little more care over the file.
I'm using the config file replacement feature of Visual Studio 2010's "Publish" functionality, as described in this article. I want to automate this using MSBuild/Hudson. Does anybody know how to do this?
I like how it works but if I cannot automate it I'll have to switch to XmlMassUpdate or similar.
Explanation
To transform your config file you'll have to execute the TransformWebConfig target.
This target takes two files Web.config and Web.$(Configuration).config and generates a Web.config. The generated file is the transformed version of the original one for the current configuration.
This file is generated in folder : obj\$(Configuration)\TransformWebConfig
Usage
You don't really explain what you want to achieve, so here a basic usage, a job that generates a transformed config file in a given folder.
Add the following piece in the end of your project file *.csproj after the import of Microsoft.WebApplication.targets
<PropertyGroup>
<!-- Directory where your web.config will be copied -->
<TransformedWebConfigDestination>$(MSBuildProjectDirectory)</TransformedWebConfigDestination>
</PropertyGroup>
<!--
This target transforms the web.config based on current configuration and
put the transformed files in $(TransformedWebConfigDestination) folder
-->
<Target Name="ConfigSubstitution">
<CallTarget Targets="TransformWebConfig"/>
<ItemGroup>
<TransformedWebConfig Include="obj\$(Configuration)\TransformWebConfig\Web.config"/>
</ItemGroup>
<!-- Copy the transformed web.config to the configured destination -->
<Copy SourceFiles="#(TransformedWebConfig)"
DestinationFolder="$(TransformedWebConfigDestination)"/>
</Target>
In Hudson you could add a Build step in your build, or create a dedicated job configured as follow:
MsBuild Build File : Your csproj file.
Command Line Arguments : /t:ConfigSubstitution /p:Platform=AnyCpu;Configuration=Test;TransformedWebConfigDestination=DestinationFolder
Edit your web project.csproj
under
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
Add -
<UseMsDeployExe>True</UseMsDeployExe>
Look at the Build output (make sure VS Tools - Options - Project & Solutions -Build & Run - MSBuild Output Verbosity - Detailed)
You should be able to see the msdeploy commands VS uses to produce the package. It's my understanding that VS actually uses Web Platform Pipeline API's and .target files to actually produce the deploy packages when building using MSBuild, and this command changes to use MsDeploy instead.
This stuff is so in need of documentation, its very frustrating.
I am using this in Hudson to target Release:
/Property:Configuration=Release
The exact settings are:
Build
MSBuild Version: msbuild-4 (configured to point to v4 msbuild)
MsBuild Build File: project_name.sln
Command Line Arguments: /Property:Configuration=Release
You can test this in your project directory by running something similar (as your .NET framework version may differ) to this:
%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\msbuild project.sln /Property:Configuration=Release