makefile can't find include file path even with -I flag - makefile

Compiling with Makefile tells me that it can't find path to some include files.
Here's my directory layout:
build (empty directory)
include (directory)
tpu_uarch (directory)
buffer.hpp common.hpp controller.hpp cpu.hpp
dram.hpp interconnect.hpp mmu.hpp unit.hpp weightfetcher.hpp
obj (directory)
tpu_uarch (empty directory)
src (directory)
test_mmu.cpp test_tile.cpp
buffer.cpp common.cpp controller.cpp cpu.cpp
dram.cpp interconnect.cpp mmu.cpp weightfetcher.cpp
Makefile
And here's what Makefile looks like:
TESTTILE := ./build/testtile.exe
TEST3 := ./build/test3.exe
CC := g++
CPP_SUFFIX := cpp
INCLUDE_DIR := -I./include
SRC_DIR = ./src
OBJ_DIR = ./obj
CFLAGS := -g -Wall -std=c++11
LDFLAGS :=
LIBS :=
# all sources
SRC = $(wildcard $(SRC_DIR)/*.$(CPP_SUFFIX))
SRC += $(wildcard $(SRC_DIR)/**/*.$(CPP_SUFFIX))
# objects
OBJ = $(patsubst $(SRC_DIR)/%.$(CPP_SUFFIX), $(OBJ_DIR)/%.o, $(SRC))
DIR = $(dir $(OBJ))
# executables
testtile: dir $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(TESTTILE) $(LIBS)
test3: dir $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o $(TEST3) $(LIBS)
dir:
mkdir -p $(DIR)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.$(CPP_SUFFIX)
$(CC) $(INCLUDE_DIR) $(CFLAGS) -c $< -o $#
clean:
rm -rf $(OBJ_DIR)
rm $(TESTTILE)
rm $(TEST3)
When I write make test3 in command line, I get the following error.
mkdir -p ./obj/ ./obj/ ./obj/tpu_uarch/ ./obj/tpu_uarch/ ./obj/tpu_uarch/ ./obj/tpu_uarch/ ./obj/tpu_uarch/ ./obj/tpu_uarch/ ./obj/tpu_uarch/ ./obj/tpu_uarch/
g++ -I./include -g -Wall -std=c++11 -c src/test_tile.cpp -o obj/test_tile.o
src/test_tile.cpp:1:22: fatal error: common.hpp: No such file or directory
compilation terminated.
Makefile:44: recipe for target 'obj/test_tile.o' failed
make: *** [obj/test_tile.o] Error 1
In all of the *.cpp files, they add include files like #include "common.hpp" without adding directory information. As I understand, adding the -I flag in INCLUDE_DIR should solve problems of finding the include files.
I've checked earlier that the code compiles if I put all .cpp and .hpp files in one directory and type g++ -g -Wall -std=c++11 -o test3.exe buffer.cpp common.cpp controller.cpp cpu.cpp dram.cpp interconnect.cpp mmu.cpp weightfetcher.cpp test_mmu.cpp in the command line interface.
In making test3.exe, test_tile.cpp is not used but I don't think that should be a problem.
Is there something I'm missing or should look into?
Any help or push in the right direction would be greatly appreciated.

[Moved from comments]
You're telling g++ to look in ./include but, according to the directory hierarchy shown, common.hpp and the other headers are actually under ./include/tpu_uarch. You need...
INCLUDE_DIR := -I./include/tpu_uarch

