Whenever possible, makefile rules should first create their target under a temporary name, then move it into place. That way, if the build process is interrupted for any reason, there won't be a half-written target file that can't be distinguished from a fully written file.
out.txt: foo.sh input.txt
./foo.sh -i input.txt >$@.tmp
mv -f $@.tmp $@
mv -f $@.tmp $@ is a common makefile idiom.
Juliano's answer shows a variant where the name of the temporary file is generated dynamically. The dynamic name generation is required if there may be more than one process generating the same target or if the directory can be written to by other users. This is very rarely the case for a build tree (if these were issues, a lot of what's going on in a typical makefile would break), so the extra complexity is usually not necessary.