每个文件名的隐式规则,具有未指定的子目录

Implicit rule for each file name, with unspecified subdirectory

这是我试图构建到我的二进制文件中的目录结构。

library_name:
    library_module:
        foo.h
        foo.c
    library_module:
        bar.h
        bar.c
        boo.h
        boo.c
    (etc...)

我正在尝试制定一条规则,将所有这些编译成对象:

obj:
    foo.o
    bar.o
    boo.o
    (etc...)
LIBRARY_NAME := $(patsubst %.c, %, $(notdir $(wildcard src/library_name/**/*.c)))
# This is a list of all file names with path and extension removed.

$(LIBRARY_NAME:%=obj/%.o): obj/%.o: src/library_name/**/%.c
    $(CC) -c $< $(FLAGS) -o $@

# make: *** No rule to make target 'src/library_name/**/foo.c', needed by 'obj/foo.o'.  Stop.

我也试过以下方法:

... $(wildcard src/alabaster/**/$(%).c) ...

但我似乎不能那样使用“%”。

也许这实际上不是执行此操作的方法,除非我真的需要,否则我通常不会触及我的 makefile。

您可以采用您的方法,但如果您有同名文件,您将 运行 遇到问题。最好保留对象目录的文件夹结构。我没有测试下面的 makefile(但我认为它有 99%)。但这让您了解如何实现您想要的 - 请注意,两个库文件夹中的文件名称重复...

# Get your source list (use wildcard or what ever, but just for clarity you should end up with a list of files with full paths to start with):
SOURCES = \
    lib1/fred.c \
    lib1/bob.c \
    lib1/carl.c \
    lib2/fred.c \
    lib2/bob.c \
    lib2/carl.c \

# Output folders/targets
OBJ_DIR = obj
BIN_DIR = bin
OUTPUT_FILE = output

# Create your objects list in the obj directory
OBJECTS = $(addprefix $(OBJ_DIR)/,$(addsuffix .o,$(basename $(SOURCES))))

# Create list of unique folders to create
DIRS = $(sort $(dir $(OBJECTS))) $(BIN_DIR)

# Create list of include paths
INCS = $(addprefix -I,$(sort $(dir $(SOURCES))))

# Main target rule
bin/$(OUTPUT_FILE): $(DIRS)  $(OBJECTS)
    @echo linker: gcc $(OBJECTS) -o $@
    @touch $@

# Rule to build your object file - ensure that the folders are created first (also create a dummy obj file) - note this works for parallel builds too (make -j
$(OBJ_DIR)/%.o: %.c | $(DIRS)
    @echo compile: gcc $(INCS) -c $? -o $@
    @touch $@

# Create your directories here
$(DIRS):
    @echo Creating dir: $@
    @mkdir -p $@

# Clean if needed
.PHONY: clean
clean:
    rm -rf $(OBJ_DIR) $(BIN_DIR)

如果你真的想按照你的方式去做,你需要看看 VPATH 我相信 - 我从来不喜欢那样做,尽管由于我之前提到的原因,我后来打了太多次了曾经想再次使用的道路! :)

已更新 刚回到家,对其进行了测试并进行了一些调整以确保其正常工作。