我不知道如何执行存储为变量的命令或如何在目标内部使用ifeq
,所以我现在有一个非常冗余的Makefile! / p>
理想情况下,我想只有一个目标(all
)可以在Mac上运行存储的命令并在Linux上运行两次,一次使用-m32,一次使用-m64。
all:
echo PLEASE SELECT OS, e.g. make linux
exit 1
mac:
gcc $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS) -o $(BUILD_DIR)$(BUILD_NAME) $(SOURCE) $(LIBRARIES)
linux:
gcc $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS) -o $(BUILD_DIR)$(BUILD_NAME64) $(SOURCE) $(LIBRARIES64) -m64
gcc $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS) -o $(BUILD_DIR)$(BUILD_NAME) $(SOURCE) $(LIBRARIES) -m32
更新:这是我在阅读各种建议后最终得到的结果。 (是的,我知道我应该使用autoconf ......)谢谢大家的帮助!
ifeq($(PLATFORM), Linux)
COMMON = -pthread -fPIC
PLATFORM_CFLAGS = $(COMMON) -m32
PLATFORM_CFLAGS64 = $(COMMON) -m64
endif
ifeq ($(PLATFORM), Darwin)
PLATFORM_CFLAGS = -arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk
endif
all: $(PLATFORM)_all
Darwin_all:
mkdir -p ../../../../tmp
gcc $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS) -o $(BUILD_DIR)$(BUILD_NAME) $(SOURCE) $(LIBRARIES)
Linux_all: Darwin_all
gcc $(SHARED_OPT) $(GENERAL_CFLAGS) $(PLATFORM_CFLAGS64) -o $(BUILD_DIR)$(BUILD_NAME64) $(SOURCE) $(LIBRARIES64)
答案 0 :(得分:2)
这非常简单,但您应该可以通过更改运行的shell命令使其适应更复杂的事情。
PLATFORM := $(shell uname)
all:$(PLATFORM)
Darwin:
echo Darwin
Linux:
echo Linux
答案 1 :(得分:2)
你让宏完成大部分工作,注意你应该使用$(CC)而不是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)
哦,看,现在Linux和MacOS X的命令是相同的......所以我们可以这样做:
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)
天哪,正如我通常在我的文件中所做的那样写作$(XXX)而不是$ {XXX}是一项艰苦的工作。
基本上,我们通过使名称系统化来应用DRY(不要重复自己)。 Makefile不应该令人兴奋。
如果你仍然希望平台之间有所不同,那么你可以按照Ivan Andrus建议的方式做点什么。 GNU Make允许您评估shell命令,所以:
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)
如果你觉得你不能依赖GNU Make,那么:
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)
默认情况下,这将编译32位和64位版本。 如果只需要32位或64位,请运行以下两者中的相应一个:
make BUILD_TYPE=use_32_bit
make BUILD_TYPE=use_64_bit
答案 2 :(得分:1)
你有一些很好的建议(探索平台,使用变量),但是你也应该意识到你的运行非常接近于最好不再考虑支持平台,而是考虑到描述您的软件所需的功能,并使用autoconf
(和系列)来发现实际存在的内容。
请注意,如果它是一个GUI应用程序,那么OSX代码和Linux / X11代码之间可能会有很多差异,通过平台检测是合理的。对于任何面向命令行的东西,你需要这样做是很少见的,因为OSX看起来很像普通的旧Unix。