Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable MSBuild's <RegisterOutput> target on a per-user basis?

Tags:

msbuild

I like to do my development as a normal (non-Admin) user. Our VS2010 project build fails with "Failed to register output. Please try enabling Per-user Redirection or register the component from a command prompt with elevated permissions."

Since I'm not at liberty to change the project file, is there any way that I can add user-specific MSBuild targets or properties that disable this step on a specific machine, or for a specific user? I'd prefer not to hack on the core MSBuild files.

I don't want to change the project file because I might then accidentally check it back in. Nor do I want to hack on the MSBuild core files, because they might get overwritten by a service pack.

Given that the Visual C++ project files (and associated .targets and .props files) have about a million places to alter the build order and to import arbitrary files, I was hoping for something along those lines.

MSBuild imports/evaluates the project file as follows (I've only looked down the branches that interest me):

Foo.vcxproj
  Microsoft.Cpp.Default.props
  Microsoft.Cpp.props
  $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props
  Microsoft.Cpp.targets
    Microsoft.Cpp.$(Platform).targets
      ImportBefore\*
      Microsoft.CppCommon.targets

The "RegisterOutput" target is defined in Microsoft.CppCommon.targets. I was hoping to replace this by putting a do-nothing "RegisterOutput" target in $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props, which is %LOCALAPPDATA%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props (UserRootDir is set in Microsoft.Cpp.Default.props if it's not already set).

Unfortunately, MSBuild uses the last-defined target, which means that mine gets overridden by the built-in one.

Alternatively, I could attempt to set the %(Link.RegisterOutput) metadata, but I'd have to do that on all Link items. Any idea how to do that, or even if it'll work?

madgnome suggested that I could do something in the .vcxproj.user file. Unfortunately, that gets included right at the beginning of the build process, which means that replacing the target won't work.

like image 445
Roger Lipscombe Avatar asked May 05 '10 12:05

Roger Lipscombe


People also ask

Will MSBuild compile a file without any target?

If there are no initial targets, default targets, or command-line targets, then MSBuild runs the first target it encounters in the project file or any imported project files.

What is MSBuild target?

A target element can have both Inputs and Outputs attributes, indicating what items the target expects as input, and what items it produces as output. If all output items are up-to-date, MSBuild skips the target, which significantly improves the build speed. This is called an incremental build of the target.

What is target file in visual studio?

targets files that contain items, properties, targets, and tasks for common scenarios. These files are automatically imported into most Visual Studio project files to simplify maintenance and readability. Projects typically import one or more . targets files to define their build process.

How do I create a .props file?

Create a properties fileIn Oracle Policy Modeling, select the Properties folder in the Project Explorer. Right-click and select Add New Properties File. A new properties file will be added to your project. The new file will be selected and highlighted in the list.


1 Answers

Final tested solution

RegisterOutput is called during link process defined by $(BuildLinkTargets) (Microsoft.CppBuild.targets) as follow :

<BuildLinkTargets Condition="'$(ConfigurationType)'!='Utility'">
  $(BuildLinkTargets);
  _Link;
  _ALink;
  _Manifest;
  RegisterOutput;
  _XdcMake;
  _BscMake;
</BuildLinkTargets>

If you dont want to execute RegisterOutput you just have to delete this step in the definition of BuildLinkTargets :

<PropertyGroup>
    <BuildLinkTargets Condition="'$(ConfigurationType)'!='Utility'">
      $(BuildLinkTargets);
      _Link;
      _ALink;
      _Manifest;
      _XdcMake;
      _BscMake;
    </BuildLinkTargets>
  • If you dont want to execute RegisterOutput for one project, you need to override it in the file : PROJECT_NAME.vcxproj.user (next to your project file, this file is user and project specific)
  • If you never want to execute RegisterOutput in all your project, you need to override it in the file : $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props (this file is user specific)
like image 94
Julien Hoarau Avatar answered Oct 04 '22 21:10

Julien Hoarau