Let's start with what you have:
$(TARGET1): $(OFILES1)
$(LD) $(LDFLAGS) $(OFILES1) -o $(TARGET1)
$(TARGET2): $(OFILES2)
$(LD) $(LDFLAGS) $(OFILES2) -o $(TARGET2)
...
$(TARGET50): $(OFILES50)
$(LD) $(LDFLAGS) $(OFILES50) -o $(TARGET50)
Then use some automatic variables to reduce the redundancy:
$(TARGET1): $(OFILES1)
$(LD) $(LDFLAGS) $^ -o $@
$(TARGET2): $(OFILES2)
$(LD) $(LDFLAGS) $^ -o $@
...
$(TARGET50): $(OFILES50)
$(LD) $(LDFLAGS) $^ -o $@
Then rearrange things a little:
$(TARGET1): $(OFILES1)
$(TARGET2): $(OFILES2)
...
$(TARGET50): $(OFILES50)
$(TARGET3) $(TARGET2) ... $(TARGET50):
$(LD) $(LDFLAGS) $^ -o $@
At this point you could write a loop that would be equivalent to the first fifty lines, and another to generate the long list of targets in the final rule, but it's probably a good idea to look first at how you define these variables. Chances are there's a way to reduce all of this into a single pattern rule.