Changing default APK output to include version in the name using MSBuild - xamarin

when building an APK using MSBuild I would like to change the output apk name to include the version number
so
android:versionName="3.1.5"
would end up like:
MyAndroidApp-3.1.5.apk
i tried to do a post-build step where i try to copy the apk to a different name , but there aren't any macros in the post build step that has the version (that i can see)
When calling
MSBuild .\trunk\TaxiTabletUniversal.Droid.MyAndroidProject /t:SignAndroidPackage /p:Configuration=Release
the output apk ends up with the name:
company_name.mypackage_name-Signed.apk
In the Android Package Signing setting i can only specify the keystore and paswords, but no output name.
I would like the output name to pickup the versionName in the
AndroidManifest.xml
file

Changing default APK output to include version in the name using
MSBuild
Sorry but the answer could be negative, as I know MSBuild itself doesn't have the ability to read data like Version-number from AndroidManifest.xml. In other words, it's not supported by msbuild.
MSBuild can access any property defined in project file or imported targets file, but it can't access AndroidManifest.xml file. And there's no official msbuild task can to this for us, so if you do need this behavior, we have to code ourselves to read the version info from that xml file. Topics about this: one, two, three...(Too many topics online talk about this, so I don't talk too much here, if you meet some issue about coding that, let me know:-
))
Here're two possible ways after that coding:
1.Create a .exe file with code to execute the renaming job, and call the .exe in a post-build event
2.Write a custom task named CustomTask, and add this script into the project file to call this task after build or SignAndroidPackage target.
<UsingTask TaskName="CustomTask.CustomTask"
AssemblyFile="path\CustomTask.dll"/>
<!--Maybe it should be AfterTargets="SignAndroidPackage"-->
<Target Name="CustomTarget" AfterTargets="Build">
<CustomTask/>
</Target>
May it makes some help.

Related

Running SPIR-V compiler as pre-build event in VS2017 if only the shader code was modified

So I've look at a few questions here which popped up after a search, but I still haven't managed to get this to work.
My project has two files, main.cpp and shader.comp.
The shader needs to be compiled before the main program is ran and I have a small .bat script that does just that. It's set to run as a pre-build event.
However, if I edit shader.comp and leave main.cpp unmodified since I last ran the project, there is no need to rebuild the project (according to VS anyway), so there is no need to run any pre-build events and my shader doesn't get compiled.
Is there a way to tell VS2017 (or VS2019) that if some file is modified, then run something, or at least a way to add an arbitrary file to list of files that VS checks against when deciding whether to run the build or not?
I've tried setting "Exclude from build" to "No" in the file properties, but no matter what "Item type" I choose, editing just the shader won't trigger the rebuild.
It's possible to define the shader that needs to be compiled as Custom Build Tool in the properties of the file (as Item Type). This will open another menu in the properties where cmd script and similar can be written.
In this particular case, value for Command Line was:
glslangValidator.exe -V -o "%(RootDir)%(Directory)%(Filename).spv" "%(FullPath)"
And the Outputs:
%(RootDir)%(Directory)%(Filename).spv
In short, if file defined in Outputs doesn't exists or is older than the owner of this property (the file that needs to be compiled), the Command Line argument will be ran in cmd.
Official documentation has more info on this.
Maybe you can get some help from this issue. You can specify the files for VS Up-To-Date check.
<Project...>
...
<ItemGroup>
<UpToDateCheckInput Include="shader.comp" /> <!--when this file is in the project folder-->
<!--<UpToDateCheckInput Include="path/shader.comp" />-->
</ItemGroup>
</Project>
And this script into your project file. Then if there's any change to shader.comp file,VS will build your project.
Note: In this way, if you only change the shader.comp file , but not change the source file(xx,cpp), the build will start but vs will skip the compile target of C++ source code. Only when you modify the source code main.cpp, then VS will run the pre-build event and compile the code. Let me know if it's what you want, hope i didn't misunderstand anything :)

MsBuild failing to build package, but okay with "just" building or building package after a "normal" build

