Set `AfterClean` to csproj file generated by CMake - visual-studio

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 ?

Related

Visual Studio 2019 not picking up CS generated files

I have created dot net core dll project. CS files for this project will be files generated by tool (Apache Thrift compiler) but output dll is not picking up generated file. I have added the pre build set to generate the file.
Repro Steps:
Build solution
Open the ThriftSample.dll with object brower. (Delete the generated cs files and bin, com and obj folder.)
Actual: Nothing is there in ThriftSample.dll
Expected: Generated CS code should be there.
Note: I have checked CS file is generated. Attached is the sample project.(
https://onedrive.live.com/?cid=aef000afffca3540&id=AEF000AFFFCA3540%21144&authkey=!AAlMaW2IqIt6l1k
)
Refer: Is there a .NET Core CLI pre before build task?
The "default items" as the .NET SDK calls it are part of the static evaluation of the project file - before any target is run. So you'll need a target that is run before the #(Compile) items are needed.
The trick is to include files added to the filesystem after the custom tool is run. This can be done by re-scanning all files and excluding those already part of the project inside a target that is run before the build:
<Target Name="GenerateSomeFiles" BeforeTargets="BeforeBuild">
<Exec Command="dotnet my-tool" />
<ItemGroup>
<Compile Include="**/*$(DefaultLanguageSourceExtension)"
Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(BaseIntermediateOutputPath)**;$(BaseOutputPath)**;#(Compile)" />
</ItemGroup>
</Target>

How do I use an MSBuild file from Visual Studio 2012?

I have a simple MSBuild file that I'm learning with.
Here it is:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Clean" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{D5A16164-962E-4A6D-9382-240F31AB6C50}</ProjectGuid>
</PropertyGroup>
<Target Name="Clean">
<ItemGroup>
<BinFiles Include="bin\*.*" />
<fff Include="f\*.*" />
</ItemGroup>
<Delete Files="#(BinFiles)" />
<Delete Files="#(fff)" />
</Target>
</Project>
Now I want to include this in a Visual Studio solution and be able to run the "clean" target from Visual Studio 2012. I tried naming it testproject.msbuildproj like the internet seems to suggest "works", but it doesn't work. When I run the clean command I just get "unexpected error".
If I rename the project to testproject.csproj, it does some unintuitive things like creating compilation directories, but it does actually run my clean command properly. However, this is undesireable because it creates obj and bin/x86/debug type directories. It also looks goofy in Visual Studio because it still gives the References drop down.
How can I use just a plain vanilla MSBuild project from Visual Studio without random errors or false assumptions?
Note I only am having a problem with this from Visual Studio. Using msbuild from the command line it works perfectly
Visual Studio creates bin / obj folders when it opens csproj file. When you click Build / Rebuild / Clean it just uses appropriate targets from the project file.
You cannot stop VS from creating these folders, but you can ask it to create them in say temp folder by setting appropriate properties - refer this MSDN article for details.
So the steps are to rename your project to csproj, and add the following lines into project:
<PropertyGroup>
<OutputPath>$(Temp)\bin</OutputPath>
<IntermediateOutputPath>$(Temp)\obj</IntermediateOutputPath>
</PropertyGroup>
I usually use a bit different approach to work with MSBUILD files from VS:
I use regular csproj file with removed Import ... CSharp.targets part as pure container for my Build projects.
I add actual build files with targets and logic, and all properties, necessary artifacts like XSLT etc using "Include into project", so I can manage hierarchy and change any file from within VS.Net.
I redefine Build / Rebuild targets in csproj file for whatever I need, for example Build may contain minimum output, and while rebuild diagnostic one.
Like this:
<Target Name="Build">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe Builds\build.proj /t:Build /v:m" />
</Target>
<Target Name="Rebuild">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe Builds\build.proj /t:Build /v:d" />
</Target>

Use different pre-build events for different build configurations in Visual Studio

