how to write makefile mixing C and C++

34,050

Solution 1

G++ can and will compile both .c and .cpp source files just fine.

What you really need to do is add dependencies for "server" target. For example:

OBJ = net.o hiredis.o sds.o async.o

...

all: server

server: $(OBJ)

There are some really good tips in this Howto.

Solution 2

You can do that by compiling first the C files and then straight after the CPP files. This might work (at least worked in one of my projects):

CXX = g++
CC = gcc
CFLAGS = -Wall -c
CXXFLAGS = -Wall -D__STDC_LIMIT_MACROS

OUTPUTDIR = ./bin/
MKDIR = mkdir -p $(OUTPUTDIR)
OBJECTC = redis.o

CSOURCES = \
     $(HIREDIS_FOLDER)/net.c \
     $(HIREDIS_FOLDER)/hiredis.c \
     $(HIREDIS_FOLDER)/sds.c \
     $(HIREDIS_FOLDER)/async.c

CXXSOURCES = \
    main.cpp 

all: server

server: 
    $(MKDIR)
    $(CC) $(CSOURCES) $(CFLAGS) -o $(OUTPUTDIR)$(OBJECTC)
    $(CXX) $(OUTPUTDIR)$(OBJECTC) $(CXXSOURCES) -o $(OUTPUTDIR)server

.PHONY: clean
clean:
    $(RM) -rf $(OUTPUTDIR)
    $(RM) ./*.gc??
    $(RM) ./*.o

Feel free to change it if you see a more proper way to do it :)

Share:
34,050
Dan
Author by

Dan

Updated on July 09, 2022

Comments

  • Dan
    Dan almost 2 years

    In this Makefile, I don't know how to compile out c objects in the same Makefile mixing C and C++. If I first compile the C objects and then run this Makefile, it works. Can anyone help to fix it for me? Thanks in advance!

    CXX = g++
    CXXFLAGS = -Wall -D__STDC_LIMIT_MACROS
    
    
    SERVER_SRC = \
        main.cpp
    
    SERVER_SRC_OBJS = ${SERVER_SRC:.cpp=.o}
    
    
    REDIS_SRC = \
        $(HIREDIS_FOLDER)/net.c \
        $(HIREDIS_FOLDER)/hiredis.c \
        $(HIREDIS_FOLDER)/sds.c \
        $(HIREDIS_FOLDER)/async.c
    
    REDIS_SRC_OBJS = ${REDIS_SRC:.c=.o}
    
    
    .SUFFIXES:
    .SUFFIXES: .o .cpp
    .cpp.o:
        $(CXX) $(CXXFLAGS) -I$(HIREDIS_FOLDER) \
        -c $< -o $*.o
    
    
    all: server
    
    net.o: net.c fmacros.h net.h hiredis.h
    async.o: async.c async.h hiredis.h sds.h dict.c dict.h
    hiredis.o: hiredis.c fmacros.h hiredis.h net.h sds.h
    sds.o: sds.c sds.h
    
    
    server: $(SERVER_SRC_OBJS) $(REDIS_SRC_OBJS)
        mkdir -p bin
        $(CXX) $(CXXFLAGS) -o bin/redis_main \
        -I$(HIREDIS_FOLDER) \
        $(REDIS_SRC_OBJS) \
        $(SERVER_SRC_OBJS) \
        -lpthread \
        -lrt \
        -Wl,-rpath,./
    
    
    .PHONY: clean
    clean:
        $(RM) -r bin/redis_main
        $(RM) ./*.gc??
        $(RM) $(SERVER_SRC_OBJS)
        $(RM) $(REDIS_SRC_OBJS)
    
  • Dan
    Dan over 12 years
    Thanks very much! I had used CMake to avoid this issue!
  • orion elenzil
    orion elenzil over 9 years
    small note - forgot to use CXXFLAGS.
  • RubberDuck
    RubberDuck over 6 years
    This also recompiles everything on each build. because dependencies aren't specified.