我正在尝试使用Makefile构建库的调试和发布版本,并将这些库复制到相关的构建目录,例如
.PHONY: all clean distclean
all: $(program_NAME_DEBUG)
$(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG)
$(RM) $(program_NAME_DEBUG)
$(RM) $(program_OBJS)
$(program_NAME_RELEASE)
$(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE)
$(RM) $(program_NAME_RELEASE)
$(RM) $(program_OBJS)
$(program_NAME_DEBUG): $(program_OBJS)
$(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(program_OBJS) -o $(program_NAME_DEBUG)
$(program_NAME_RELEASE): $(program_OBJS)
$(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(program_OBJS) -o $(program_NAME_RELEASE)
所有(program_NAME_DEBUG)中的第一个目标编译好,但第二个(program_NAME_RELEASE)产生以下错误:
libGlam_rel.so
make: libGlam_rel.so: Command not found
make: *** [all] Error 127
libGlam_rel.so
是program_NAME_RELEASE
它似乎没有像第一个那样识别第二个目标吗?
修改
终于有了这个工作。
一个问题是在多个目录中使用src文件,使用VPATH对此进行排序,例如
# specify dirs other then current dir to search for src files
VPATH = ../../pulse_IO/src ../../../g2/src
在平台条件内添加其他库目标,例如
# Platform specific conditional compilation
UNAME := $(shell uname)
TARGET := Glam
ifeq ($(UNAME), Linux)
# LINUX version
program_NAME := lib$(TARGET).so
program_DEBUG_NAME := lib$(TARGET)_dbg.so
program_RELEASE_NAME := lib$(TARGET)_rel.so
BUILD_DIR = ../build/linux
endif
ifeq ($(UNAME), MINGW32_NT-6.1)
# WINDOWS version
program_NAME := lib$(TARGET).dll
program_DEBUG_NAME := lib$(TARGET)_dbg.dll
program_RELEASE_NAME := lib$(TARGET)_rel.dll
BUILD_DIR = ../build/windows
endif
添加了新的调试和发布对象文件:
DEBUG_OBJS := $(addprefix $(BUILD_DIR)/debug/,${program_OBJS})
RELEASE_OBJS := $(addprefix $(BUILD_DIR)/release/,${program_OBJS})
设置我的调试并释放CFLAGS:
DEBUG_CFLAGS := -fPIC -g -Wall -DDEBUG=1
RELEASE_CFLAGS := -fPIC -O2 -Wall -DDEBUG=0
整理所有调试和发布编译器选项:
DEBUG_LINK.c := $(CC) $(DEBUG_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
RELEASE_LINK.c := $(CC) $(RELEASE_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
将我的新规则添加到“所有”目标:
.PHONY: all clean
all: $(program_DEBUG_NAME) $(program_RELEASE_NAME)
规则集如下所示(包括隐式目标文件生成的替代):
$(program_DEBUG_NAME): $(DEBUG_OBJS)
$(DEBUG_LINK.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/debug/$@
$(program_RELEASE_NAME): $(RELEASE_OBJS)
$(RELEASE_LINK.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/release/$@
# rule to build object files (replaces implicit rule)
$(BUILD_DIR)/debug/%.o: %.c
$(DEBUG_LINK.c) $< -c -o $@
$(BUILD_DIR)/release/%.o: %.c
$(RELEASE_LINK.c) $< -c -o $@
并完成我修改干净以处理所有新文件:
clean:
@- $(RM) $(BUILD_DIR)/debug/$(program_DEBUG_NAME)
@- $(RM) $(DEBUG_OBJS)
@- $(RM) $(BUILD_DIR)/release/$(program_RELEASE_NAME)
@- $(RM) $(RELEASE_OBJS)
这有助于我使用单个Makefile在Linux和Windows平台上生成我的库的调试和发布版本,例如: $ make -k
答案 0 :(得分:2)
首先要做的事情。您似乎想要两个库的目标文件的不同版本,但此makefile中没有任何内容可以提供该文件。
有几种方法可以做到这一点。最干净的可能有两个目录:
debug_objs/
ang.o
naur.o
gul.o
release_objs/
ang.o
naur.o
gul.o
第二个最干净的是拥有不同的文件名:
ang_debug.o
naur_debug.o
gul_debug.o
ang_rel.o
naur_rel.o
gul_rel.o
无论哪种方式,您都可以为RELEASE_OBJS
和DEBUG_OBJS
编写规则(如果需要,我们可以提供帮助)。
现在看看图书馆规则:
$(program_NAME_DEBUG): $(DEBUG_OBJS)
$(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(DEBUG_OBJS) -o $(program_NAME_DEBUG)
$(program_NAME_RELEASE): $(RELEASE_OBJS)
$(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(RELEASE_OBJS) -o $(program_NAME_RELEASE)
我们可以使用Automatic Variables让它们更简洁:
$(program_NAME_DEBUG): $(DEBUG_OBJS)
$(LINK_DEBUG.c) -shared -Wl,-soname,$@ $^ -o $@
$(program_NAME_RELEASE): $(RELEASE_OBJS)
$(LINK_RELEASE.c) -shared -Wl,-soname,$@ $^ -o $@
(我们可以走得更远,但不要推它。)
现在为all
。我们将$(program_NAME_RELEASE)
移动到它所属的先决条件列表中:
all: $(program_NAME_DEBUG) $(program_NAME_RELEASE)
$(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG)
$(RM) $(program_NAME_DEBUG)
$(RM) $(DEBUG_OBJS)
$(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE)
$(RM) $(program_NAME_RELEASE)
$(RM) $(RELEASE_OBJS)
但没有理由删除目标文件,因为它们不会发生冲突,如果它们是中间文件,Make会将它们删除。当我们只能$(CP)
时,就不需要$(RM)
然后mv
。并且没有必要mv
;如果这就是图书馆所属的地方,我们可以在那里建立它们:
all: $(program_NAME_DEBUG) $(program_NAME_RELEASE)
$(program_NAME_DEBUG): $(DEBUG_OBJS)
$(LINK_DEBUG.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/debug/$@
$(program_NAME_RELEASE): $(RELEASE_OBJS)
$(LINK_RELEASE.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/release/$@
修改:
构建目标文件(我猜你正在使用C):
OBJS:= ang.o naur.o gul.o
DEBUG_OBJS := $(addprefix debug_objs/,$(OBJS))
RELEASE_OBJS := $(addprefix release_objs/,$(OBJS))
debug_objs/%.o: $(SOURCE_DIR)/%.c
$(CC) $(DEBUG_FLAGS) $< -o $@
release_objs/%.o: $(SOURCE_DIR)/%.c
$(CC) $(RELEASE_FLAGS) $< -o $@
(只要确保这些目录存在 - 你也可以自动化,但是你在一天内做了足够的更改。)
答案 1 :(得分:1)
这种改变应该这样做:
all: $(program_NAME_DEBUG) $(program_NAME_RELEASE)
否则,make all
无法生成$(program_NAME_RELEASE)
,这就是错误消息告诉您的内容。