MSBUild script to read VCS settings - msbuild

Using MSBuild script, can I read my VCS root settings?
Suppose I have two VCS settings for my TeamCity Build Configuration.
1. VCS Root Name is VCSId1 and Root is $/Source/Dev/Project1
2. VCS Root Name is VCSId2 and Root is $/Source/Dev/Project2
Can i read VCSId1 and its root using MSBuild script?

You can add custom build parameter like described here. For example MyRoot1 with value $/Source/Dev/Project1, then you can use it in VCS settings, specifying %MyRoot1% in Root field.
To pass it to you msbuild script you can write /p:Root=%MyRoot1% in Command line parameters: field from MsBuild Build step. After that it could be accessable in msbuild script as $(Root) property.

Related

MSBuild output in subfolder for each targetframework when using OutDir

When using the new SDK style csproj format, it is possible to use a <targetframeworks> element for a semicolon-separated list of target frameworks to build the project for.
This results in one subfolder per target framework in the build output folder:
However, when passing the OutDir property on the msbuild command line, it does NOT create the subfolders, and the built assemblies are all placed in the same folder.
Command line that works, but doesn't allow output location:
msbuild projectfile.csproj
Command line that selects output directory, but places built assemblies in same folder (effectively overwriting the target framework assemblies that are built first):
msbuild projectfile.csproj /p:OutDir=buildtemp
Is there a way to place the build output in a non-default folder while still retaining the targetframwork subfolders?
The property that is now used is OutputPath, however setting it from the CLI makes it a global property and overrules the automatic appending of the output path. The workaround is to make an intermediate property that is global and consume it from the project.
Add this to your project file inside a PropertyGroup:
<OutputPath>$(BaseOutputPath)</OutputPath>
Then you can set this property globally when calling the build command:
martin.ullrich#martins-imac:~/tmp$ dotnet build /p:BaseOutputPath=bin/foo
tmp -> /Users/martin.ullrich/tmp/bin/foo/netstandard1.4/tmp.dll
tmp -> /Users/martin.ullrich/tmp/bin/foo/netstandard1.6/tmp.dll
The problem here is that the SDK tries to change the OutputPath property based on TargetFramework and AppendTargetFrameworkToOutputPath. But if the value is specified via CLI, the project logic cannot overwrite it.
Also note that BaseOutputPath is actually used in the SDK defaults (defaulted to bin\), but it will try to append the configuration name by default..

Can I specify fileloggerparameters in msbuild project file

I see that you can use the /fileLogger and /fileloggerparameters command line arguments in msbuild to specify things like the location of the log file. Is there any way to specify this information in the Project or PropertyGroup section of the project file? I have all my other project properties imported via an include file. I really don't want to have to one set of properties in an include file and then another set that is specified on the command line.
As far as I'm aware just VC projects has ability log build into separate files. But you have to build it through devenv :-(
and you don't have control over other logging parameters.
Microsoft.Cpp.Default.props
<ItemDefinitionGroup>
<BuildLog>
<Path>$(IntDir)\$(MSBuildProjectName).log</Path>
</BuildLog>
</ItemDefinitionGroup>
Other ugly way is to execute build of each project via
<Exec Command="msbuild.exe project /fl /flp...." />
I guess you want to avid it.
I'm think it could be possible to create custom distributed file logger to do this but I sill don't have it working properly.

How to build csproj files which exist in different workspace/folder in source control but are in the same solution

I have build definition which builds this single solution in source control:
$/MyTeamProject/Dev
So, I use this mapping on the 'Workspace' tab for the build definition:
Source Control Folder: $/MyTeamProject/Dev
Build Agent Folder: $(SourceDir)\Dev
I added a few more projects to this same solution. These other projects exist in a different branch/folder root in source control:
$/MyTeamProject/MyProductName/Dev
So, I added this to the Workspace for the same build definition:
Source Control Folder: $/MyTeamProject/MyProductName/Dev/MyCsProjFolderRoot
Build Agent Folder: $(SourceDir)\MyProductName\Dev\MyCsProjFolderRoot
Build fails with:
C:\Dev\Sources\Dev\AllProjects.sln.metaproj: The project file "C:\Dev\Sources\Dev\..\MyteamProject\MyProduct\Dev\MyCsProjFolderRoot\MyProj.csproj" was not found.
On the build machine, I see the sources downloaded correctly in the structure I expect, but obviously the build doesn't agree.
I reviewed this question: Project file was not found however I am still unclear how to implement this. I am also confused that on the Workspace tab, there is a 'Browse For Folder' button for Build Agent Folder which says 'Please select a local folder.'
Am I going about this all wrong? Do I really need to select a local folder for the Build Agent Folder? (or does that just mean it must be not be a UNC folder - it must be mapped?)?
Solved. It was indeed that the Solution had relative reference to the projects and my workspace mapping wasn't reflecting this exactly.

Use path system environment variable in MSBuild exec task

I'm calling an external tool to do some post processing in my build sequence using the Exec task in MSBuild. When I update the tool to a new version the name of the directory of the executable changes, but the directory is added to the system PATH variable. Is it possible to use the system PATH variable in MSBuild? I tried the following code but it does not work:
<Exec Command=""$(PATH)\mytool.exe" />
If the directory has been added to the PATH variable, I would expect that the file path would be resolved automatically. I.e. you should be able to use:
<Exec Command="mytool.exe"/>
Maybe first check if the resolution is working ok by opening up a command prompt, cd'ing to some root directory that is different to where the 'mytool.exe' lives, and see if it is resolved when you simply enter "mytool.exe" at the prompt.

MSBuild: override path to .user file

We have many standard .vcxproj files that we use MSBuild to build. For certain properties and targets we need a .vcxproj.user file to override the properties that are specific to the build in progress.
In order to use the same build process in the development environment as the build machine, we'd like to specify the path to the .vcxproj.user as a different directory to the .vcxproj file, so the build process can generate the file it needs in a separate directory without disturbing the user's own settings.
I've found very little documentation on where msbuild looks for the .user file, or if it is even possible to specify the path?
Path *.user file for cpp projects is specified in C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.Cpp.Default.props
<MSBuildAllProjects Condition="Exists('$(MSBuildProjectFullPath).user')">$(MSBuildAllProjects);$(MSBuildProjectFullPath).user</MSBuildAllProjects>
It is intended to specify custom user settings (for example you can specify app to run in debug) and couldn't be changed.
To change build process you can use CustomBeforeMicrosoftCommonTargets. You can create your own *.targets file which will imports special properties/targets, change build process to make some preprocessing actions and so on. I've wrote an example for AfterTargets here. All you need is to implement custom build logic and change registration to BeforeTargets.