I had the same problem today: m1.c and m2.c both had a main function but needed to be linked and run one of them.
Solution: user STRIP to remove the main symbol from one of them after compilation but before linking:
gcc -c m1.c m2.c; strip --strip-symbol main m1.o; gcc m1.o m2.o; ./a.out
will run main from m2
gcc -c m1.c m2.c; strip --strip-symbol main m2.o; gcc m1.o m2.o; ./a.out
will run main from m1
Without strip:
gcc - m1.c m2.c
m2.o: In function `main':
m2.c:(.text+0x0): multiple definition of `main'
m1.o:m1.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status