1
votes

I'm trying to compile some third-party code and have hit some strange NMAKE behavior.

The line in the Makefile is

cholmod_aat.o: ../Core/cholmod_aat.c
        $(C) -c $(I) $< -Fo$@

which produces the following error:


Wed, Aug 15 2012 23:25:20           ../Include/cholmod.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_blas.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_check.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_cholesky.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_complexity.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_config.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_core.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_internal.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_matrixops.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_modify.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_partition.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_supernodal.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_template.h
Fri, Aug 17 2012 16:06:24           ../Core/cholmod_aat.c
                                  cholmod_aat.o target does not exist
NMAKE : warning U4006: special macro undefined : '$<'
        cl -O2 -nologo -D__MINGW32__ /MD -DNPARTITION -c -I../../AMD/Include -I.
./../AMD/Source -I../../COLAMD/Include  -I../../metis-4.0/Lib -I../../CCOLAMD/In
clude -I../../CAMD/Include  -I../Include -I../../UFconfig  -Focholmod_aat.o
cl : Command line error D8003 : missing source filename
NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio 10.0
\VC\BIN\cl.EXE"' : return code '0x2'
Stop.

Why is nmake saying '$<' is "undefined" when it lists cholmod_aat.c as a dependency right beforehand? Even more confusing is that if I replace $< with $? in the makefile, nmake expands '$?' just fine:


Wed, Aug 15 2012 23:25:20           ../Include/cholmod.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_blas.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_check.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_cholesky.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_complexity.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_config.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_core.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_internal.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_matrixops.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_modify.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_partition.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_supernodal.h
Wed, Aug 15 2012 23:25:20           ../Include/cholmod_template.h
Fri, Aug 17 2012 16:06:24           ../Core/cholmod_aat.c
                                  cholmod_aat.o target does not exist
        cl -O2 -nologo -D_MINGW32_ /MD -DNPARTITION -c -I../../AMD/Include -I.
./../AMD/Source -I../../COLAMD/Include  -I../../metis-4.0/Lib -I../../CCOLAMD/In
clude -I../../CAMD/Include  -I../Include -I../../UFconfig ../Include/cholmod.h .
./Include/cholmod_blas.h ../Include/cholmod_check.h ../Include/cholmod_cholesky.
h ../Include/cholmod_complexity.h ../Include/cholmod_config.h ../Include/cholmod
_core.h ../Include/cholmod_internal.h ../Include/cholmod_matrixops.h ../Include/
cholmod_modify.h ../Include/cholmod_partition.h ../Include/cholmod_supernodal.h
../Include/cholmod_template.h ../Core/cholmod_aat.c -Focholmod_aat.o

What is going on?

2
So, did you get this fixed? - Joey.Z

2 Answers

3
votes

The answer is on MSDN:

$< - Dependent file with a later timestamp than the current target. Valid only in commands in inference rules.

It's not in an "inference rule", it's in a "description block", as these things are called in NMAKE.

--- EDIT: Expanding on my original answer ---

The terminology is a little strange so in this case it's easiest to show by example. I created a makefile with 2 rules - a description block (a.k.a. target rule), and an inference rule.

C:\temp>type makefile.txt
c.txt : a.txt b.txt
        @echo $?
        @echo %s

.SUFFIXES: .log

.log.txt:
        @echo $<

I created empty files a.txt, b.txt and d.log for dummy input. Then I ran the makefile on targets c.txt and d.txt:

C:\temp>nmake /f makefile.txt c.txt d.txt

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

a.txt b.txt
a.txt
d.log

C:\temp>

Hopefully this illustrates the difference between $?, %s and $<. The MSDN documentation is rather terse, but the code really does work as documented. Honest!

1
votes

You could try the following:

cholmod_aat.obj: ../Core/cholmod_aat.c
        $(C) -c $(I) %s -Fo$@

The symbol %s maps to the first dependency in the list