Makefile: Adding 2nd directory for .h and .cpp files - makefile

I am adapting my Makefile to look into 4 directories, rather than 2 (it had one for source files and one for header files, but I've added a new folder for common source and include). I have something like follows:
CC = g++
FLAGS = -g -c
BUILDDIR = build
INCLUDEDIR = -Icode/inc -I../common/code/inc -I/usr/include/libxml2
SOURCEDIR = code/src ../common/code/src
SOURCES = $(wildcard $(SOURCEDIR)/*.cpp)
OBJECTS = $(patsubst $(SOURCEDIR)/%.cpp,$(BUILDDIR)/%.o,$(SOURCES))
EXECUTABLE = Exec
all: $(BUILDDIR)/$(EXECUTABLE)
$(BUILDDIR)/$(EXECUTABLE): $(OBJECTS)
$(CC) $^ -o $# -lpthread -lxml2
$(OBJECTS): $(BUILDDIR)/%.o : $(SOURCEDIR)/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
I tried to add one entry to INCLUDEDIR as follows:
-I../common/code/inc
And added ../common/code/src to SOURCEDIR:
SOURCEDIR = code/src ../common/code/src
This is not currently working and I am wondering how to fix it please. I am getting the error:
Makefile:27: target `code/src' doesn't match the target pattern
but I cannot find how to fix it so far. Any help would be appreciated.
EDIT: After following MadScientist response below, I am getting the following output:
g++ -c -o code/src/Client.o code/src/Client.cpp
code/src/Client.cpp:1:20: fatal error: Client.h: No such file or directory
compilation terminated.
make: *** [code/src/Client.o] Error 1
Updated Makefile:
SOURCEDIR = code/src ../common/code/src
SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCEDIR)))
OBJECTS = $(SOURCES:%.cpp=%.o)
$(BUILDDIR)/$(EXECUTABLE): $(OBJECTS)
$(CC) $^ -o $# -lpthread -lxml2
$(BUILDDIR)/%.o : ../common/code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
$(BUILDDIR)/%.o : code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
PS:
I was able to fix it using the following:
SOURCEDIR = code/src ../common/code/src
SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCEDIR)))
TEMP_OBJ = $(SOURCES:%.cpp=%.o)
NOT_DIR = $(notdir $(TEMP_OBJ))
OBJECTS = $(addprefix $(BUILDDIR)/, $(NOT_DIR))

Sure, because now your static pattern rule expands to:
$(OBJECTS): build/%.o : code/src ../common/code/src/%.cpp
which is illegal syntax. If you avoid using static pattern rules, and instead use pattern rules, then it will just work. Replace your single static pattern rule with two pattern rules:
$(BUILDDIR)/%.o : code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
$(BUILDDIR)/%.o : ../common/code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
EDIT: you also need to change other uses of SOURCEDIR:
SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCEDIR))
OBJECTS = $(patsubst %.cpp,$(BUILDDIR)/%.o,$(notdir $(SOURCES)))

Related

Static pattern rule for makefile

I have to make a static pattern rule in this makefile to avoid to use all the source files for each executable file.
CC = gcc
CFLAGS = -Wall
LDFLAGS =
OBJFILES = structuri_c.o structuri_1.o structuri_2.o structuri_3.o structuri_4.o
TARGET = structuri_c structuri_1 structuri_2 structuri_3 structuri_4
all: $(TARGET)
$(TARGET): $(OBJFILES)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LDFLAGS)
clean:
rm -f $(OBJFILES)
Can you help me to do this and to understand why i should do this ?
In this part :
TARGET = structuri_c structuri_1 structuri_2 structuri_3 structuri_4
all: $(TARGET)
$(TARGET): $(OBJFILES)
I have to make that static pattern rule

How to efficiently write a GNU makefile with several modules with an arbitrary number of dependencies in Fortran

My makefile currently looks like this:
#Source file locations
VPATH = :../AHMCodePara
#Compiler
CC = mpifort
#Debugging Flags
#Flags =
#Regular flags
Flags = -Ofast -mkl=sequential
# File name labels
FF =
DE =
Const =
OBJDIR = OBJ
# make object directory
$(OBJDIR):
-mkdir $(OBJDIR)
CC += -module $(OBJDIR)
#Object File List
Inputs =
Tools = $(OBJDIR)/$(Const)Inputs.o
Diag$(DE) = $(Tools)
PreAnalysis = $(Tools) $(OBJDIR)/Tools.o
DOSsetupPara$(DE) = $(PreAnalysis) $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o
$(Const)AHMRGv3 = $(Tools) $(OBJDIR)/Diag$(DE).o $(OBJDIR)/DOSsetupPARA$(DE).o
#Object File List
obj = $(OBJDIR)/$(Const)Inputs.o $(OBJDIR)/Diag$(DE).o $(OBJDIR)/Tools.o \
$(OBJDIR)/PreAnalysis.o $(OBJDIR)/DOSsetupPARA$(DE).o $(OBJDIR)/$(Const)AHMRGv3.o
# dependence files
$(OBJDIR)/%.o: %.f90 $(%)
# #$(%)
#-rm -f #<~
$(CC) -c $< -o $# $(Flags)
All: V3.e
# Target
V3.e: $(obj)
$(CC) $(Flags) -o $# $^
clean:
rm $(OBJDIR)/*.o $(OBJDIR)/*.mod
It used to be similar to this one:
LOC = ../../AHMCode/
CC = gfortran
#Debugging
#Flags = -O0 -g -fcheck=all -Wall -llapack
#Normal
Flags = -O3 -I/usr/lib/ -L/usr/lib/ -lblas -llapack
FF = _Old
IG = #IGNORE or nothing
TT = #TYPE or nothing
V3$(FF).e: Inputs.o Tools.o PreAnalysis.o DOSsetup$(IG).o Diag$(TT).o AHMRGv3_Manyruns.o
$(CC) $(Flags) AHMRGv3_Manyruns.o Diag$(TT).o DOSsetup$(IG).o PreAnalysis.o Tools.o Inputs.o -o V3$(FF).e
Inputs.o: Inputs.f90
$(CC) $(Flags) -c Inputs.f90
Tools.o: $(LOC)Tools.f90 Inputs.o
$(CC) $(Flags) -c $(LOC)Tools.f90
PreAnalysis.o: $(LOC)PreAnalysis.f90 Inputs.o Tools.o
$(CC) $(Flags) -c $(LOC)PreAnalysis.f90
DOSsetup$(IG).o: $(LOC)DOSsetup$(IG).f90 Inputs.o Tools.o PreAnalysis.o Diag$(TT).o
$(CC) $(Flags) -c $(LOC)DOSsetup$(IG).f90
Diag$(TT).o: $(LOC)Diag$(TT).f90 Inputs.o
$(CC) $(Flags) -c $(LOC)Diag$(TT).f90
AHMRGv3_Manyruns.o: AHMRGv3_ManyRuns.f90 DOSsetup$(IG).o Diag$(TT).o Inputs.o
$(CC) $(Flags) -c AHMRGv3_Manyruns.f90
clean:
rm *.o *.mod
The section I want to compare in these makefiles is the .o file definitions. In the second makefile, I wrote these all out by hand and it worked great. My intention with the second makefile was to do the same thing but more efficiently.
The problems arose with dependencies. When I initially made changes to my makefile, I didn't put any dependencies at all. This led to problems where I would update Inputs and the relevant files wouldn't recompile (e.g. Tools.o). This is as expected so I've been looking for ways to add dependencies in a creative and efficient way that forces the relevant files to recompile.
As you can see I tried creating variables with the same name as the .f90 and .o to use $(%). This seemed kinda janky (and I didn't really think it would work) but unfortunately didn't solve my problem.
As you can see from the original makefile, the dependencies don't follow any sort of pattern. As well you can see that I am compiling Fortran and I'm pretty sure that -gen-dep doesn't do anything and if it does I'm doing it wrong.
Existing questions on the subject have been very unhelpful since the majority uses C++ and that can be very different here.
EDIT: I "fixed" my problem. Its not the most efficient and doesn't automatically generate dependencies but I like it in that its not a lot of repetitive lines.
#Object File List
oInpt =
oTool = $(OBJDIR)/$(Const)Inputs.o
oPreA = $(oTool) $(OBJDIR)/Tools.o
oDOSs = $(oPreA) $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o
oDiag = $(oTool)
oMain = $(oTool) $(OBJDIR)/Diag$(DE).o $(OBJDIR)/DOSsetupPARA$(DE).o
obj = $(OBJDIR)/$(Const)Inputs.o $(OBJDIR)/Tools.o $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o \
$(OBJDIR)/DOSsetupPARA$(DE).o $(OBJDIR)/$(Const)AHMRGv3.o
# dependence files
$(OBJDIR)/$(Const)Inputs.o: $(oInpt)
$(OBJDIR)/Tools.o: $(oTool)
$(OBJDIR)/PreAnalysis.o: $(oPreA)
$(OBJDIR)/Diag$(DE).o: $(oDiag)
$(OBJDIR)/DOSsetupPARA$(DE).o: $(oDOSs)
$(OBJDIR)/$(Const)AHMRGv3.o: $(oMain)
$(OBJDIR)/%.o: %.f90
#-rm -f #<~
$(CC) -c $< -o $# $(Flags)
All: V3.e
# Target
V3.e: $(obj)
$(CC) $(Flags) -o $# $^
I just made multiple rules for each target. One a default rule that actually compiles the .o files and the other that specifies the dependencies for each .f90 file.

makefile multiple main with wildcard

I would like to compile many mains that are automatically found in a folder containing many mains.
SOURCES = $(wildcard src/shared/*.cc)
OBJECTS = $(SOURCES:%.cc/%.o)
MAINS_SOURCES = $(wildcard src/mains/*.cc)
MAINS_OBJECTS = $(MAINS_SOURCES:%.cc=%.o)
PROGRAMS_NAME = $(MAINS_SOURCES:src/mains/%.cc=%)
For now I have this code that of course, does not work with more than one main.
$(PROGRAMS_NAME):$(OBJECTS) $(MAINS_OBJECTS)
$(CXX) $(LIBS) $(OBJECTS) $(MAINS_OBJECTS) -o $#
How could I split $(MAINS_OBJECTS) correctly for each main ?
Thanks !
For this kind of situations static pattern rules are frequently handy:
SOURCES = $(wildcard src/shared/*.cc)
OBJECTS = $(SOURCES:%.cc/%.o)
MAINS_SOURCES = $(wildcard src/mains/*.cc)
MAINS_OBJECTS = $(MAINS_SOURCES:%.cc=%.o)
PROGRAMS_NAME = $(MAINS_SOURCES:src/mains/%.cc=%)
$(OBJECTS) $(MAINS_OBJECTS): %.o: %.cc
$(CXX) $(CXXFLAGS) -c $< -o $#
$(PROGRAM_NAME): %: src/mains/%.o $(OBJECTS)
$(CXX) $(LIBS) $^ -o $#

Makefile which can generate all object files in a specific path

Somewhere I am going wrong !!
I am trying to generate the object files in ../bin/
But the below code generates in corresponding source file directory.
Below the code, which I am running.
Modified code:
LIB = $(BIN_DIR)/libutils.a
APP = $(BIN_DIR)/app
CC = gcc
AR = ar
CFLAGS = -Wall -g
LDFLAGS =
all: $(LIB) $(APP)
SRC = $(SRC_DIR)/add.c \
$(SRC_DIR)/sub.c
OBJ = $(SRC:.c=.o)
INCLUDES = -I$(INC_DIR)/
LIBS = -L../ -L/usr/local/lib -lm
LDFLAGS = -g
.SUFFIXES: .c
.c.o:
$(CC) $(INCLUDES) -c $(SRC_DIR)/$< -o $(BIN_DIR)/$#
$(LIB): $(OBJ)
$(AR) rcs $(LIB) $(OBJ)
$(BIN_DIR)/app: $(BIN_DIR)/test.o \
$(BIN_DIR)/t.o \
$(BIN_DIR)/libutils.a
$(CC) $(LDFLAGS) -o $# $^
clean:
rm -f $(LIB) $(BIN_DIR)/* $(SRC_DIR)/*.o *.o
Thank you :)
You still have the rule:
$(LIB): $(OBJ)
...
and OBJ is still src_dir/add.o src_dir/sub.o, so that's where Make will try to build these objects if your object rule works as intended. So, first step:
SRC = $(SRC_DIR)/add.c \
$(SRC_DIR)/sub.c
OBJ = $(SRC:.c=.o)
OBJ = $(patsubst $(SRC_DIR)/%.c,$(BIN_DIR)/%.o,$(SRC))
Now you'll find that your object rule,
.c.o:
...
doesn't work, because it expects to find the source file in the same place where the object file should go (i.e. $(OBJ_DIR)). So replace this rule with:
$(BIN_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(INCLUDES) -c $< -o $#
I notice that you have no provision for building $(BIN_DIR)/t.o and $(BIN_DIR)/test.o, but the app needs them. You should look into that.
Further refinements are possible, but this is a start.
Your SRC has a relative path, and your OBJ is just the SRC with the extension changed to. o
So OBJ will contain this:
../src/add.o
../src/sub.o
And there is where the .o will be created.
Make these changes and it will work:
SRC = add.c \
sub.c
.c.o:
$(CC) $(INCLUDES) -c ../src/$< -o ../bin/$#

patsubst on makefile

I have to create different *.o files from a same set of *.c using various CFLAGS. I wanted to use patsubst to generate different *.o files from same *.c. I am doing something wrong the following statement, please help (I want to generate one set of object files having ($<)_O0.o and the other ($<)_O2.o from the same set of c source files):
$(CC) $(CFLAGS_02) -c $< -o $(patsubst %.c,%_O2.o,$<)
Thanks
Use patsubst to make lists of the objects that you want to build, and then use separate rules for each type of build.
Something like this:
SRC_FILES = source1.c source2.c
OBJ_FILES_O0 = $(patsubst %.c,%_O0.o,$(SRC_FILES))
OBJ_FILES_O2 = $(patsubst %.c,%_O2.o,$(SRC_FILES))
CFLAGS_O0 := -O0
CFLAGS_O2 := -O2
all: $(OBJ_FILES_O0) $(OBJ_FILES_O2)
$(OBJ_FILES_O0): %_O0.o: %.c
$(CC) $(CFLAGS_O0) -c $< -o $#
$(OBJ_FILES_O2): %_O2.o: %.c
$(CC) $(CFLAGS_O2) -c $< -o $#
You can also use wild cards to specify all files in the directory.
eg:
#Generic Makefile.
CC := g++
LD := g++
CFLAGS := -c
LDFLAGS := -L<path to lib> -l<libname> \
-L<path to lib> -l>libname> \
......................
ifeq (${TARGETARCH}, debug)
CFLAGS += -g -O0
elif
CFLAGS += -O4 -DNDEBUG
SRCFILES := $(wildcard *.cpp)
OBJFILES := $(patsubst %.cpp, %.o, ${SRCFILES})
all: main
main: ${OBJFILES}
#echo "[Linking]"$#
${LD} ${LDFLAGS} ${OBJFILES}
%.o: %.cpp
#echo "[Compiling]"$#
${CC} ${CFLAGS} $^ -o $#

Resources