I have a problem with building a Web Deployment Package from a Web Application Project (within a solution containing multiple projects, as well as multiple web applications).
This actually works
I can build the project just fine from the command line if I use this command for example:
msbuild D:\PathTo\Solution\Project\Project.csproj
/fl /flp:logfile="D:\buildadventures\Build.log";errorsonly;verbosity=diagnostic
/p:SolutionDir="D:\PathTo\Project\\";Configuration=Release;Platform=AnyCpu
But this does not work
But when I try the same command just a bit differently to build a deployment package for me like that:
msbuild D:\PathTo\Solution\Project\Project.csproj
/fl /flp:logfile="D:\buildadventures\Build.log";errorsonly;verbosity=diagnostic
/T:Package
/p:SolutionDir="D:\PathTo\Solution\\";Configuration=Release;Platform=AnyCpu;
PackageLocation="D:\buildadventures\Project.zip";
AutoParameterizationWebConfigConnectionStrings=false
...it fails miserably, spitting out hundreds of errors of the "The type or namespace name '' does not exist"-kind
And why does it work this way?
The strange thing however is, the second command I posted works fine if the first one was executed prior to that.
I suppose the tasks executed when doing a "normal" build are different to those that are executed when building a package, now I wonder in what way they are different.
What symptomatically seems to cause it
I noticed that in the project file of the project I want to build a package of contains a custom section towards the end:
<PropertyGroup>
<PreBuildEvent>
cscript $(ProjectDir)SvnRevision\svnrevision.vbs $(ProjectDir) $(ProjectDir)Version.cs
nuget install "$(ProjectDir)packages.config" -o "$(SolutionDir)Packages"
</PreBuildEvent>
</PropertyGroup>
This seems to be responsible for that difference; if I do a "normal" build I can see that after that a new "Packages" directory was created in my solution folder.
However, as you might have guessed, that directory is missing when I try to do the package creation command. I also do not run into this problem if I let Visual Studio create the package for me.
Maybe I do have to change the project file or passed properties to carry over this behavior for my package creation, too?
Or Is there maybe a way to force a "normal" build and then just append package creation to that somehow?
Silly me.
I was able to circumvent this issue by just calling multiple targets in my msbuild command such as that:
msbuild D:\PathTo\Solution\Project\Project.csproj
/fl /flp:logfile="D:\buildadventures\Build.log";errorsonly;verbosity=diagnostic
/t:Build;Package
/p:SolutionDir="D:\PathTo\Solution\\";Configuration=Release;Platform=AnyCpu;
PackageLocation="D:\buildadventures\Project.zip";
AutoParameterizationWebConfigConnectionStrings=false

external file to hold msbuild tasks

I have created some ms build tasks for my VS project.
Rather than having to update the VS Project file with each of the tasks, is it possible to create an external file to hold the build tasks and reference it via the main project file?
Also, I have seen with nant, that you can create .bat file to run nant tasks. Is it possible to do similar with msbuild?
Yes. You can use the Import task:
<Import Project="PathToMyIncludeFile\Include.proj" />
And yes you can create a batch file to run msbuild. The syntax is
msbuild <project> /t:target[;target] /p:propertyname=propertyvalue
Where the targets are defined in the msbuild file and the properties are any properties defined in the file. If you don't specify a target, the default that is defined in the msbuild file element will be run. Here are a couple of examples:
So to run your build with the Clean, and Compile targets:
msbuild myproject.proj /t:Clean;Compile
Or to run your build with a target of Compile and a release configuration:
msbuild myproject.proj /t:Compile /p:Configuration=Release
Or to run your build with the default target and a set a version property:
msbuild myproject.proj /p:Version=2.0.0.1
Command line parameters take precedence over the values defined in the file. So in the example above if you had the version defined in the file as:
<PropertyGroup>
<Version>1.0.0.0</Version>
<PropertyGroup>
The build would run with a configured version of 2.0.0.1
As usual, check out MSDN for more info.

