依赖树中的 Makefile 循环

Makefile cycle in dependency tree

我正在尝试使用 makefile 和 nmake 在 windows 上构建我的 c 项目。

我收到以下错误: NMAKE : fatal error U1071: cycle in dependency tree for target 'src\source.c' Stop.

完整的 makefile 是这个

CC = cl
LINK = link
CFLAGS = /Ox \
/I ext\MulticoreBSP-for-C\ \
/I ext\unistd\include \
/I ext\pthreads-win32\sources\pthreads-w32-2-9-1-release \
/D HAVE_STRUCT_TIMESPEC

SOURCE_DIR = src
OBJECT_DIR = build

LIBS = ext\pthreads-win32\sources\pthreads-w32-2-9-1-release\pthreadVC2.lib

DLLS = bin\pthreadVC2.dll
DLLS_SRC = ext\pthreads-win32\sources\pthreads-w32-2-9-1-release\pthreadVC2.dll

BSP_SOURCES = ext\MulticoreBSP-for-C\mcbsp.c ext\MulticoreBSP-for-C\mcinternal.c ext\MulticoreBSP-for-C\mcutil.c
USER_SOURCES = source.c

SOURCES = src$(USER_SOURCES) $(BSP_SOURCES)
OBJECTS = $(SOURCES:*.c=build\*.obj)
# OBJECTS = build\source.obj build\mcbsp.obj build\mcinternal.obj  build\mcutil.obj
EXECUTABLE = bin\BSP.exe

all: $(EXECUTABLE) $(DLLS) $(OBJECTS)

$(EXECUTABLE): $(OBJECTS)
    $(LINK) $(OBJECTS) $(LIBS) /OUT:$(EXECUTABLE)

$(DLLS): $(DLLS_SRC)
    copy $** $@

$(OBJECTS): $(SOURCES)
    $(CC) $(LDFLAGS) /c /Fo.$(OBJECT_DIR)\ $@ $** $(CFLAGS)

clean:
    del $(OBJECT_DIR)\*.obj bin\*.dll bin\*.exe

我可以看出问题出在第 21 行中将 OBJECTS 定义为 OBJECTS = $(SOURCES:*.c=build\*.obj) 然后有规则 $(OBJECTS): $(SOURCES)。这是循环的事实相当清楚,并且在第 22 行中使用 OBJECTS 的注释定义工作正常。

如何实现 OBJECTS 的自动定义而不用第 33 行的规则引起麻烦?我需要不同的规则还是其他规则?

(我有单独的文件夹存放源文件和对象,我认为这样可以防止我使用像 .c.obj: 这样的简单规则。至少,我还没有使用某些东西让它工作那种形式)。

谢谢。

虽然 nmake 支持模式匹配语法 $(macroname:string1=string2),但不支持以这种方式使用通配符。如果我找到在 nmake 的字符串替换版本中使用通配符的方法,我将编辑此答案。

编辑:

有点狡猾,但下面解决了问题

BSP_SOURCES = mcbsp.c mcinternal.c mcutil.c
USER_SOURCES = source.c

SOURCES = src$(USER_SOURCES) ext\MulticoreBSP-for-C$(BSP_SOURCES: = ext\MulticoreBSP-for-C\)
_OBJECTS = build$(USER_SOURCES) build$(BSP_SOURCES: = build\)
OBJECTS = $(_OBJECTS:.c=.obj)

基本上,模式匹配源列表中元素之间的 spaces,而不是使用通配符。请注意,第一个前缀添加在模式匹配之外,因为列表的开头没有 space。另请注意,替换必须分两步完成。

不优雅但有效。