The preprocessor won't be able to figure out structure offsets, so no amount of macro magic alone will dump your offsets for you. 
If you are building for embedded targets, you will probably be able to create .bin files (not elf, coff, mach-o). If you use each of your target compilers to create an array of  offsets in an object file and then dump it to a bin file, it should be possible to compare the bin files for each of your targets.  It would be a good idea to automate the process for build time checks. 
Here is an example of what I'm talking about:
#include <stdint.h>
#include <stddef.h>
typedef struct s1{
    uint16_t f1;
    uint32_t f2;
    uint64_t f3;
    int8_t f4[5];
    uint32_t f5[2];
}s1;
#define o(f) ((int32_t)offsetof(s1,f))
int32_t offsets[]={
    o(f1),
    o(f2),
    o(f3),
    o(f4),
    o(f5)
};
This just creates a table of offsets. Build this for a mipsel and x86_64 and compare. Here is a make file: 
T1:=x86_64-linux-gnu
CC1:=$(T1)-gcc
OBJCPY1:=$(T1)-objcopy
T2:=mipsel-linux
CC2:=$(T2)-gcc
OBJCPY2:=$(T2)-objcopy
.PHONY: all cmp clean hexdumps
all: hexdumps 
hexdumps: hexdump.$(T1).txt hexdump.$(T2).txt
hexdump.$(T1).txt: offsets.$(T1).bin
    hexdump -C $< > $@
hexdump.$(T2).txt: offsets.$(T2).bin
    hexdump -C $< > $@
offsets.$(T1).bin: offsets.$(T1).o
    $(OBJCPY1) -j.data  -O binary $< $@
offsets.$(T2).bin: offsets.$(T2).o
    $(OBJCPY2) -j .data -O binary $< $@
offsets.$(T1).o: offsets.c
    $(CC1) -Wall -c -o $@ $<
offsets.$(T2).o: offsets.c
    $(CC2) -Wall -c -o $@ $<
clean:
    -rm -f offsets.$(T1).o offsets.$(T2).o
    -rm -f offsets.$(T1).bin offsets.$(T2).bin
    -rm -f hexdump.$(T1).txt hexdump.$(T2).txt
Now, comparing the offsets is pretty easy:
evaitl@evbb ~/se $ cat hexdump.mipsel-linux.txt 
00000000  00 00 00 00 04 00 00 00  08 00 00 00 10 00 00 00  |................|
00000010  18 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020
evaitl@evbb ~/se $ cat hexdump.x86_64-linux-gnu.txt 
00000000  00 00 00 00 04 00 00 00  08 00 00 00 10 00 00 00  |................|
00000010  18 00 00 00                                       |....|
00000014
The mips emits a 32 byte data section instead of the x86 20 byte. If you set the size of offsets, you should be able to use cmp to compare the two in your build. 
If your targets have different endianess, you may need to change the o macro to use ntohl or some such to get both compilers to emit integers in the same format.