.NET Framework Bookmark and Share   
 index > MSBuild > Well-known Item Metadata Usage scenarios
 

Well-known Item Metadata Usage scenarios

Hi,

I have been struggling with the possible usages of ModifiedTime well-known item metadata. It is often necessary to rebuild a target based on the fact that a file has been modified after some other file was. When I was using nant, I was able to say that if file::get-last-access-time('source.ext') >= file::get-last-access-time('source2.ext') then I can rebuild the target. Note that this is not the case where I want to rebuild target based on the fact that one of the input files for it have changed. The dependency exists between two source files, one of which is generated from a different target, so it's a bit more complicated scenario.

In order to detect which file was modified last in msbuild, closest thing I can find is to use ModifiedTime. Besides from the fact that direct usage of ModifiedTime in conditions with a syntax %(MyItemName.ModifiedTime) doesn't work (why? I did find a way to get the value looking at one of the Microsoft's target files, but I am still puzzled), when I finally get the value it is just a string and I can't use it to compare two times like this: time1 > time2. What can I do to get this behavior?

Btw, is there any way to extend conditions with our own "functions"? If not, what is preferred way to have richer conditions - is there an extension mechanism at all?

Regards,

Drazen
Drazen Dotlic
Yes, for dependency analysis in MSBuild targets you can

   1) Use Inputs and Outputs on targets. We call this TLDA (top level dependncy analysis). These can get moderately sophisticated (for example, MSBuild can detect the mapping when you have
Inputs="@(Cppfile)" Outputs="@(CppFile->'%(filename).obj')"
and only rebuild the out of date obj's, synthesizing any necessary output items from the skipped items) however MSBuild targets cannot detect dependencies that are transitive (eg header files defined in your source files).

2) Make your task do dependency analysis itself. This is what the GenerateResource task has to do, because .resx files can contain links to other resource files that the build process doesn't directly know about. In these cases, you must take Inputs and Outputs off the target so the task always gets called.

3) Piggy back off another target. E.g, say you have to sign a binary after linking it. However signing just "waves a wand" over the binary, you cannot compare timestamps to see if it has yet to be done. For linking in contrast you can check timestamps reliably. The solution is to make signing happen whenever link occurs like this
<Target Name="Link" Inputs="@(Cppfile->'%(filename)'.obj)" Outputs="$(OutputBinary);$(ManifestFile)">
   <!-- do link here first -->
   <CallTarget Targets="Sign"/>
</Target>

<!-- piggy backs off Link's TLDA-->
<Target Name="Sign"><!-- No inputs or outputs-->
   <!-- sign here-->
</Target>

If you have beta2, you'll have to do <MSBuild Projects="$(MSBuildProjectFile)" Targets="Sign"/> which does much the same thing as CallTarget.

Dan
DanMoseley - MSFT
I forgot to answer your question. We wanted to add something like IConditionalFunction so you could add functions, but we didn't have time, sorry. You're limited to the built in functions which are Exists(...) and to fix a bug we added the oddly specialized HasTrailingSlash(...).

Dan
DanMoseley - MSFT
I figured out how to reorganize my build file to get the result I want. I did not notice that by using Inputs and Outputs on targets I can get msbuild to verify up-to-date timestamps for me Smile

Anyway, second question still remains - what is (if any) way to have custom functions to be used in conditions?

Thanks,

Drazen
Drazen Dotlic
Yes, for dependency analysis in MSBuild targets you can

   1) Use Inputs and Outputs on targets. We call this TLDA (top level dependncy analysis). These can get moderately sophisticated (for example, MSBuild can detect the mapping when you have
Inputs="@(Cppfile)" Outputs="@(CppFile->'%(filename).obj')"
and only rebuild the out of date obj's, synthesizing any necessary output items from the skipped items) however MSBuild targets cannot detect dependencies that are transitive (eg header files defined in your source files).

2) Make your task do dependency analysis itself. This is what the GenerateResource task has to do, because .resx files can contain links to other resource files that the build process doesn't directly know about. In these cases, you must take Inputs and Outputs off the target so the task always gets called.

3) Piggy back off another target. E.g, say you have to sign a binary after linking it. However signing just "waves a wand" over the binary, you cannot compare timestamps to see if it has yet to be done. For linking in contrast you can check timestamps reliably. The solution is to make signing happen whenever link occurs like this
<Target Name="Link" Inputs="@(Cppfile->'%(filename)'.obj)" Outputs="$(OutputBinary);$(ManifestFile)">
   <!-- do link here first -->
   <CallTarget Targets="Sign"/>
</Target>

<!-- piggy backs off Link's TLDA-->
<Target Name="Sign"><!-- No inputs or outputs-->
   <!-- sign here-->
</Target>

If you have beta2, you'll have to do <MSBuild Projects="$(MSBuildProjectFile)" Targets="Sign"/> which does much the same thing as CallTarget.

Dan
DanMoseley - MSFT
I forgot to answer your question. We wanted to add something like IConditionalFunction so you could add functions, but we didn't have time, sorry. You're limited to the built in functions which are Exists(...) and to fix a bug we added the oddly specialized HasTrailingSlash(...).

Dan
DanMoseley - MSFT
 DanMoseley wrote:
I forgot to answer your question. We wanted to add something like IConditionalFunction so you could add functions, but we didn't have time, sorry. You're limited to the built in functions which are Exists(...) and to fix a bug we added the oddly specialized HasTrailingSlash(...).

Dan


Time, always lacking time... On the other hand, considering how msbuild was designed, I think I'll rely less on functions and more on built-in features to get desired result. Only time will tell if extension functions were really necessary, once I run into a really complex build problem.

Your previous post had some great info btw, nevermind you forgot to answer the question Smile
Drazen Dotlic
Ooh, I like the idea of being able to extend the built-in function set.  Here's hoping this will make it into the Orcas release.
Keith Hill
I hope so too.

Dan
DanMoseley - MSFT

You can use google to search for other answers

Custom Search

More Threads

• target framework confusion
• error while loading config file into dll
• how to change obj folder to common folder
• MSBuild to publish a web project
• Use MSBuild for Integration Services project
• Delayed import of MSBuild project files
• ConvertToAbsolutePath error?
• msbuild BootstrapperFile Include for Office 2007 System Driver
• What is MSBuild?
• MSBuild with RunAs command.