Search code examples
makefilegnuprerequisites

How to write a recipe common to both .c and cpp files


I want to compile both .c and .cpp files using same compiler command like

CC=g++
...
OBJS=mora.o
all : $(OBJS) libMO.so
%.o: %.c
        $(CC) $(INCLUDES) $(CCFLAGS) -c $(<) -o $(@)
libMO.so: $(OBJS)
        $(CC) $(LDFLAGS) $(CCFLAGS)  $(^) -o $(@)

Now the question is how to include rule/recipe for .cpp files too? Can we do it in same rule using regex for prerequiste?

Is it ok to write one more rule/recipe for .cpp ?

%.o: %.c
        $(CC) $(INCLUDES) $(CCFLAGS) -c $(<) -o $(@)
%.o: %.cpp
        $(CC) $(INCLUDES) $(CCFLAGS) -c $(<) -o $(@)

Will the above 1st recipe give error for .cpp files as it will not find correspoding .c file ?


Solution

  • Is it ok to write one more rule/recipe for .cpp ?

    Yes it is. You can write a rule for each extension you need Make to process. If you redefine the same pattern, make will choose the first one found in the makefile.

    Will the above 1st recipe give error for .cpp files as it will not find corresponding .c file ?

    Make will process .cpp files independently of .c files, and vice versa (unless you explicitely tell him not to, e.g. if a .c file depends of a .cpp file).


    That said, a little review :

    • Special variables like $(<) or $(@) do not need parenthesis. You can write $< and $@ directly.

    • C and C++ rules share the same built-in $(CPPFLAGS) variable (meant for preprocessor flags, your $(INCLUDE) variable content should go into).

    • C uses the $(CC) and $(CFLAGS) built-in variables :

      CC = $(CXX)
      ...
      %.o: %.c
          $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
      
    • C++ uses the $(CXX) and $(CXXFLAGS) built-in variables :

      %.o: %.cpp
          $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
      
    • GNU Make already has built-in rules for C and C++ source files. Using the above variables right, there is no need for you to specify these generic rules at all.