Is it possible to use different pre-build events for different build configurations in Visual Studio?
For example, I'd like both a release configuration for a beta & live system and have the relevant app.[type].config get copied to app.config before it is compiled.
At the moment the configuration settings are baked into the .settings file, using the settings from the default app.config file.
Or just put the Condition on your target ... eg.,
Condition="'$(Configuration)' == 'Debug'"
.. or on your task.
If you're using Visual Studio VB/C# simple post build events, you can hand-edit the project file to put such conditions on the PreBuildEvent/PostBuildEvent property tags; and repeat the tags for Release.
Dan (msbuild dev)
You can do this in a couple of ways, depending on your exact situation:
Option 1: Check the $(ConfigurationName) variable in your pre-build script, like so:
IF EXISTS $(ProjectDir)app.$(ConfigurationName).config
COPY $(ProjectDir)app.$(ConfigurationName).config $(ProjectDir)app.config
Option 2: Add a "BeforeCompile" MSBuild target to your project file:
<Target Name="BeforeBuild">
<!-- MSBuild Script here -->
</Target>
Option 3: Use configuration file transformations; this VSIX plug-in adds the web.config transform features to non-web projects. These are XSLT files that let you rewrite your config files on build (unlike web projects, where it happens on publish.)
To use different build events for different configuration in visual studio, open the cs proj file of the project. in the pre build section
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Condition="'$(Configuration)'=='Release'" Command="echo Release" />
<Exec Condition="'$(Configuration)'=='Debug'" Command="echo Debug" />
</Target>
The command in "Command" parameter will only execute if this condition is met.

How can I exclude a project from a build in MSBuild?

I need to build a solution, but exclude one project. How should I do it?
I searched a lot about this issue, but nothing could help.
An ItemGroup section rises the following exception:
Invalid element . Unknown task or datatype.
PropertyGroup also rises the exception.
Below is my code sample:
<project name="TI 8.1.6 build script">
<ItemGroup>
<Solution Include="${ROOT}\Core\TI Core.sln" Exclude="${ROOT}\Utilities\DTS Indexing Service\Tdi.Origami.IndexUpdaterServiceSetup\Tdi.Origami.IndexUpdaterServiceSetup.wixproj"/>
</ItemGroup>
...
</project>
How can I do this?
You can exclude projects at the solution level for a specific build configuration by using the Configuration Manager Dialog in Visual Studio:
Then you can simply invoke msbuild on the solution file specifying the build configuration to use:
msbuild /property:Configuration=Release MySolution.sln
The solution suggested by Enrico is the most versatile solution that would work always. An alternative solution might be to use a <MSBuild> task directly. This will work for you if you have all your project files under a particular directory, or be able to easily enumerate all projects you want to build (i.e. number of projects in your solution is not very big).
For example, this MSBuild file will build every project under your current directory except for a specific project:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<MyProjectReferences Include="**\*.*proj" />
<MyProjectReferences Exclude="Utilities\DTS Indexing Service\Tdi.Origami.IndexUpdaterServiceSetup\Tdi.Origami.IndexUpdaterServiceSetup.wixproj" />
</ItemGroup>
<Target Name="BuildAllExceptWixProject">
<MSBuild Projects="#(MyProjectReferences)" Targets="Build" />
</Target>
</Project>
Then you can build that using command line msbuild <myproject> /t:BuildAllExceptWixProject
In your solution file (.sln), remove the Build.0 entries. For example:
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyProject", "MyProject.vcxproj", "{2281D9E7-5261-433D-BB04-176A61500CA3}"
EndProject
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2281D9E7-5261-433D-BB04-176A61500CA3}.Debug|x86.Build.0 = Debug|x64
If you delete this "Build.0" entry, it will load in the solution fine, but will not be built, either through the GUI or via external MSBuild.
Since VS 2019 and MSBuild 16.7, the right way is to use Solution filters. Ref
create a master.proj file:
in another ItemGroup add DefaultExclude properties for programs - put it in front of the solution
-- BA was Canadian
Configuration=Release
Release
drop the master.proj into the directory with the programs and msbuild the master.proj
compiles everything except... that HelloWorld

Running FxCop directly through VS project file

I am interested in setting up FxCop to run on each of our VS .csproj files in our developing environment by calling it as a target in the .csproj file itself without creating a separate MSBuild file for the project. Is this
<Target Name="AfterBuild">
<Exec Command=""C:\Program Files\Microsoft FxCop\FxCopCmd.exe" /searchgac /p:FxCopProject.fxcop /out:FxCopOutput.xml" ContinueOnError="true">
</Exec>
</Target>
possible to get working in one way or another being included at the tail end of my .csproj file?
I think you're looking for the post-build event.
Right Click the Project
Click Properties
Go to the "Build Events" Tab
Add the command line to the "Post-build event command line" box.
The following should work - paste it anywhere at just under the node level:
<PropertyGroup>
<PostBuildEvent>"%25ProgramFiles%25\Microsoft FxCop 1.36\FxCopCmd.exe" /p:$(SolutionDir)Bank.FxCop /o:$(TargetDir)FxCopResults.xml /d:"%25ProgramFiles%25\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies"
</PropertyGroup>
Note the /d parameter I'm using to point to where my project is using additional assemblies (in this case, the MSTest unit testing stuff).

Resources