For those who came to find an answer... Even after fixing the issue that G.M. pointed out, I still had some minor issues. (Such as conflict in that both test files include the main() function, etc.)
After that, I managed to fix the code to work.
Here is the working version of Makefile.
TESTTILE := ./build/testtile.exe
TESTMMU := ./build/testmmu.exe
CC := g++
CPP_SUFFIX := cpp
INCLUDE_DIR := -I./include/tpu_uarch
SRC_DIR = ./src
OBJ_DIR = ./obj
BUILD_DIR = ./build
CFLAGS := -g -Wall -std=c++11
LDFLAGS :=
LIBS :=
# all sources
SRC = $(wildcard $(SRC_DIR)/*.$(CPP_SUFFIX))
SRC += $(wildcard $(SRC_DIR)/**/*.$(CPP_SUFFIX))
# objects
OBJ = $(patsubst $(SRC_DIR)/%.$(CPP_SUFFIX), $(OBJ_DIR)/%.o, $(SRC))
DIR = $(dir $(OBJ))
# for tests
TESTTILE_OBJ := ./obj/test_tile.o
TESTMMU_OBJ := ./obj/test_mmu.o
# executables
testtile: dir $(OBJ) $(TESTTILE_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(TESTTILE_OBJ) -o $(TESTTILE) $(LIBS)
testmmu: dir $(OBJ) $(TESTMMU_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(TESTMMU_OBJ) -o $(TESTMMU) $(LIBS)
dir:
mkdir -p $(DIR)
obj/test_tile.o: $(BUILD_DIR)/test_tile.cpp
$(CC) $(INCLUDE_DIR) $(CFLAGS) -c ./build/test_tile.cpp -o ./obj/test_tile.o
obj/test_mmu.o: $(BUILD_DIR)/test_mmu.cpp
$(CC) $(INCLUDE_DIR) $(CFLAGS) -c ./build/test_mmu.cpp -o ./obj/test_mmu.o
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.$(CPP_SUFFIX)
$(CC) $(INCLUDE_DIR) $(CFLAGS) -c $< -o $#
clean:
rm -rf $(OBJ_DIR)
rm $(TESTTILE)
rm $(TEST3MMU)
The directory topology is as follows:
build (directory)
test_mmu.cpp test_tile.cpp
testmmu.exe testtile.exe (executables created after running make)
include (directory)
tpu_uarch (directory)
buffer.hpp common.hpp controller.hpp cpu.hpp
dram.hpp interconnect.hpp mmu.hpp unit.hpp weightfetcher.hpp
obj (directory, all contents here including directory are created after running make)
tpu_uarch (directory)
buffer.o common.o controller.o cpu.o
dram.o interconnect.o mmu.o weightfetcher.o
test_mmu.o
test_tile.o
src (directory)
tpu_uarch (directory)
buffer.cpp common.cpp controller.cpp cpu.cpp
dram.cpp interconnect.cpp mmu.cpp weightfetcher.cpp
Makefile
Hope this helps.

Related

How can I modify my Makefile so that I build two different executables

I have a Makefile that works correctly, but now I want to modify it so that I can build two different executables (i.e. client.exe, server.exe). In my directory, I have a client.cpp and a server.cpp, each of which has a main function. I know I can't build an executable with more than one main function. Ultimately, I want to be able to build an executable (client.exe or server.exe) using 'make client', 'make server', or something to that effect.
I have seen similar questions on this website, but all of the solutions I have seen assume that the number of source files will not change. Take for example this solution: Makefile to compile multiple C programs? Or this question: How can I configure my makefile for debug and release builds?
I do not want to have to update my Makefile every time I add a new source file.
How can I modify my Makefile so that I build two different executables?
SRC_DIR := src
OBJ_DIR := obj
BIN_DIR := bin
EXE := $(BIN_DIR)/client.exe
SRC := $(wildcard $(SRC_DIR)/*.cpp)
OBJ := $(subst $(SRC_DIR),$(OBJ_DIR),$(SRC:.cpp=.o))
DEP := $(OBJ:.o=.d)
.PHONY: clean
all: $(EXE)
CXX := g++
CPPFLAGS := -I$(PWD) -MMD -MP
CXXFLAGS := -std=c++17
LDFLAGS := -L /usr/lib/x86_64-linux-gnu
CFLAGS := -Wall
$(EXE): $(OBJ) | $(BIN_DIR)
$(CXX) $(LDFLAGS) $^ -o $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CXX) $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS) -c $< -o $#
$(BIN_DIR) $(OBJ_DIR):
mkdir -p $#
clean:
#$(RM) -rv $(BIN_DIR) $(OBJ_DIR)
-include $(DEP)
I have tried to exclude either the client.cpp or server.cpp file depending on which command I use (e.g. 'make client' or 'make server'). But I reached a dead end since I don't know how to make a rule that excludes one file.
SRC := $(filter-out $(SRC_DIR)/client.cpp, $(wildcard $(SRC_DIR)/*.cpp))
SRC := $(filter-out $(SRC_DIR)/server.cpp, $(wildcard $(SRC_DIR)/*.cpp))
Simply build two different lists of object files for your two executables:
...
EXE := $(patsubst %,$(BIN_DIR)/%.exe,client server)
...
CLIENT_OBJ := $(filter-out $(OBJ_DIR)/server.o,$(OBJ))
SERVER_OBJ := $(filter-out $(OBJ_DIR)/client.o,$(OBJ))
.PHONY: all client server
all: $(EXE)
client: $(BIN_DIR)/client.exe
server: $(BIN_DIR)/server.exe
$(BIN_DIR)/client.exe: $(CLIENT_OBJ)
$(BIN_DIR)/server.exe: $(SERVER_OBJ)
$(EXE): | $(BIN_DIR)
$(CXX) $(LDFLAGS) $^ -o $#
...

Compile a program with source files in different folders, with makefile

So I have been trying to use the answers and the idea of this published question: Makefile: Compiling from directory to another directory
In the following excerpt code, you can see the definition of the directories, for sources and compilation objects.
all : Mpois Mkvz MBJ Mlid
# Definitions
COMPILER := gfortran -O3
LIBS := -g -fbounds-check -ffast-math -lm
# Directories of object code
OBJDIR = objects
SRCDIR = src
SOURCES := $(SRCDIR)/lbm_const.f90 $(SRCDIR)/BORDERS.f90 $(SRCDIR)/CONVERGENCE.f90 $(SRCDIR)/FILESIO.f90 $(SRCDIR)/LBM.f90
OBJECTS := $(OBJDIR)/lbm_const.o $(OBJDIR)/BORDERS.o $(OBJDIR)/CONVERGENCE.o $(OBJDIR)/FILESIO.o $(OBJDIR)/LBM.o
SOURCES_pois := $(SRCDIR)/Main_pois.f90
OBJECTS_pois := $(OBJDIR)/Main_pois.o
# Linking
Mpois: $(OBJECTS) $(OBJECTS_pois)
$(COMPILER) $^ -o $# $(LIBS)
# Compiling
$(OBJECTS): $(OBJDIR)/%.o: %.f90
$(COMPILER) -c $< -o $#
# Compiling
$(OBJECTS_pois): $(OBJDIR)/%.o: %.f90
$(COMPILER) -c $< -o $#
clean:
rm -f $(OBJDIR)/*.o
rm -f $(OBJDIR)/*.mod
rm -f $(SRCDIR)/*.mod
When running the makefile script I get the following error:
make: *** No rule to make target 'lbm_const.f90', needed by 'objects/lbm_const.o'. Stop.
Interesting is to note that when SRCDIR = src changes to SRCDIR = . the makefile compiles even having files in folder src.

Makefile doesn't find source files

I have tried to make a makefile. I have the following folder structure.
Source
- include
- My headerfiles
- objects
- The object files
- src
- My source files
My problem is that the source files in the src directory isn't found.
My make file looks as the following.
# gcc for C
# g++ for c++
CC = gcc
#compiler flags
# -g adds debugging information to the executebells
# -Wall
CFLAGS = -g -Wall
#target
TARGET = gabe_the_dog_server
#directory for the object files
OBJDIR = ./objects
SRCDIR = ./src
default: $(TARGET)
all: default
HEADERS = $(wildcard include/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $#
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(CFLAGS) $(LIBS) -o $(OBJDIR)/$#
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
-rm -f *.o
-rm -f $(TARGET)
Here:
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
You use the variable SOURCES, but you never define it. You need one more line:
SOURCES = $(wildcard $(SRCDIR)/*.c)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
Instead of using the path to your source files, it's recommended that you put this path in the special variable named VPATH. Then you just mention your source file, like this:
OBJDIR = ./obj
SRCDIR = ./src
VPATH = $(SRCDIR)
OBJECTS = $(addprefix $(OBJDIR)/, foo.o bar.o)
all: $(OBJECTS)
$(OBJDIR)/%.o: %.c
$(cc) ...
GNU make will look in the folders present in VPATH for the files that are prerequisites of a target. Note that this could be a problem if you have multiple folders where you can find multiple times the same file name.
See GNU make VPATH manual. If you need additional examples of VPATH good practices, see this link as well: Mad Scientist: How not to use VPATH

Create Directory using MakeFile

I wrote a MakeFile, but I need it to create folder OBJ, so, for this, I tried a lot of things... based on this link:
https://stackoverflow.com/questions/ask
So, that is my makefile
IDIR =.
CC=gcc
CFLAGS=-I$(IDIR) -Wall -g
SRCDIR=src
ODIR=obj
LIBS=-ltest
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
OUTPUTDIR = ../bin
$(ODIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $# $< $(CFLAGS)
$(OUTPUTDIR)/test: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
I need to create the obj folder, I tried that idea:
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir -p $(OBJDIR)
and this:
MKDIR_P = mkdir -p
.PHONY: directories
all: directories program
directories: ${OUT_DIR}
${OUT_DIR}:
${MKDIR_P} ${OUT_DIR}
But apparently every time I called the makefile, it ignored the command to create the directory OBJ and began compiling directly...
How I can make to makefile create the directory?
Another approach is to have a dummy variable that evaluates early in the parse of the Makefile and produces the required folder.
ODIR = obj_64
dummy_build_folder := $(shell mkdir -p $(ODIR))
Then the rest of the Makefile can safely assume that $(ODIR) exists.
I've used this on various Linux flavors, and Solaris, with GNU Make 3.81.
Try this:
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR): FORCE
mkdir -p $(OBJDIR)
FORCE:

Generate object files in subdirectory using a Makefile

I am trying to create a Makefile in order to generate object files in a subdirectory rather than let them in the src/ folder.
Here is the structure of the project:
Trunk
- Server
- src/
- include/
- Common
- src/
- include/
The Makefile is located in Trunk/Server. Source files are located both in Server/src and Common/src, so the Makefile currently has something like this:
SRC = src/main.cpp \
src/Network.cpp \
../Common/src/SQLManager.cpp \
../Common/src/Utils.cpp
I woud like to put generated object files in respective obj folders, so Trunk/Server/obj and Trunk/Common/obj. How can I achieve this? I've found many ways to generate object files in subdirectories (vpath, patsubst and many more) but I can't make any of them work for this folder organization.
Edit: If there is a way to put all object files in Server/obj/, that would be ok too.
Here's the complete Makefile (minus some source files and linked libraries):
Edit2: Updated with Didier Trosset's changes
CXX = g++
RM = rm -vf
NAME = Server
SRC = src/main.cpp \
src/Network.cpp \
../Common/src/SQLManager.cpp \
../Common/src/Utils.cpp
OBJ = $(subst src/,obj/, $(subst .cpp,.o, $(SRC)))
LDFLAGS = -lpthread -lm
CPPFLAGS = -std=c++0x -pedantic -Wextra -Wall -Wconversion -Iinclude -I../Common/include
all: Server
%.o: %.cpp
$(CXX) $< -o $#
Server: $(OBJ)
$(CXX) -o $(NAME) $(OBJ) $(LDFLAGS)
clean:
$(RM) $(OBJ) *~
fclean: clean
$(RM) $(NAME)
re: fclean Server
.PHONY: all clean fclean Server
Given these definitions, subst should be used to substitute the src part of the directory, and the file extension.
OBJ = $(subst src/,bin/,$(subst .cpp,.o,$(SRC)))
Then, you have to add new pattern rules to compile your source files. (You have to write one pattern rule per directory where your source files are.)
obj/%.o: src/%.cpp
$(CXX) -c $< -o $#
../Common/obj/%.o: ../Common/src/%.cpp
$(CXX) -c $< -o $#
I'm not sure that this will work, but I would try something like:
OBJ := $(join $(addsuffix ../obj/,$(dir $(SRC))),$(notdir $(SRC))
# or, as Didier suggested:
# OBJ := $(subst src/,obj/,$(SRC))
%.o: ../src/%.cpp
$(CXX) $< -o $#
It's not clear exactly what you're trying to do, but this should come close:
OBJ = $(subst src/,obj/,$(SRC:.cpp=.o))
obj/%.o : src/%.cpp
$(CXX) $< -o $#
../Common/obj/%.o : ../Common/src/%.cpp
$(CXX) $< -o $#

Resources