user15745460
user15745460

Reputation:

How to have multiple source dirs?

After doing some research, I was able to found the following makefile to compile every cpp file in my project and place every object files in the obj directory. However, it still doesn't work. I have two directories, one called src and another one called lib. I'm not able to make it work for both of these directories. Any help?

TARGET   = app
CC       = c++
CFLAGS   = -std=c++2a -Wall -I.
LINKER   = c++
LFLAGS   = -Wall -I. -lm

# change these to proper directories where each file should be
SRCDIR   = src lib
OBJDIR   = obj
BINDIR   = .

# SOURCES  := $(wildcard $(SRCDIR)/*.cpp)
SOURCES  := $(wildcard */*.cpp ) # Match every c++ file
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS  := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
rm       = rm -f

$(BINDIR)/$(TARGET): $(OBJECTS)
    @$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
    @echo "Linking complete!"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
    @$(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

.PHONY: clean
clean:
    @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONY: remove
remove: clean
    @$(rm) $(BINDIR)/$(TARGET)
    @echo "Executable removed!"

It will compile every file inside the src directory but it will ignore the lib directory. Can someone read it and explain me what I'm doing wrong?

Upvotes: 0

Views: 325

Answers (1)

Altaf
Altaf

Reputation: 3086

Please see below code which will help you to compile from src and lib directory all C++ files:

TARGET   = app
CC       = c++
CFLAGS   = -std=c++2a -Wall -I.
LINKER   = c++
LFLAGS   = -Wall -I. -lm

# change these to proper directories where each file should be
# SRCDIR   = src lib
# I created a separate variable for src and lib path
SRC_PATH =./src/
LIB_PATH =./lib/
OBJDIR   = obj
BINDIR   = .

# Collect all cpp files from src and lib folder
SOURCES  := $(shell find $(SRC_PATH) $(LIB_PATH) -type f -name '*.cpp' ) 
# Collect all headers from src and lib folder
INCLUDES := $(shell find $(SRC_PATH) $(LIB_PATH) -type f -name '*.h' )
# Get all object files from SOURCES
OBJECTS   := $(patsubst %.cpp, $(OBJDIR)/%.o,   $(notdir $(SOURCES)))
rm       = rm -f

$(BINDIR)/$(TARGET): $(OBJECTS)
    @$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
    @echo "Linking complete!"

$(OBJDIR)/%.o : $(SRCDIR)/%.cpp
    @$(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

$(OBJDIR)/%.o : $(LIB_PATH)/%.cpp
    @$(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

.PHONY: clean
clean:
    @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONY: remove
remove: clean
    @$(rm) $(BINDIR)/$(TARGET)
    @echo "Executable removed!"

You could also do it in below way without creating separate variable for src and lib:

TARGET   = app
CC       = c++
CFLAGS   = -std=c++2a -Wall -I.
LINKER   = c++
LFLAGS   = -Wall -I. -lm

# change these to proper directories where each file should be
SRCDIR   = src lib
OBJDIR   = obj
BINDIR   = .

# Collect all cpp files from src and lib folder
SOURCES  := $(shell find $(SRCDIR) -type f -name '*.cpp' ) 
# Collect all headers from src and lib folder
INCLUDES := $(shell find $(SRCDIR) -type f -name '*.h' )
# Get all object files from SOURCES
OBJECTS   := $(patsubst %.cpp, $(OBJDIR)/%.o,   $(notdir $(SOURCES)))
rm       = rm -f

$(BINDIR)/$(TARGET): $(OBJECTS)
    @$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
    @echo "Linking complete!"

$(OBJECTS): $(OBJDIR)/%.o : %.cpp
    @$(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

.PHONY: clean
clean:
    @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONY: remove
remove: clean
    @$(rm) $(BINDIR)/$(TARGET)
    @echo "Executable removed!"

vpath %.cpp $(wildcard *)

Upvotes: 1

Related Questions