gpt4 book ai didi

c - Gnu 在先决条件列表中进行独占或(有点)?

转载 作者:行者123 更新时间:2023-11-30 15:13:38 26 4
gpt4 key购买 nike

我有这样的模式规则:

$(BIN_DIR)/%: $(SOURCES_DIR)/%/*.c
$(CC) $? $(CFLAGS) $(LDFLAGS) -o $@ $(LDLIBS) $(LIBS)

是否可以做这样的事情:

$(BIN_DIR)/%: $(SOURCES_DIR)/%.c OR $(SOURCES_DIR)/%/*.c
$(CC) $? $(CFLAGS) $(LDFLAGS) -o $@ $(LDLIBS) $(LIBS)

其中OR表示如果需要目标$(BIN_DIR)/progname,则首先查找$(SOURCEDS_DIR)/progname.c这将是唯一的先决条件。如果没有这样的文件,先决条件列表将是 $(SOURCES_DIR)/progname/*.c ,就像现在在原始规则中一样?也许还有其他方法可以实现这种行为?

完整的 Makefile(测试因不相关而被忽略):

SOURCES_DIR         = src
INCLUDE_DIR = $(SOURCES_DIR)/include
OBJECTS_DIR = build
BIN_DIR = bin
LIB_DIR = lib

INCLUDE_FLAGS = -I$(INCLUDE_DIR)
CFLAGS=-g --std=c99 -Wall -Wextra -O2 $(INCLUDE_FLAGS)
LDLIBS=-ldl -lm $(OPTLIBS)
LIB_SOURCES=$(wildcard $(SOURCES_DIR)/lib*)
BIN_SOURCES=$(filter-out $(INCLUDE_DIR) $(LIB_SOURCES),\
$(patsubst %.c,%,$(wildcard $(SOURCES_DIR)/*)))
BINS=$(addprefix $(BIN_DIR)/, $(notdir $(BIN_SOURCES)))
OBJECTS=$(patsubst %.c,%.o,\
$(subst $(SOURCES_DIR),$(OBJECTS_DIR),\
$(wildcard $(SOURCES_DIR)/lib**/*.c)))
LIBS=$(addsuffix .a, $(addprefix $(LIB_DIR)/, $(notdir $(LIB_SOURCES))))

SO_LIBS=$(patsubst %.a,%.so,$(LIBS))

all: $(OBJECTS) $(LIBS) $(SO_LIBS) $(BINS)

$(OBJECTS_DIR)/%.o: CFLAGS+= -fPIC
$(OBJECTS_DIR)/%.o: $(SOURCES_DIR)/%*
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $(SOURCES_DIR)/$*.c -o $@ $(LDFLAGS) $(LDLIBS)

$(LIB_DIR)/%.a: $(OBJECTS)
$(AR) rcs $@ $(OBJECTS_DIR)/$*/*.o
ranlib $@

$(LIB_DIR)/%.so: $(LIBS)
$(CC) -shared $(OBJECTS_DIR)/$*/*.o -o $@ $(LDFLAGS) $(LDLIBS)

# the rule i'm talking about
$(BIN_DIR)/%: $(SOURCES_DIR)/%/*.c
$(CC) $? $(CFLAGS) $(LDFLAGS) -o $@ $(LDLIBS) $(LIBS)

最佳答案

忏悔:tl;dr

Is it possible to do something like:

$(BIN_DIR)/%: $(SOURCES_DIR)/%.c OR $(SOURCES_DIR)/%/*.c
$(CC) $? $(CFLAGS) $(LDFLAGS) -o $@ $(LDLIBS) $(LIBS)

您可以通过声明模式规则两次来做到这一点。将配方放入宏中以避免编写两次。

define recipe
$(CC) $? $(CFLAGS) $(LDFLAGS) -o $@ $(LDLIBS) $(LIBS)
endef

$(BIN_DIR)/%: ${SOURCES_DIR}/%.c
$(recipe)

$(BIN_DIR)/%: $(SOURCES_DIR)/%/*.c
$(recipe)

好的,但不要这样做。恕我直言,模式规则是一个丑陋的黑客——我不喜欢这种模糊性。不同的make版本做不同的事情。(通配符也好不了多少,但我不会在这里进一步评论。)明确地写出你想要的东西总是感觉更干净。您仍然可以使用模式,但通过显式列出模式适用的目标来使用静态模式规则

recipe = $(CC) $? $(CFLAGS) $(LDFLAGS) -o $@ $(LDLIBS) $(LIBS)

single-source-targets := $(addprefix ${BIN_DIR}/,counter filter)# for example
multi-source-targets := $(addprefix ${BIN_DIR}/,engine database)

${single-source-targets}: ${BIN_DIR}/%: ${SOURCES_DIR}/%.c ; $(recipe)
${multi-source-targets}: ${BIN_DIR}/%: ${SOURCES_DIR}/%/*.c ; $(recipe)

关于c - Gnu 在先决条件列表中进行独占或(有点)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34477487/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com