Makefile for a C++ project using Boost, Eigen, and htslib I had a Makefile but it doesn't meet the "industry-standard expectation". That was feedback from my client. The old Makefile was rejected. Thus, I'm making a new one.

Here is the repository for my project.



My old Makefile:

# Boost C++ library
BOOST = /usr/local/include/boost_1_64_0

# Linear-algebra library
EIGEN = /usr/local/Cellar/eigen/3.2.8/include/eigen3

# HTSLIB library for BAM files
HTSLIB = /Users/tedwong/Sources/QA/htslib

# Where the header are
INCLUDE = src

EXEC         = anaquin
SOURCES      = $(wildcard src/*.cpp src/tools/*.cpp src/analyzers/*.cpp src/RnaQuin/*.cpp src/VarQuin/*.cpp src/MetaQuin/*.cpp src/data/*.cpp src/parsers/*.cpp src/writers/*.cpp src/stats/*.cpp src/cufflinks/*.cpp)
OBJECTS      = $(SOURCES:.cpp=.o)
OBJECTS_TEST = $(SOURCES_TEST:.cpp=.o)
SOURCES_LIB  = $(wildcard src/htslib/cram/*.c)
OBJECTS_LIB  = $(SOURCES_LIB:.c=.o)

$(EXEC): $(OBJECTS) $(OBJECTS_TEST) $(OBJECTS_LIB)
    g++ $(OBJECTS) $(OBJECTS_TEST) $(OBJECTS_LIB) -DBACKWARD_HAS_BFD -g -lpthread -lz -lhts -L $(HTSLIB) -o $(EXEC)

%.o: %.c
    gcc -g -c -DBACKWARD_HAS_BFD -I src/htslib -I $(INCLUDE) -I $(EIGEN) -I ${BOOST} $&lt; -o $@

%.o: %.cpp
    g++ -g -DK_HACK -DBACKWARD_HAS_BFD -c -std=c++11 -I src/htslib -I src/stats -I $(INCLUDE) -I $(EIGEN) -I ${BOOST} $&lt; -o $@

clean:
    rm -f $(EXEC) $(OBJECTS) $(OBJECTS_TEST)


My new Makefile:

#
# Please modify only BOOST, EIGEN and HTSLIB. You should be able to leave all other options intact. C++ compiler with C++11 support is mandatory.
#

# Boost C++ library
BOOST = /usr/local/include/boost_1_64_0

# Linear-algebra library
EIGEN = /usr/local/Cellar/eigen/3.2.8/include/eigen3

# HTSLIB library for reading BAM files
HTSLIB = /Users/tedwong/Sources/QA/htslib

CC     = g++
CFLAGS = -g -O2
CPPFLAGS = -c -std=c++11
DFLAGS = 
#DFLAGS = -DBACKWARD_HAS_BFD # https://github.com/bombela/backward-cpp
LIBS   = -lpthread -lz -lhts

# Where the header are (no need to modify this)
INCLUDE = src

EXEC         = anaquin
SOURCES      = $(wildcard src/*.cpp src/tools/*.cpp src/analyzers/*.cpp src/RnaQuin/*.cpp src/VarQuin/*.cpp src/MetaQuin/*.cpp src/data/*.cpp src/parsers/*.cpp src/writers/*.cpp src/stats/*.cpp src/cufflinks/*.cpp)
OBJECTS      = $(SOURCES:.cpp=.o)
OBJECTS_TEST = $(SOURCES_TEST:.cpp=.o)
SOURCES_LIB  = $(wildcard src/htslib/cram/*.c)
OBJECTS_LIB  = $(SOURCES_LIB:.c=.o)

$(EXEC): $(OBJECTS) $(OBJECTS_TEST) $(OBJECTS_LIB)
    $(CC) $(OBJECTS) $(OBJECTS_TEST) $(OBJECTS_LIB) $(CFLAGS) $(DFLAGS) $(LIBS) -L $(HTSLIB) -o $(EXEC)

%.o: %.c
    $(CC) $(CFLAGS) -c $(DFLAGS) -I $(INCLUDE) -I $(EIGEN) -I ${BOOST} $&lt; -o $@

%.o: %.cpp
    $(CC) $(CFLAGS) $(DFLAGS) $(CPPFLAGS) -I $(HTSLIB) -I src/stats -I $(INCLUDE) -I $(EIGEN) -I ${BOOST} $&lt; -o $@

clean:
    rm -f $(EXEC) $(OBJECTS) $(OBJECTS_TEST)
Couple of things you do that don't match standards.

CXX is usually the C++ compiler
CC  is usually the C   compiler.


CXXFLAGS  are the flags that are applied to the C++ compiler.
CPPFLAGS  are the flags that are applied for the pre-processor.
          This usually means passed to both C and C++ compiler.

CFLAGS    are the flags passed to the C compiler.

LDDFLAGS  are the flags passed to the linker.


Why are you building the tests into your main executable?
Should the test application be generated as a seprate application that includes the normal objects (apart from main) and the test objects.

Why do you have libs outside your lib variable?

$(LIBS) -L $(HTSLIB)


You should have a line earlier in your make file like:

# This adds more libs to the current set of libs.
LIBS    += -L $(HTSLIB)


I am confused why you are including -I ${BOOST} for the C compiler but not the C++ compiler. I did not think there was anything in the boost that could be used by C (I could be wrong but seems strange).

The default rule for C/C++/Linking are:

$(CC)  $(CPPFLAGS) $(CFLAGS) -c
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
$(CC)  $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)


Unless you need to change these I would not. This means adding values to the existing variables.

Something like this (untested):

# Addition Packages.
SRC_PACKAGES = BOOST EIGEN
LIB_PACKAGES = HTSLIB

# Boost C++ library
ROOT_BOOST▸ = /usr/local/include/boost_1_64_0

# Linear-algebra library
ROOT_EIGEN = /usr/local/Cellar/eigen/3.2.8/include/eigen3

# HTSLIB library for reading BAM files
ROOT_HTSLIB = /Users/tedwong/Sources/QA/htslib

#
# Turn on BFD by compiling with
# make -DHASBFD=1
DFLAGS_1▸   = -DBACKWARD_HAS_BFD # https://github.com/bombela/backward-cpp
DFLAGS▸ ▸   = $(DFLAGS_$(HASBFD))

EXTRA_INCLUDE_DIR▸  = $(foreach loop, $(SRC_PACKAGES) $(LIB_PACKAGES), -I$(ROOT_$(loop)))
EXTRA_LIB_DIR▸  ▸   = $(foreach loop, $(LIB_PACKAGES),                 -L$(ROOT_$(loop)))

# Compiler
CXX▸▸   ▸   = g++ 
CC▸ ▸   ▸   = $(CXX)
CPPFLAGS▸   += -g -O2 $(EXTRAFLAGS) $(DFLAGS) -Isrc -Isrc/stats
CFLAGS▸ ▸   +=
CXXFLAGS▸   += -std=c++11

# Linker
LDFLAGS▸▸   += $(EXTRA_LIB_DIR)
LDLIBS▸ ▸   += -lpthread -lz -lhts

# Application
SRC_DIR▸▸   = src src/tools src/analyzers src/RnaQuin src/VarQuin src/MetaQuin src/data src/parsers src/writers src/stats src/cufflinks

EXEC        = anaquin
SOURCES     = $(wildcard $(foreach loop, $(SRC_DIR), $(loop)/*.cpp))
OBJECTS     = $(patsubst $(SOURCE), %.cpp, %.o)

$(EXEC): $(OBJECTS)

.PHONEY: clean
clean:
    $(RM) $(EXEC) $(OBJECTS) $(OBJECTS_TEST)