2015-09-04 114 views
0

我想在Windows上使用makefile和nmake构建我的c项目。Makefile循环依赖树

我收到以下错误: 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 $** [email protected] 

$(OBJECTS): $(SOURCES) 
    $(CC) $(LDFLAGS) /c /Fo.\$(OBJECT_DIR)\ [email protected] $** $(CFLAGS) 

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

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

如何在没有第33行规则的情况下自动定义OBJECTS导致麻烦?我需要一个不同的规则,还是其他的?我有单独的文件夹的源文件和对象,我认为这阻止了我使用一个简单的规则,如.c.obj:。至少,我没有得到它的工作使用这种形式的东西)。

谢谢。

+0

您是否尝试过打印'SOURCES'和'OBJECTS',以确保它们正确? –

+0

此外,现在*所有*目标文件取决于*所有*源文件。因此,修改单个源文件将导致重新编译所有源文件。 –

+0

谢谢Joachim。在回显“OBJECTS”变量后,似乎strsub不起作用,而“OBJECTS”变量与“SOURCES”相同。除非你知道为什么它不起作用,否则我必须研究这一点。 – Sam

回答

0

尽管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) 

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

不雅但有效。