【发布时间】:2018-02-14 01:15:23
【问题描述】:
这个问题有点含糊,因为我不完全确定在如此简短的摘要中问我想要实现什么的最佳方式。
为了更好地解释它,这就是我目前所拥有的......
common.mk
DESTDIR = ../../install/
tools.mk
CC = gcc
CFLAGS = -fPIC -Wall -Wextra -O2 -g -I.
LDFLAGS = -shared
RM = rm -f
MAKEDIR = mkdir -p
生成文件
include ../../builder/tools.mk
include ../../builder/common.mk
TEST_RUNNERS = test_foo test_bar
test_foo_TESTS = tests/test_foo.c
test_foo_SOURCES = foo.c
test_bar_TESTS = tests/test_bar.c
test_bar_SOURCES = bar.c
# Gather lists of ALL sources and objects required to build test_foo
test_foo_ALL_SOURCES = $(test_foo_TESTS) $(test_foo_SOURCES)
test_foo_ALL_OBJECTS = $(test_foo_ALL_SOURCES:.c=.o)
# Compile All the sources required for test_foo
$(test_foo_ALL_SOURCES:.c=.d):%.d:%.c
$(CC) $(CFLAGS) -MM $< >$@
include $(test_foo_ALL_SOURCES:.c=.d)
# Build test_foo and clean up temporary build files
test_foo: $(test_foo_ALL_OBJECTS)
$(CC) -L$(DESTDIR) -o $(strip $(DESTDIR))$(strip $@) $^
-${RM} ${test_foo_ALL_OBJECTS} ${test_foo_ALL_SOURCES:.c=.d}
# Gather lists of ALL sources and objects required to build test_bar
test_bar_ALL_SOURCES = $(test_bar_TESTS) $(test_bar_SOURCES)
test_bar_ALL_OBJECTS = $(test_bar_ALL_SOURCES:.c=.o)
# Compile All the sources required for test_bar
$(test_bar_ALL_SOURCES:.c=.d):%.d:%.c
$(CC) $(CFLAGS) -MM $< >$@
include $(test_bar_ALL_SOURCES:.c=.d)
# Build test_bar and clean up temporary build files
test_bar: $(test_bar_ALL_OBJECTS)
$(CC) -L$(DESTDIR) -o $(strip $(DESTDIR))$(strip $@) $^
-${RM} ${test_bar_ALL_OBJECTS} ${test_bar_ALL_SOURCES:.c=.d}
我想要做的是消除必须为每个目标手动添加规则的所有复杂性,而是“自动生成”这些规则。在我看来,它相当干净和简单......
TEST_RUNNERS = test_foo test_bar
因此,对于列表中指定的每个 TEST_RUNNER,必须提供 SOURCES 列表(被测代码)和 TESTS 列表(单元测试源)...
test_foo_TESTS
test_foo_SOURCES
我一直在玩 foreach,但这不是正确的方法,而且我不完全确定我需要做什么才能实现我的目标,所以在玩了几个小时后,我想我会尝试问你们中的一些人,因为这里有一些非常聪明的人,希望可以帮助我!
我正在考虑的另一个想法是创建可以调用的模板来生成这些规则:
$(foreach runner,$(TEST_RUNNERS),$(eval $(call COMPILE_ALL_TEST_RUNNER_SOURCES, runner)))
$(foreach runner,$(TEST_RUNNERS),$(eval $(call MAKE_TEST_RUNNER_TEMPLATE, runner)))
define COMPILE_ALL_TEST_RUNNER_SOURCES
$($(1)_ALL_SOURCES:.c=.d):%.d:%.c
$(CC) $(CFLAGS) -MM $< >$@
include $($(1)_ALL_SOURCES:.c=.d)
endef
define MAKE_TEST_RUNNER_TEMPLATE
$(1): $($(1)_ALL_OBJECTS)
$(CC) -L$(DESTDIR) -o $(strip $(DESTDIR))$(strip $@) $^
-${RM} ${$(1)_ALL_OBJECTS} ${$(1)_ALL_SOURCES:.c=.d}
endef
【问题讨论】:
-
如果您可以使用 BSD 的
make,您可以更轻松(主要是bmake包)。看一个例子:github.com/uzsolt/wpwmm4/blob/master/Makefile#L55 - 我认为这正是你想要的:)