Source Control Binding, Part 2: SAK and SOURCE_CONTROL_SETTINGS_PROVIDER

In a previous post I shared one form of binding trouble, which had to do with MSSCCPRJ.scc location on disk. A side note there reminded me of another issue -

… The choice of binding location is controlled via a separate file – more in a future post.

- and lo, that future has just arrived.

Source Control (henceforth SC) info is maintained independently for projects and solutions. This by itself is understandable, as solutions can hold their own ‘solution items’. What’s less understandable is that some SC vendors try to apply the solution’s binding as a root to its projects, thus effectively pretending the solution has exclusive ownership over them – but that is an entirely different matter.

SC info amounts to 4 strings – SccProvider, SccProjectName, SccLocalPath and SccAuxPath, whose exact meaning can vary among SC vendors. These strings can be stored as fields in project/solution files, but that can make branching hard to handle properly – so it is highly preferable to store them externally, in a special file called MSSCCPRJ.scc.

When you do use MSSCCPRJ files (as you should) you’d see that the 4 SC fields include only  the string ‘SAK’. According to Alin Constantineasily the best online source on SC in Visual Studio – SAK probably stands for ‘Sumedh A. Kanetkar’ (a clear case of MZ envy). Anyway, it is just a flag that tells the IDE to look for the real SC bindings in the nearest MSSCCPRJ.

While MSSCCPRJ is opaque to the IDE, VS uses a host of its own files to store SC info – specifically project hint files (.vspscc) and solution hint files (.vssscc). Both files contain the field SOURCE_CONTROL_SETTINGS_PROVIDER, which can hold either ‘PROJECT’ or ‘PROVIDER’ – the latter meaning exactly that:

If the setting is "PROVIDER", VisualStudio expects your source control provider to create mssccprj.scc files that will contain the location in the scc database where the local project files are stored. VS will read in that case the bindings from the mssccprj.scc files.

As it turns out, the SAK declarations in the vcxproj/sln might clash with seemingly identical declarations in the vspscc/vssscc.

As I discovered some years ago, such a clash can cause some very thorny SC binding issues. Despite all sorts of online advice saying the contrary – I had to fix the hint files manually to contain ‘SOURCE_CONTROL_SETTINGS_PROVIDER = PROVIDER’, and thus be consistent with the project/solution files.

I was admittedly very hesitant about such manual modifications (and across half our dev machines, no less). Noting that Alin seems a top notch authority on SC apparatuses (apparati?) and that he’s quoted to be a heck of a nice guy, I simply mailed him and asked.

He replied within ~2 hours.

Hi Ofek,

Yes, the 2 settings are related.

Indeed, if the “SAK” strings are written in the project this means the real bindings can and will be provided by the source control provider and the setting in the vspscc files should be "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" I haven’t worked for source control in the last 5 years and I don’t remember exactly what all these are used for. At a quick look it seems the setting matters only for project files (not for solutions), and it seems to be used when opening just the project file from source control.

Anyway, I don’t recommend changing these settings manually – they really depend on the capabilities of your source control provider. Setting them incorrectly or not matching the reality will cause your projects to end up uncontrolled. I suggest using ChangeSourceControl dialog whenever you need to change the bindings.

Alin

[Note: Alin explicitly permitted the publication of this correspondence, verbatim].


<aside> It is nowhere near obvious that a knowledgeable guy such as Alin Constantin dedicates this much effort and time to help out, either in online articles, forum answers or email responses (on matters which he stopped working in years before!). Beyond the personal kudos to Alin, I gotta say I feel some wider kudos is in order to Microsoft for actively encouraging this culture. I personally had quite a few similar experiences with other (even senior) MS employees. I cannot say the same for other tech giants. </aside>

$(TargetDir) Bug, or: Where Did My PDB Go?

Edit: This is now a confirmed VS bug. Hope the Connect page would be updated when it is resolved.


Try this (if you weren’t bitten by this issue already):

1. Create a new C++ project – any project type will do – at a volume other than your VS installation, say under D:\code.

2. Open its property pages, and under Configuration Properties\ General\ Output Directory, type exactly: \bin\

image

3. Go to Linker/Debugging and inspect the PDB location. It gives the innocent looking: ‘$(TargetDir)$(TargetName).pdb’. Now edit it and expand the Macros pane to dig deeper:

image

Your PDBs are all going to be generated at a drive different than the project’s (and thus, probably different than where you intended).

This is definitely new to VS2010, and calls for a deeper peek. Turns out the calculations of these macros are visible, at %PROGRAM FILES% \MSBuild\ Microsoft.Cpp\ v4.0\ Microsoft.CommonCpp.targets:

<TargetPath Condition="’$(TargetPath)’ == ”" 
   $([System.IO.Path]::Combine($(ProjectDir),$(OutDir)
   $(TargetName)$(TargetExt)))
</TargetPath>  
<TargetDir Condition="’$(TargetDir)’==”"
   $([System.IO.Path]::GetDirectoryName(‘$(TargetPath)’))
</TargetDir>

This format is quite readable as pseudo-code, and brief C# experiment shows that this code on the inputs above still gives the relative path ‘\bin\’ for $(TargetDir).

System.Io.Path documentation says:

Relative paths specify a partial location: the current location is used as the starting point when locating a file specified with a relative path.

‘Current location’ is the location of the running executable – unless a different directory is explicitly set. Since the full path ‘C:\bin\’ is displayed at the expanded macro page, I suspect somewhere VS runs GetFullPath over the result of the Microsoft.CommonCpp.targets code, resulting in a path on the volume of the VS installation.

I can’t verify any of it, but a while ago I opened an MS Connect issue about it, which seem to have received little attention from MS till now (can’t say I blame them – they seem to be bombarded recently with bogus issues). I’ll update in this blog if any new info is available.