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

时间:2019-02-07 20:36:47

标签: makefile gnu-make

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

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。

1 个答案:

答案 0 :(得分:0)

您可以采用这种方法,但是如果您使用相同名称的文件,则会遇到问题。最好保留对象目录的文件夹结构。我还没有测试下面的makefile(但我认为其中的99%)。但这使您知道如何实现所需的目标-请注意,两个librarie文件夹中的文件名重复...

# 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,我相信-我从来不喜欢那样做,尽管由于我之前提到的原因,后来我在此途中被击中了很多次想要再次使用! :)

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