Since each compilation probably looks at different source files, most of the rules for compatible types across separate compiles are structural in nature:
Matching scalar (integral, floating, and pointer) types must be compatible, as if they were in the same source file.
Matching structures, unions, and enums must have the same number of members. Each matching member must have a compatible type (in the separate compilation sense), including bit-field widths.
Matching structures must have the members in the same order. The order of union and enum members does not matter.
Matching enum members must have the same value.
An additional requirement is that the names of members, including the lack of names for unnamed members, match for structures, unions, and enums, but not necessarily their respective tags.