依赖树中的 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。另请注意,替换必须分两步完成。
不优雅但有效。
我正在尝试使用 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。另请注意,替换必须分两步完成。
不优雅但有效。