在目录的子目录中编译几个程序,并使用 makefile 将可执行文件放在不同的目录中

Compile several programs in the subdirectories of a directory and place the executables in different directories using makefile

我的问题是:我想创建一个 makefile,它将在多个目录中编译程序,但会将可执行文件放置在每个目录中名为 executables 的子目录中。我有大量程序要编译,因此为每个程序编写规则似乎很乏味。假设我当前的工作目录是Curr_dir 下面是目录结构-

Curr_dir
    |
    |__dir1
    |   |__q1.c
    |   |__q2.c
    |   |__q3.c
    |   |__+executable
    |
    |__dir2
    |   |__q4.c
    |   |__q5.c
    |   |__q6.c
    |   |__+executable
    |
    |__Makefile

我在我的根目录中只列出了 2 个目录,但有几个目录包含 3-4 个 .c 文件。现在我想在我的根目录中使用 Makefile 编译所有这些 .c 文件,并将可执行文件放在相应的 executables 目录中。 这是我的 makefile,它编译每个程序并在同一目录中生成可执行文件。

CC= gcc
RM= rm -vrf
CFLAGS= -lm -g
SRCFILES =$(wildcard */*.c)
SRCDIRS= $(wildcard */)
EXECDIRS= $(SRCDIRS:%=%executables)
EXECFILES = $(SRCFILES:%.c=%)
dirs: 
    mkdir -p $(EXECDIRS)

all: dirs $(EXECFILES)

%: %.c
    -$(CC) -o $@ $< $(CFLAGS)

.PHONY: clean
clean:
     $(RM) $(EXECFILES) $(EXECDIRS)

任何帮助将不胜感激。

您有两个问题:构建您要构建的文件的列表,以及编写一个或一组规则来构建它们。碰巧的是,由于 Make 缺乏良好的通配符处理,这两个问题都变得很困难。

第一部分:

SRCFILES := $(wildcard */*.c)

EXECFILES := $(join $(addsuffix executables/,$(dir $(SRCFILES))), $(basename $(notdir $(SRCFILES))))

简陋,但有效。

第二部分需要将目标名称 (dir1/executables/q1) 与相应的源名称 (dir1/q1.c) 相关联。也许最不可怕的方法是使用使用 SECONDEXPANSION 进行操作的模式规则目标名称:

.SECONDEXPANSION:
$(EXECFILES): $$(addsuffix .c,$$(subst executables/,,$$@))
    @echo building $@ from $<
    -$(CC) -o $@ $< $(CFLAGS)

关于构建目录的最佳方法存在一些争议,但我喜欢这种方法:

.SECONDEXPANSION:
$(EXECFILES): $$(addsuffix .c,$$(subst executables/,,$$@)) $$(dir $$@)
    @echo building $@ from $<
    -$(CC) -o $@ $< $(CFLAGS)

%/executables:
    mkdir -p $@