0

I am trying to build my c project on windows using a makefile and nmake.

I get the following error: NMAKE : fatal error U1071: cycle in dependency tree for target 'src\source.c' Stop.

The full makefile is this

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

I can see that the issue comes from defining OBJECTS in line 21 as OBJECTS = $(SOURCES:*.c=build\*.obj) and then having the rule $(OBJECTS): $(SOURCES). The fact that this is cyclic is fairly clear, and using the commented definition of OBJECTS in line 22 works fine.

How can I achieve an automatic definition of OBJECTS without the rule at line 33 causing trouble? Do I need a different rule, or something else?

(I have separate folders for the source files and the objects, and I think having that prevents me from using a simple rule like .c.obj:. At least, I haven't got it to work using something of that form).

Thanks.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Sam
  • 222
  • 2
  • 12
  • Have you tried printing out `SOURCES` and `OBJECTS`, to make sure they are correct? – Some programmer dude Sep 04 '15 at 09:56
  • Also, right now *all* object files depends on *all* source files. So modifying a single source file will lead to recompilation of all source files. – Some programmer dude Sep 04 '15 at 09:57
  • Thank you Joachim. After echoing the `OBJECTS` variable, it seems that the strsub is not working and the `OBJECTS` variable is identical to `SOURCES`. I'll have to look into that, unless you have any idea why it isn't working. – Sam Sep 04 '15 at 10:08
  • [`nmake`](https://msdn.microsoft.com/en-us/library/dd9y37ha.aspx) is different from the "standard" make programs found in POSIX environments, and might not support that form of string substitution? – Some programmer dude Sep 04 '15 at 10:16
  • The [documentation](https://msdn.microsoft.com/en-us/library/bsd42ets.aspx) indicates that it should be ok. At least now that I know that is the cause of the problem I can play around with it a bit to get it working. Also, you mentioned that currently all objects depend on all sources, is that due to `$(OBJECTS): $(SOURCES)` rule? And how can I change that? – Sam Sep 04 '15 at 10:37
  • Althought, now I think about it, the documenation makes no mention of whether the wildcard `*` is supported... – Sam Sep 04 '15 at 10:39
  • How about a [recursive invocation](http://stackoverflow.com/a/640880/2908724), since `nmake` doesn't support wildcards in production targets? – bishop Sep 04 '15 at 12:48

1 Answers1

0

Although the pattern matching syntax $(macroname:string1=string2)is supported by nmake, use of wildcards in this way is not. I will edit this answer if I find a way to use wildcards in nmake's version of string substitution.

Edit:

Its a little dodgy, but the following solves the problem

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)

Basically, pattern matching the spaces inbetween the elements in the list of sources, rather than using a wildcard. Note that the first prefix is added outside of the pattern match, because there is no space at the start of the list. Also note that the substitution had to be done in two steps.

Inelegant but effective.

Sam
  • 222
  • 2
  • 12