This is my direcctoriy
Image
What i dont know is why I get the message
no targets.stop
CFLAGS := -g -std=c++11# -Wall
LIB := -L lib -lboost_thread-mt -lboost_filesystem-mt -lboost_system-mt
# ALL SERVER %.o
/build/server/%.o: /src/server.cpp /lib/server/%.cpp
g++ $(CFLAGS) /src/server.cpp /lib/server/%.cpp -o -c $# $^
You should define the "all" target with object files as dependencies, in order to run the command "make" or "make all".
There are also some mistakes in makefile syntax and on paths. Here are suggestion of solution:
SRCS := ./src/server.cpp ./lib/server/server.cpp # input source files
OBJS := ./build/server/user.o ./build/server/server.o # output object files
# ALL TARGET
all: $(OBJS)
$(OBJS): $(SRCS)
g++ ... # to complete to generate object files from source files
Related
Summarize the problem
I would like to change the compilation for a single source file, like so:
%.exe: %.c
ifeq($#, cannon.exe)
$(CC) $(CFLAGS) -o $(patsubst %.exe,%,$#) $^ $(inc_flags) $(LDLIBS)
else
$(CC) $(CFLAGS) -o $(patsubst %.exe,%,$#) $^
endif
but it doesn't work!
Describe what you’ve tried
I have tried getting bash conditionals involved, but I couldn't figure it out and I shouldn't have to mix bash and make.
Here's the full Makefile:
CC := gcc
CFLAGS := -g -Wall -Wextra
LDLIBS := -lm
inc_dirs := math.h stdio.h
inc_flags := $(addprefix -I,$(inc_dirs))
executable:=cannon.exe
source:=$(executable:%.exe=%.cpp)
.DELETE_ON_ERROR:
all: $(executable)
%.exe: %.c
ifeq($#, cannon.exe)
$(CC) $(CFLAGS) -o $(patsubst %.exe,%,$#) $^ $(inc_flags) $(LDLIBS)
else
$(CC) $(CFLAGS) -o $(patsubst %.exe,%,$#) $^
endif
clean:
rm -f $(executable:%.exe=%)
It turns out that if you want to do a special case for a certain source file, you can just define its recipe explicitly! Make will take explicit over implicit rules. Full working code below.
CC := gcc
CFLAGS := -g -Wall -Wextra
LDLIBS := -lm
inc_dirs := math.h stdio.h
inc_flags := $(addprefix -I,$(inc_dirs))
executable:=cannon.exe
source:=$(executable:%.exe=%.cpp)
# no deps so no objs
.DELETE_ON_ERROR:
all: $(executable)
%.exe: %.c
$(CC) $(CFLAGS) -o $(patsubst %.exe,%,$#) $^
cannon.exe: cannon.c
$(CC) $(CFLAGS) -o $(patsubst %.exe,%,$#) $^ $(inc_flags) $(LDLIBS)
clean:
rm -f $(executable:%.exe=%)
A better / more make-ish solution is to use constructed variable names, like this:
CC := gcc
CFLAGS := -g -Wall -Wextra
LDLIBS := -lm
inc_dirs := math.h stdio.h
cannon_CFLAGS := $(addprefix -I,$(inc_dirs))
executable := cannon.exe
source := $(executable:%.exe=%.cpp)
# no deps so no objs
.DELETE_ON_ERROR:
all: $(executable)
%.exe: %.c
$(CC) $(CFLAGS) $($*_CFLAGS) -o $# $^
clean:
rm -f $(executable:%.exe=%)
Notes:
Your rules should always create the same name as the target in the makefile. It's not right for the target to be named foo.exe but the build command creates a file named foo. If you want to create a file named foo, then the makefile target should be named foo. Basically you should always create the file contained in the make variable $#.
Is it really the case that the directories you have are named math.h and stdio.h? That's.... bizarre. And very likely to cause serious problems. If math.h and stdio.h are files, then you should not add them with -I because -I takes directory names, in which to search file files. It doesn't take filenames.
If you really did create local files named math.h and stdio.h, that's also a very bad idea: those are standard header file names and you shouldn't redeclare them yourself unless you really know what you're doing.
If you didn't create these files and you're just trying to include the standard headers math.h and stdio.h in your file, then you definitely don't need to add any flags to your compile line. Just include them.
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 $#
...
I have to make a XC8 project in Ubuntu terminal with makefile.
The directory structure is like this
Project/lib/GPIO/gpio.c
Project/lib/GPIO/gpio.h
Project/main.c
Project/Makefile
Project/build/lib/GPIO
The makefile is generating intermediate files in the Project directory itself. Actually makefile will goto each location and generates intermediate files for each .c file.
Like this
Project/gpio.d
Project/gpio.p1
Project/gpio.pre
Project/<other files>
But I wanted to generate them in Project/build/lib/GPIO instead.
i.e
Project/build/lib/GPIO/gpio.d
Project/build/lib/GPIO/gpio.p1
Project/build/lib/GPIO/gpio.pre
Project/build/<other files>
Makefile:
CHIP := 18F4580
CC := xc8
INCLUDE_PATH := /opt/microchip/xc8/v2.10/include/
PROG := /usr/share/tinybldlin/tinybldlin.py
PORT := /dev/ttyUSB0
AR := libr
SRC_DIR := $(wildcard *.c)
INC_DIR := $(wildcard *.h)
LIB_DIR := \
. \
lib \
lib/GPIO
BUILD_DIR := \
build/ \
build/lib/GPIO
TARGET := pic${CHIP}
FLASH_REGION := 0-3000
ifeq (${SRCS},)
SRCS := $(foreach libdir, $(LIB_DIR), $(wildcard $(libdir)/*.c))
endif
ifeq (${INCS},)
INCS := $(foreach libdir, $(LIB_DIR), $(wildcard $(libdir)/*.h))
endif
ifeq (${OBJS},)
OBJS := $(SRCS:.c=.obj)
endif
ifeq (${P1},)
OBJS := $(SRCS:.c=.p1)
endif
MIN_CFLAGS := --chip=${CHIP} -I${INCLUDE_PATH} --ROM=${FLASH_REGION}
# The following MSG_CFLAGS controls the compiler messages
MSG_CFLAGS := -Q
# The following OPT_CFLAGS reduces the code size
OPT_CFLAGS := --opt=all
# The following OUT_CFLAGS controls the generated outputs
OUT_CFLAGS := --asmlist --summary=psect,mem -M${TARGET}.map
EXTRA_CFLAGS += ${MSG_CFLAGS} ${OPT_CFLAGS} ${OUT_CFLAGS}
CFLAGS := ${MIN_CFLAGS} ${EXTRA_CFLAGS} -DCOMPILER=${COMPILER}
ARFLAGS := r
${TARGET}.hex: ${OBJS}
${CC} ${CFLAGS} -intel $^ -o$#
${MAKE} xclean
${TARGET}.bin: ${OBJS}
${CC} ${CFLAGS} -bin $^ -o$#
${MAKE} xclean
%.p1: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} --pass1 $<
%.obj: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} -C $<
%.as: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} -S $<
%.lib: %.obj
${AR} ${ARFLAGS} $# $<
The first thing I'll say is that this answer relies on your using GNU make. You don't say for sure that you are but since you're using pattern rules I will assume so. Note that what you want to do is not possible with standard POSIX make (unless you want to write out explicit rules for every target to be built).
You need two things:
Tell your compiler what you want to do
Tell make what you want to do
For #1, by default the compiler will generate the output which is the input file name, minus the extension (e.g. .c) plus a specific extension (e.g. .as). Since your input file is lib/GPIO/gpio.c the compiler generates gpio.as. Most compilers support a -o option which allows you to rename the output: you'll have to check your compiler's documentation if this doesn't work. So, you'd want to write your rule:
%.as: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} -S -o $# $<
(etc.). Now when you compile lib/GPIO/gpio.c into lib/GPIO/gpio.as, make will set $# to lib/GPIO/gpio.as and invoke your compiler such that it creates lib/GPIO/gpio.as not gpio.as.
But you wanted to put the output files in a build subdirectory. Now that you've convinced your compiler to write files where make tells it to, you have to tell make where to put the output.
So first, when you generate the output files to be created you have to create them with the correct path:
OBJS := $(SRCS:.c=.p1)
That converts lib/GPIO/gpio.c into lib/GPIO/gpio.p1 which isn't what you want. You need this:
OBJS := $(SRCS:%.c=build/%.p1)
Now, make knows you want to build build/lib/GPIO/gpio.p1 instead. However now you'll get an error because make doesn't know how to create that file. You've told it how to build a %.p1 from %.c, but the % must be an exact text match between the target and prerequisite, and here the target % matches build/lib/GPIO/gpio but there's no build/lib/GPIO/gpio.c so the rule doesn't match. You need to rewrite the rule like this:
build/%.p1: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} --pass1 -o $# $<
Now it should work. You might also want to add in a mkdir to ensure the directory exists:
build/%.p1: %.c ${INC_DIR}
#mkdir -p ${#D}
${CC} ${CPPFLAGS} ${CFLAGS} --pass1 -o $# $<
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.
I am looking to write a makefile to automate the compiling of a project that I am working on where the files may, or may not, change in number. I also need to be able to quickly tell make to compile the files as a debug build or a release build (differentiated by a command line define). After some research, I came upon pattern rules and made one. Here is the code I have so far:
# Our folders
# ODIR - The .o file directory
# CDIR - The .cpp file directory
# HDIR - The .hpp file directory
ODIR = obj
CDIR = src
HDIR = inc
# Get our compiler and compiler commands out of the way
# CC - Our compiler
# CFNO - Our compiler flags for when we don't have an output file
# CF - Our compiler flags. This should be appended to any compile and should
# have the name of the output file at the end of it.
# OF - Object flags. This should be appended to any line that is generating
# a .o file.
CC = g++
CFNO = -std=c++11 -wall -Wno-write-strings -Wno-sign-compare -lpaho-mqtt3c -pthread -O2 -I$(HDIR)
CF = $(CFNO) -o
OF = -c
# Our project/output name
NAME = tls_test
# Set out Debug and Release settings, as well as any defines we will use to identify which mode we are in
# NOTE: '-D[NAME OF DEFINE]' is how you create a define through the compile commands
DEBUG = -DDEBUG -g
RELEASE = -DRELEASE
# Our two compile modes
# eval allows us to create variables mid-rule
debug:
$(eval DR = $(DEBUG))
release:
$(eval DR = $(RELEASE))
# Our compiling commands
all:
$(CC) $(CF) $(NAME) $(ODIR)/*.o
# NOTE: $# is the end product being created and $< is the first of the prerequisite
$(ODIR)/%.o: $(CDIR)/%.c
echo "$(CC) $(DR) $(OF) $(CF) $# $<"
The issue that I am having is with the order that I need things to run in. The command line call should tell make to use either debug or release, which sets a make variable, then call all. all should then run the pattern rule at the bottom before running the line currently in the all rule. So, how do I make a pattern rule a dependency and how do I call a rule from another rule?
Use target-specific variables
While not strictly necessary, separating your flags goes a long way in managing build options, you can then use target-specific variable appends to toggle the flags. While you're at it you might as well use the built-in variable names.
I've also added dependency generation (-MMD -MP) because it's always useful.
ODIR := obj
CDIR := src
HDIR := inc
SRCS := $(wildcard $(CDIR)/*.cpp)
OBJS := $(SRCS:$(CDIR)/%.cpp=$(ODIR)/%.o)
DEPS := $(OBJS:%.o=%.d)
CPPFLAGS := -I$(HDIR) -MMD -MP
CXXFLAGS := -std=c++11 -Wall -Wno-write-strings -Wno-sign-compare -pthread -O2
LDFLAGS := -pthread
LDLIBS := -lpaho-mqtt3c
NAME := tls_test
.PHONY: debug release clean
debug: CPPFLAGS+=-DDEBUG
debug: CXXFLAGS+=-g
release: CPPFLAGS+=-DRELEASE
debug release: $(NAME)
$(NAME): $(OBJS)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJS): $(ODIR)/%.o: $(CDIR)/%.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
clean: ; $(RM) $(NAME) $(OBJS) $(DEPS)
-include $(DEPS)