As Carl Norum notes in their answer (and also see my comment in How do I use a conditional in nmake), the !IF is used when the makefile is parsed, while the $@ only has meaning when the makefile run after being parsed.
One solution is the following makefile:
all: foo.obj bar.obj
.c.obj:
@cmd /c if $(@B)==foo ( \
echo clang will be used to create $@ from $** \
) else ( \
echo cl will be used create $@ from $** \
)
which gives:
clang will be used to create foo.obj from foo.c
cl will be used create bar.obj from bar.c
Update: A better, more scalable, solution is the following makefile:
CLANG_SOURCES = foo1.c foo2.c
CL_SOURCES = bar1.c bar2.c
CLANG_OBJECTS = $(CLANG_SOURCES:.c=.obj)
CL_OBJECTS = $(CL_SOURCES:.c=.obj)
all: $(CLANG_OBJECTS) $(CL_OBJECTS)
$(CLANG_OBJECTS):
@echo using clang to create $@ from $?
$(CL_OBJECTS):
@echo using cl to create $@ from $?
Then nmake -nologo will give (assuming the *.c files exist):
using clang to create foo1.obj from foo1.c
using clang to create foo2.obj from foo2.c
using cl to create bar1.obj from bar1.c
using cl to create bar2.obj from bar2.c
Update 2: A complete working example. The makefile:
CLANG_SOURCES = foo1.c foo2.c
CL_SOURCES = bar1.c bar2.c
CLANG_OBJECTS = $(CLANG_SOURCES:.c=.obj)
CL_OBJECTS = $(CL_SOURCES:.c=.obj)
OBJECTS = $(CLANG_OBJECTS) $(CL_OBJECTS)
CFLAGS = -nologo
CLANG_CL = C:\Progra~2\LLVM32\bin\clang-cl
all: $(OBJECTS)
$(OBJECTS): some_header.h
$(CLANG_OBJECTS):
$(CLANG_CL) $(CFLAGS) -c $*.c
clean:
del $(OBJECTS) 2>NUL
gives, with nmake -nologo:
C:\Progra~2\LLVM32\bin\clang-cl -nologo -c foo1.c
C:\Progra~2\LLVM32\bin\clang-cl -nologo -c foo2.c
cl -nologo /c bar1.c bar2.c
bar1.c
bar2.c
Generating Code...
Here for convenience we are using nmake's predefined inference rule for generating $(CL_OBJECTS).
Note nmake doesn't allow $< here, and some_header.h causes problems for $? and $**. My previous suggestions are wrong concerning this.
Also note, while not apparent in the above, nmake preserves the implicit dependency of the object file to the corresponding source file, even with the added rule for clang. For example:
C:\Users\Joe>nmake -nologo
C:\Users\Joe>copy /b foo1.c +,,
1 file(s) copied.
C:\Users\Joe>nmake -nologo
C:\Progra~2\LLVM32\bin\clang-cl -nologo -c foo1.c
C:\Users\Joe>copy /b bar1.c +,,
1 file(s) copied.
C:\Users\Joe>nmake -nologo
cl -nologo /c bar1.c
bar1.c
(Here the copy command is used as a "touch": see the example at https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/copy/.)