Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile. How to exclude one particular file from compilation?

Tags:

makefile

I am trying to exclude main.cpp file from the list of files to be compiled defined by the rule below:

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
ifneq ($(notdir $<), main.cpp)
        @$(COMPILE.cpp) $(OUTPUT_OPTION) $<
endif

This 'ifneq' condition always evaluates to true, which is bizarre. What am I doing wrong? Is there a better way to exlude one file from an explicit rule?

like image 524
bioffe Avatar asked Mar 04 '11 03:03

bioffe


2 Answers

Why don't you try using the filter-out text function if you're using GNU Make.

Returns all whitespace-separated words in text that do not match any of the pattern words, removing the words that do match one or more. This is the exact opposite of the filter function.

For example, given:

objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o 

the following generates a list which contains all the object files not in ‘mains’:

$(filter-out $(mains),$(objects))
like image 113
v3nM Avatar answered Jan 02 '23 01:01

v3nM


That isn't the best way to do it, but if you do it along these lines, write it as a shell condition, not using GNU make conditionals:

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @if [ $(notdir $<) != main.cpp ]; \
    then $(COMPILE.cpp) $(OUTPUT_OPTION) $<; \
    fi

The continuation markers (backslashes) are needed. So are the semicolons. The values prefixed with $ will be expanded by make before the shell is invoked to interpret them. You probably don't want the echo where it is, either. You probably need:

$(TMPDIRPATH)%.o: %.cpp
    @if [ $(notdir $<) != main.cpp ]; \
    then echo compile $<; \
         $(COMPILE.cpp) $(OUTPUT_OPTION) $<; \
    fi

The way I would expect to do it is with a list of the files to be compiled. Using any wild card mechanism leads to problems when extra files are added - other tests, or stray files that aren't really part of the system.


The comment says "But the GNU Make Manual says ifneq should work".

The ifneq would work if it were positioned correctly, which means 'not indented as part of the commands associated with a rule'. You could, therefore, write something like (an appallingly bad example, but my brain's on the fritz):

ifneq (${CFLAGS}, -Wall)
CFLAGS += -Wall
endif

file1.o: file1.c
    ${CC} ${CFLAGS} -c $<

But when the ifneq is indented as in the question, it is just a command that actually isn't found on the system when the make runs the shell to process the command.

like image 21
Jonathan Leffler Avatar answered Jan 02 '23 00:01

Jonathan Leffler