views:

195

answers:

3

This is a bit of an odd situation. Here's what's happening.

So, we have a VS2008 project which outputs to a number of files under perforce control. These files have the always writable flag set.

I compile the project in VS, which gives me up to date binaries on my machine. If I then revert those binaries via perforce, I have the version of the binaries that were up on perforce (ie, old ones.)

Despite this, compiling the project again at this point detects no changes and will not remake those binaries. In a way, this makes sense, since none of the code or obj files have changed, but it's not really what I want to happen.

This comes up in an edge case on our automated build server. I can think of tons of different little hacks I could do to fix this, but I'm thinking I could be missing something fundamental here.

The actual build process uses the Unreal build tool, so there is a bit of magic going on behind the scenes that I'm not entirely familiar with too.

Edit: This is a C/C++ project, forgot to mention that.

+2  A: 

Do you have the modtime client option disabled (that is, set to nomodtime)? If the option is disabled, Perforce will sync all files using the current date and time (including, I believe, files you explicitly revert), so if your build system is simply checking file timestamps, it will believe the binary is newer than the source files and declare itself complete.

(I tend to intentionally disable modtime in my clients, so that when I sync source files my build system always rebuilds potentially-affected binaries.)

Commodore Jaeger
I had no idea this option existed, thanks! I could see how enabling it could lead to weirdness in certain situations, but in this case it fixes the problem perfectly.
CHaskell2
Well. It sort of fixes it. I'm running into problems where it is not rebuilding affected binaries, like you had mentioned. What I really want is the modification time for source files to be when it was submitted to the depot, which is what the behavior is for files marked +m in perforce. I don't see a clean way to do this without marking every source file, or changing how/where the binaries are stored, neither of which I can do.
CHaskell2
A: 

I've come across similar 'problems' with SVN, so this is something which is common to most version control systems:

When you update or revert or in any way modify files under version control, they generally take on the time now - just like using touch. So, as Commodore mentioned, your binary file is now newer than anything else, so it 'must' be up to date.

I've had a similar experience when reverting a source file (especially a header file) and I'd not expected a rebuild because I was expecting a revert to be like a DOS COPY, but because the file in question takes on the time now, VS thinks the binaries are out of date and rebuilds everything that depends on the source file.

Its done like this so that you never get things like libraries built with different versions of headers.

You could try 'touching' a crucial file (like a common header file) to force a rebuild, or just ask Visual Studio to do a complete rebuild.

Oh, and don't put files that are the output of a build under version control - you only need the source files. You need to store your binaries elsewhere, maybe in dated folders.

quamrana
+3  A: 

I just wanted to add that the behavior you observe is a consequence of using timestamps to determine whether a file was updated or not.

You can observe similar issues when the compiling machine and the file hosting machine are distinct and their clocks get out of sync.

Modern build systems use MD5 stamps instead of timestamps, which makes them impervious to these build issues.

bltxd
+1. This isn't an issue with Perforce - it's a long standing Visual Studio issue. Perforce is accurately setting the timestamps to the time of the last modification. Visual Studio uses the flawed reasoning that if the output has a newer timestamp than the input, everything is up to date.
Joe Gauterin
Yeah, this definitely seems to have been the problem.
CHaskell2