Project file with just files and no built output

How can I make a project file (VS 2008) that just has some data files in and has no built output?
I can make an empty project and add my data files to it (which get copied to the output folder
), but it produces an EmptyProject.dll after I do a build. I want just my data files in the output directory and not some empty DLL or EXE.
I want the data files to be the only thing in this project as the project will be shared in a couple of solutions.
Our application is C#. All of our normal code projects are C#.
The data files are schemas (XSD). I want these schemas to be in the output folder, but I don't want them included with an existing project. I would like a project named "Schemas" that has nothing in except the XSD files and does nothing except copy the XSD files to the output folder. I would like this in a project file so that the same schemas project can be referenced in multiple solutions.
I don't know of a way to suppress the creation of the .dll file. BUT... here's an easy workaround. In the project properties, Build Events tab, write a Post-build event command line that will delete the file. Something like:
del path\filename.dll
Expanding on Scott's answer:
Create a new project of type Empty project
In Properties->Application, change Output type to Class Library
In Properties->Build->Advanced, change Debug Info to None
In Properties->Build Events, set the Post-build event command line to del $(TargetPath)
That way, the project creates only a DLL, which gets deleted. At the same time, the "copy to output directory" settings on your data files is respected.
Possibly another way is editing the csproj file by replacing this:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
with this:
<Target Name="Build" />
<Target Name="Rebuild" />
Then builds don't create anything. It worked for me.
Same general idea should work for any xxproj file. Just replace the <Import Project...> tags with the <Target...> tags.
I'd be interested in knowing if this causes any issues or doesn't work for anyone.
What do you need a project for if you're not building it?
You can use solution folders to "store" files...
Why not just disable building this project for all configurations (use the Configuration Manager) - that way it won't build.
Great stuff. Expanding on Scott > Daniel's answer:
Safe to remove all References and Properties (AssemblyInfo.cs)
If it is a node/grunt/gulp project then you can invoke it in your Build Events > *Post-build event command line * eg: gulp build or gulp clean
Perhaps you can add removal or obj and bin output folders to your node/grunt/gulp clean scripts mitigating the need for del $(TargetPath)

Calling batch/script files from VC6/VC2005/VC2008 project files

Is there a way to invoke an external script or batch file from VC6 (and later) project files?
I have a background process that I need to kill before attempting to build certain projects (DLLS, executables) and haven't found a way to successfully do so from the project itself. I'd like simply to call a batch file with a taskkill command in it.
(Yes, I could run the batch file from a command line before building the projects, but I don't always remember to do so and having it done automatically would be more convenient and less irritating for the whole development team.)
You can create a utility project (configuration type: Utility in the project property pages) that has a post build event. You then call the batch file from that Post-Build event. If I remember correctly, utility configuration appeared in VS2005. But I believe the same can be achieved with another type of configuration on VC6.
Here is an example of a setup (this is the text of the Command Line property of the Post-Build Event):
set solutionDir=$(SolutionDir)
set platformName=$(PlatformName)
set configurationName=$(ConfigurationName)
call $(SolutionDir)PostBuild.bat
As you can see, you have all the flexibility of customizing the batch environment based on VisualStudio macros.
If you want to have this batch file called every time you build, add a dependency to the requiring project (your main executable or dll project for example). You can add your batch file to the solution items for convenient access (right-click on the solution and select Add -> Existing Item...).
You can even invoke the build command on this utility project to force the execution of the batch file.
At work we have a similar setup to start our unit tests each time a build is triggered.
You could invoke it from a custom build step or a build event.
At least for C# in Visual Studio 2008, you can open the project file and find within the file the following comment:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
Uncomment the one that works best for you, in this case the "BeforeBuild" item. Then substitute your batch file for the one I have here:
<Target Name="BeforeBuild">
<Exec Command="MyBatchFile.bat" />
</Target>
That's all there is to it; whenever you build that project, this will take place each and every time.
That said, I do not know if this works the same for VS 2005 or, especially, VC6. YMMV!

Resources