makefile for all but one?

Hi, I’m trying to compile my CUDA program so that all but one file is compiled with g++, and for that one file to be compiled in gcc.

My current setup is like this:

$(OBJDIR)/%.c.o : $(SRCDIR)main.c $(C_DEPS)
$(VERBOSE)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -c $<

$(OBJDIR)/%.c.o : $(SRCDIR)%.c $(C_DEPS)
$(VERBOSE)$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/%.cpp.o : $(SRCDIR)%.cpp $(C_DEPS)
$(VERBOSE)$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/%.cu.o : $(SRCDIR)%.cu $(CU_DEPS)
$(VERBOSE)$(NVCC) $(NVCCFLAGS) $(SMVERSIONFLAGS) -o $@ -c $<

However, no matter what I do, it either compiles all of the .c files with gcc, or all of them with g++.

So my main question, then, is how do I make one file an exception to something like ‘%.c’?

Thank you.

It is not possible to specify the same pattern matching rule twice with different actions. How is make supposed to known which one to use? All that is happening is that the second .c.o rule overrides the first, leading to the first having no effect.

If you want a specific rule for compiling main.c, then specify it fully without using patterns which will conflict with other rules. Changing the main.c compile rule to this:

$(OBJDIR)/main.c.o : $(SRCDIR)main.c $(C_DEPS)

$(VERBOSE)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -c $<

should fix things.

I tried this and while it did succeed in creating main.c.o without errors, it just immediately stopped after doing so. None of the other compiling rules followed.

I only changed that one line, so I’m not sure what the reason for that is…

Presumably you have a target which contains all the object you are tryibg to compile and then links them into an application or library? Or is what you posted the entire makefile?

Yes, but I don’t see how changing that line would affect the target:

$(TARGET): makedirectories $(OBJS) makefile
$(VERBOSE)$(LINKLINE) $(LDFLAGS)

as OBJS is defined as follows:

OBJS += $(patsubst %.c,$(OBJDIR)/%.c.o,$(notdir $(CCFILES)))
OBJS += $(patsubst %.c,$(OBJDIR)/%.c.o,$(notdir $(CFILES)))
OBJS += $(patsubst %.cu,$(OBJDIR)/%.cu.o,$(notdir $(CUFILES)))

which doesn’t exclude main.c.

Now I’m trying this:

$(OBJDIR)/%.c.o : $(SRCDIR)%.c $(C_DEPS)
ifeq ‘$(basename $<)’ ‘main’
$(VERBOSE)$(CC) $(CXXFLAGS) $(CFLAGS) $(PUFLAGS) $(LDFLAGS) -o $@ -c $<
else
$(VERBOSE)$(CXX) $(CXXFLAGS) $(CFLAGS) $(PUFLAGS) -o $@ -c $<
endif

but it appears to go to the else case no matter what - even on main.c. I’ve checked the makefile documentation, but this - and all other forms of it (such as ifeq(,), ifeq"" “”, etc) - have the same effect of not working. Now I’m really confused…