You make macros do most of the work, noting that you should use $(CC) rather than gcc.
BUILD_COMMAND = $(CC) $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS)
BUILD_NAME32 = $(BUILD_NAME)
TARGET_32 = $(BUILD_DIR)$(BUILD_NAME32)
TARGET_64 = $(BUILD_DIR)$(BUILD_NAME64)
LIBS_32 = $(LIBRARIES)
LIBS_64 = $(LIBRARIES64)
OPTS_32 = -m32
OPTS_64 = -m64
# We could do some fancy stuff here...
# Except that we will remove the commands momentarily
all:
echo PLEASE SELECT OS, e.g. make linux
exit 1
# Note that without a qualifier
# - MacOS X 10.5.x will build 32-bit
# - MacOS X 10.6.x will build 64-bit
# But why not build both anyway?
mac:
$(BUILD_COMMAND) -o $(TARGET_64) $(SOURCE) $(LIBS_64) $(OPTS_64)
$(BUILD_COMMAND) -o $(TARGET_32) $(SOURCE) $(LIBS_32) $(OPTS_32)
linux:
$(BUILD_COMMAND) -o $(TARGET_64) $(SOURCE) $(LIBS_64) $(OPTS_64)
$(BUILD_COMMAND) -o $(TARGET_32) $(SOURCE) $(LIBS_32) $(OPTS_32)
Oh, and look, the commands are the same for Linux and MacOS X now...so we can do:
BUILD_COMMAND = $(CC) $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS)
BUILD_NAME32 = $(BUILD_NAME)
TARGET_32 = $(BUILD_DIR)$(BUILD_NAME32)
TARGET_64 = $(BUILD_DIR)$(BUILD_NAME64)
LIBS_32 = $(LIBRARIES)
LIBS_64 = $(LIBRARIES64)
OPTS_32 = -m32
OPTS_64 = -m64
all:
$(BUILD_COMMAND) -o $(TARGET_64) $(SOURCE) $(LIBS_64) $(OPTS_64)
$(BUILD_COMMAND) -o $(TARGET_32) $(SOURCE) $(LIBS_32) $(OPTS_32)
Gosh, it is hard work writing $(XXX) instead of ${XXX} as I normally do in my makefiles.
Basically, we apply DRY (Don't Repeat Yourself) by making names boringly systematic. Makefiles should not be exciting.
If you still want to have a difference between your platforms, then you can do something along the lines suggested by Ivan Andrus. GNU Make allows you to evaluate shell commands, so:
BUILD_COMMAND = $(CC) $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS)
BUILD_NAME32 = $(BUILD_NAME)
TARGET_32 = $(BUILD_DIR)$(BUILD_NAME32)
TARGET_64 = $(BUILD_DIR)$(BUILD_NAME64)
LIBS_32 = $(LIBRARIES)
LIBS_64 = $(LIBRARIES64)
OPTS_32 = -m32
OPTS_64 = -m64
all: $(shell uname)
Linux:
$(BUILD_COMMAND) -o $(TARGET_64) $(SOURCE) $(LIBS_64) $(OPTS_64)
$(BUILD_COMMAND) -o $(TARGET_32) $(SOURCE) $(LIBS_32) $(OPTS_32)
Darwin:
$(BUILD_COMMAND) -o $(TARGET_32) $(SOURCE) $(LIBS_32)
If you feel you can't rely on GNU Make, then:
BUILD_COMMAND = $(CC) $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS)
BUILD_NAME32 = $(BUILD_NAME)
TARGET_32 = $(BUILD_DIR)$(BUILD_NAME32)
TARGET_64 = $(BUILD_DIR)$(BUILD_NAME64)
LIBS_32 = $(LIBRARIES)
LIBS_64 = $(LIBRARIES64)
OPTS_32 = -m32
OPTS_64 = -m64
BUILD_32 = use_32_bit
BUILD_64 = use_64_bit
BUILD_TYPE = $(BUILD_32) $(BUILD_64)
.PHONEY: $(BUILD_32) $(BUILD_64)
all: $(BUILD_TYPE)
use_64_bit:
$(BUILD_COMMAND) -o $(TARGET_64) $(SOURCE) $(LIBS_64) $(OPTS_64)
use_32_bit:
$(BUILD_COMMAND) -o $(TARGET_32) $(SOURCE) $(LIBS_32) $(OPTS_32)
By default this will compile both 32-bit and 64-bit versions.
If you want 32-bit only or 64-bit only, run the appropriate one of these two:
make BUILD_TYPE=use_32_bit
make BUILD_TYPE=use_64_bit