What's the difference between these two files, and which elements should go in which?
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
I too came to this page hoping to find an answer about what's the difference. But alas that information is not here. Fortunately after a slightly long web search, I came across this blog post from 2010 which states the following:
Typically, imports have the ".props" or ".targets" extension. MSBuild does not really care what the extension is, and considers these to all be just regular MSBuild project files. By convention, the extensions imply that a ".props" file contains property definitions (and/or items and definitions), and a ".targets" file contains target definitions.
So in other words it doesn't really matter.
@AdrianSanguineti it does matter, .props are processed earlier compared to targets. Setting BaseIntermediateOutputPath to change project.assets.json location must be done in props, in targets I got errors.
@MagicAndre1981 I would expect that any property you can include in a .props file could instead go into a .targets file. I believe it would need to be inside of a Target element in the .targets file. @rainersigwald for comment, since there might be a lot more to this.
there might be a lot more to this.
Alas, yes. The problems generally arise because MSBuild is import-order dependent, and the last definition of a property, UsingTask, or target "wins".
MSBuild doesn't care about the extension--with explicit imports, you can import from any extension at any point. But there's a widely-used convention:
.props files are imported _early_ in the import order..targets files are imported _late_ in the build order.That's _enforced_ by <Project Sdk="Whatever"> imports (the import of Sdk.props comes first, before all of the contents of the file, then Sdk.targets comes last, after all of the contents of the file). But that just formalized the longstanding convention.
.props and .targetsSo what does this mean for a user who's setting a property? It's impossible to provide _complete_ guidance, because there's a lot of MSBuild logic out there and some of it requires special handling. But I'd offer these guidelines:
.props files for behavior that _might be customized in an individual project_..props files by reading the value of a possibly-customized property, because _the customization won't happen until the user project_..targets files, because they'll pick up customizations from individual projects..targets file, after all user-project customizations have had a chance to kick in. But be wary of derived properties--they may need to be overridden as well..props files (conditioned on a property). _All_ properties are considered before any item, so user-project property customizations will be picked up, and this gives the user project the opportunity to Remove or Update any item brought in by the import..targets files. But remember that this makes overriding the target more difficult if the .targets file is imported by an SDK, because the user project doesn't have a place to override it by default.@rainersigwald, great explanation. The guidelines you've provided was exactly what I was hoping to find back in Feb. Hope that goes into the actual documentation.
@MagicAndre1981, I must agree my statement back in Feb of:
So in other words it doesn't really matter.
is a little misguided and I was doing explicit imports at the time.
I can plan to add this to a section on recommendations/guidance. Sound OK, @rainersigwald ?
Yeah, sounds great.
Most helpful comment
Alas, yes. The problems generally arise because MSBuild is import-order dependent, and the last definition of a property, UsingTask, or target "wins".
MSBuild doesn't care about the extension--with explicit imports, you can import from any extension at any point. But there's a widely-used convention:
.propsfiles are imported _early_ in the import order..targetsfiles are imported _late_ in the build order.That's _enforced_ by
<Project Sdk="Whatever">imports (the import ofSdk.propscomes first, before all of the contents of the file, thenSdk.targetscomes last, after all of the contents of the file). But that just formalized the longstanding convention.Choosing between
.propsand.targetsSo what does this mean for a user who's setting a property? It's impossible to provide _complete_ guidance, because there's a lot of MSBuild logic out there and some of it requires special handling. But I'd offer these guidelines:
.propsfiles for behavior that _might be customized in an individual project_..propsfiles by reading the value of a possibly-customized property, because _the customization won't happen until the user project_..targetsfiles, because they'll pick up customizations from individual projects..targetsfile, after all user-project customizations have had a chance to kick in. But be wary of derived properties--they may need to be overridden as well..propsfiles (conditioned on a property). _All_ properties are considered before any item, so user-project property customizations will be picked up, and this gives the user project the opportunity toRemoveorUpdateany item brought in by the import..targetsfiles. But remember that this makes overriding the target more difficult if the.targetsfile is imported by an SDK, because the user project doesn't have a place to override it by default.