I've been having serious trouble with Makefiles, I'm trying to run those commands in it and so far most of the changes I made resulted in "Nothing to be done for 'all'" no matter I change the lines, it just don't work. For example, PROG4 should have worked below but it says nothing to be done.
BIN_DIR = bin
LEX_DIR = lexyacc-code
LIB_DIR = lib
SRC_DIR = src
OBJ_DIR = obj
CC = gcc
BS = bison
FX = flex
CFLAGS = -I$(LIB_DIR)
SRCS = $(wildcard $(LEX_DIR)/calc3b.c)
SRCS2 = $(wildcard $(LEX_DIR)/calc3.y)
SRCS3 = $(wildcard $(LEX_DIR)/calc3.l)
SRCS4 = $(wildcard $(OBJ_DIR)/y.tab.c)
SRCS5 = $(wildcard $(OBJ_DIR)/lex.yy.c)
OBJS = $(patsubst $(LEX_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS))
PROG = calc3b
PROG2 = y.tab
RM = rm -f
MVV="$(shell mv y.tab.c obj)"; echo $MVV
all: $(PROG2) $(PROG4)
$(PROG): $(OBJS)
$(CC) $^ -o $(PROG)
$(PROG2):
$(BS) -y -d $(SRCS2)
$(PROG4): $(CC) -c $(SRCS4) $(SRCS5) $(CFLAGS)
$(OBJ_DIR)/%.o: $(LEX_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
$(RM) $(PROG) $(OBJS)
Only PROG2 is working, basically for result I have header and source file which I tried to move specific folders but eventually I did it with 'mv' command (I know its against Makefile).
The commands are these:
bison -y -d calc3.y
flex calc3.l
gcc -c y.tab.c lex.yy.c
gcc y.tab.o lex.yy.o calc3b.c -o calc3b.exe
First command, I have one header and source as a result.
Second I have one source as a result.
Third I have 2 objects file as a result.
And fourth, I will have one executable.
Therefore, I also need to move those files to their specific folders.
Can anyone help me out with this? Thanks.
I think that the problem with $(PROG4) is that you forgot to put command on a new line with tab. In what you've showed above, the whole line of command is placed where it should be dependency but not command. Therefore, makefile executes no command for $(PROG4).
Related
I have three directories obj/, inc/ and src/ . The directories inc/ and src/ contains all the .c files. I would like to redirect all the .o files generated in src/ and inc/ to obj/
This is a simple example of my makefile
NAME = push_swap
SRC = $(wildcard ./src/*c)
INC = $(wildcard ./inc/*c)
OBJ1 = $(SRC:.c=.o)
OBJ2 = $(INC:.c=.o)
CC = gcc
CFLAGS = -Wall -Werror -Wextra
$(NAME): $(OBJ1) $(OBJ2)
$(CC) $(CFLAGS) $(OBJ1) $(OBJ2) -o $#
all: $(NAME)
clean:
rm -f */*.o
fclean: clean
rm -f $(NAME)
re: fclean all
The makefile works perfectly, but all the object files are generetad in its src folder, making hard to search for .c files and debbug the code.
By default, Make will build the object file in the directory where it finds the source. If you want the object file to be built somewhere else, there is more than one way to do it.
You could write a rule for Make to use instead of the default:
obj/%.o: src/%.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
And another for source files in inc/, if you want to keep source files there.
Or you could write a more general rule, and use 'vpath` to find the sources:
vpath %.c src inc
obj/%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
EDIT: Did you remember to change the names of the files you ask Make to build (as #MadScientist pointed out in his comment (and as I ought to have pointed out in my Answer))?
Try this:
SRC = $(wildcard ./src/*c)
OBJ1 = $(patsubst ./src/%.c, ./obj/%.o, $(SRC))
CC = gcc
CFLAGS = -Wall -Werror -Wextra
vpath %.c src
obj/%.o: %.c
$(CC) $(CFLAGS) -c -o $# $<
all: $(OBJ1)
I'm new to C, sorry if my question is basic, below is my makefile:
src = $(wildcard *.c)
obj = $(src:.c=.o)
LDFLAGS = -pthread
prog: $(obj)
$(CC) -o $# $^ $(LDFLAGS)
.PHONY: clean
clean:
rm -f $(obj) prog
but I have source files(let's myfunc.c) in other directory. I don't want to copy myfunc.c to every project then compile and link it, I only want to use a single source from that directory, how can I modify my makefile to reflect this?
You must tell Make two new things: That myfunc.o is needed, and where to find myfunc.c. (I'll assume some/dir/myfunc.c.)
There is more than one way to do it. A beginner should learn the simple way:
obj = $(src:.c=.o) myfunc.o
myfunc.o: some/dir/myfunc.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
Once you understand that, you can use vpath instead:
obj = $(src:.c=.o) myfunc.o
vpath %.c some/dir
I have a question regarding my Makefile. The Makefile intends to compile C files containing code for a STM8 µC using the Cosmic compiler. The problem is that everytime I invoke the build target, all available source file are getting recompiled without any change. I'm really new in the field of Makefiles and I have no idea how to fix it.
The second questions is related to the two targets "%.o: src/%.c" and %.o: src/stm8/%.c. They do exactly the same and I would prefer a generic one that is able to deal with all subdirectories within the src folder. With this solution it ist required to add an additional rule for each subfolder of the src folder
#***************PROJECT INFORMATIONS****************
PROJECT_NAME = stm8template
MODULES = stm8
#****************SET BUILD MODE*********************
ifeq ($(MODE), )
MODE=Debug
endif
#***************DIRECTORY INFORMATION***************
SRCDIR = src
INCLUDES = includes
OUTPUT_DIR = bin/$(MODE)
#**************HELPER FUNCTIONS*********************
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
#***************FILE SPECIFICATIONS***************
SOURCE_FILES = $(foreach d, $(call rwildcard,$(SRCDIR),*.c), $(notdir $d))
OBJECT_FILES = $(patsubst %.c, %.o, $(SOURCE_FILES))
HEADER_FILES = $(wildcard $(INCLUDES)/*.h) $(wildcard $(INCLUDES)/**/*.h)
INCLUDE_DIRS_PARAM=$(foreach d, $(MODULES), -iincludes/$d) -iincludes -iC:\Hstm8
#***************COMPILER INFORMATIONS***************
CC = cxstm8
LIBS = -l +mods0
ifeq ("$(MODE)","Debug")
CFLAGS = $(INCLUDE_DIRS_PARAM) -cl$(OUTPUT_DIR) -co$(OUTPUT_DIR) -pxp -no -pp +debug
else
CFLAGS = $(INCLUDE_DIRS_PARAM) -cl$(OUTPUT_DIR) -co$(OUTPUT_DIR) -pxp -no -pp
endif
#***************LINKER INFORMATIONS***************
LINKFILE=$(OUTPUT_DIR)\$(PROJECT_NAME).lkf
OUTFILE=$(PROJECT_NAME)
LFLAGS = -lC:\Lib
#*************FLASHER CONFIGURATIONS***************
FLASHER_PATH="C:\Program Files (x86)\STMicroelectronics\st_toolset\stvp\STVP_CmdLine.exe"
DEVICE=STM8S105x6
PORT=USB
PROG_MODE=SWIM
BOARD_NAME=ST-LINK
FLASHER_PARAM = -no_loop
#***************BUILT TARGETS***************
all: build run
%.o: src/%.c
$(info ********** Compile $< ***********)
$(CC) $(CFLAGS) $(LIBS) $<
%.o: src/stm8/%.c
$(info ********** Compile $< ***********)
$(CC) $(CFLAGS) $(LIBS) $<
build: $(OBJECT_FILES)
$(info ********** Build the Application ***********)
clnk -m $(OUTPUT_DIR)\$(OUTFILE).map -o $(OUTPUT_DIR)\$(OUTFILE).sm8 $(LINKFILE)
cvdwarf $(OUTPUT_DIR)\$(OUTFILE).sm8
chex -o $(OUTPUT_DIR)\$(OUTFILE).s19 $(OUTPUT_DIR)\$(OUTFILE).sm8
run:
$(info ********** Flashing the Application ***********)
$(FLASHER_PATH) -BoardName=$(BOARD_NAME) -Device=$(DEVICE) -Port=$(PORT) -ProgMode=$(PROG_MODE) -FileProg="$(OUTPUT_DIR)\$(OUTFILE).s19" $(FLASHER_PARAM)
The build target never gets created, so the commands after it are executed every time you run make (or make all or make build), so the program is linked each time.
Change your build target so that it is phony:
.PHONY: build clean
and so that it depends on the program, not the object files:
build: $(OUTPUT_DIR)\$(OUTFILE).sm8
and then have a rule (recipe) that builds the program if the object files are more recent:
$(OUTPUT_DIR)\$(OUTFILE).sm8: $(OBJECT_FILES)
$(info ********** Build the Application ***********)
clnk -m $(OUTPUT_DIR)\$(OUTFILE).map -o $(OUTPUT_DIR)\$(OUTFILE).sm8 $(LINKFILE)
cvdwarf $(OUTPUT_DIR)\$(OUTFILE).sm8
chex -o $(OUTPUT_DIR)\$(OUTFILE).s19 $(OUTPUT_DIR)\$(OUTFILE).sm8
It isn't 100% clear to me that I chose the correct suffix for the program. I would also create series of macros to avoid the repetition I see:
OUTFILE.sm8 = $(OUTPUT_DIR)\$(OUTFILE).sm8
OUTFILE.s19 = $(OUTPUT_DIR)\$(OUTFILE).s19
OUTFILE.map = $(OUTPUT_DIR)\$(OUTFILE).map
build: $(OUTFILE.sm8)
$(OUTFILE.sm8): $(OBJECT_FILES)
$(info ********** Build the Application ***********)
clnk -m $(OUTFILE.map) -o $(OUTFILE.sm8) $(LINKFILE)
cvdwarf $(OUTFILE.sm8)
chex -o $(OUTFILE.s19) $(OUTFILE.sm8)
Also, since I work on Unix mostly, I'd use / instead of \, but that's a minor detail.
Update:
Thank you all for your help. I changed the Makefile in the way shown below. The second problem is now fixed but the first problem still remains.
Every time the build rule is invoked all .c files are recompiled. Compiling only the changed files is the main purpose/benefit of using make, I thought. So something is wrong but unfortunately I don't find the mistake.
#***************PROJECT INFORMATIONS****************
PROJECT_NAME = stm8template
MODULES = stm8
#****************SET BUILD MODE*********************
ifeq ($(MODE), )
MODE=Debug
endif
#***************DIRECTORY INFORMATION***************
SRCDIR = src
INCLUDES = includes
#**************HELPER FUNCTIONS*********************
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
#***************FILE SPECIFICATIONS***************
SOURCE_FILES = $(foreach d, $(call rwildcard,$(SRCDIR),*.c), $(notdir $d))
OBJECT_FILES = $(patsubst %.c, %.o, $(call rwildcard,$(SRCDIR),*.c))
HEADER_FILES = $(wildcard $(INCLUDES)/*.h) $(wildcard $(INCLUDES)/**/*.h)
INCLUDE_DIRS_PARAM=$(foreach d, $(MODULES), -iincludes/$d) -iincludes -iC:\Hstm8
#***************COMPILER INFORMATIONS***************
CC = cxstm8
LIBS = -l +mods0
ifeq ("$(MODE)","Debug")
CFLAGS = $(INCLUDE_DIRS_PARAM) -cl$(OUTPUT_DIR) -co$(OUTPUT_DIR) -pxp -no -pp +debug
else
CFLAGS = $(INCLUDE_DIRS_PARAM) -cl$(OUTPUT_DIR) -co$(OUTPUT_DIR) -pxp -no -pp
endif
#***************LINKER INFORMATIONS***************
LINKFILE=$(OUTPUT_DIR)\$(PROJECT_NAME).lkf
LFLAGS = -LC:\Lib
#*******************OUTPUT FILES********************
OUTPUT_DIR = bin/$(MODE)
OUTFILE=$(PROJECT_NAME)
OUTFILE.sm8 = $(OUTPUT_DIR)\$(OUTFILE).sm8
OUTFILE.s19 = $(OUTPUT_DIR)\$(OUTFILE).s19
OUTFILE.map = $(OUTPUT_DIR)\$(OUTFILE).map
TARGET_FILE=$(OUTPUT_DIR)\$(PROJECT_NAME).elf
#*************FLASHER CONFIGURATIONS***************
FLASHER_PATH="C:\Program Files (x86)\STMicroelectronics\st_toolset\stvp\STVP_CmdLine.exe"
DEVICE := STM8S105x6
PORT=USB
PROG_MODE=SWIM
BOARD_NAME=ST-LINK
FLASHER_PARAM = -no_loop
#***************BUILT TARGETS***************
.PHONY: all run build clean
all: build run
%.o: %.c
$(info ********** Compile $< ***********)
$(CC) $(CFLAGS) $(LIBS) $<
build: $(OUTPUT_DIR)\$(PROJECT_NAME).elf
$(TARGET_FILE): $(OBJECT_FILES)
$(info ********** Build the Application ***********)
clnk -m $(OUTFILE.map) -o $(OUTFILE.sm8) $(LINKFILE)
cvdwarf $(OUTFILE.sm8)
chex -o $(OUTFILE.s19) $(OUTFILE.sm8)
run:
$(info ********** Flashing the Application ***********)
$(FLASHER_PATH) -BoardName=$(BOARD_NAME) -Device=$(DEVICE) -Port=$(PORT) -ProgMode=$(PROG_MODE) -FileProg="$(OUTPUT_DIR)\$(OUTFILE).s19" $(FLASHER_PARAM)
I'm following this guide about makefile, but I didn't understand at all the last example and I can't get my makefile work, as I obtain the error make: *** No rule to make target "obj/date.o", needed by "Whatsapp". Stop.
Here is my makefile:
IDIR = ../include
CC = gcc
CFLAGS = -I$(IDIR)
ODIR = obj
LDIR = ../lib
LIBS = -lncurses
# Keep the alphabetical order!
_DEPS = \
constants.h\
date.h\
inOut.h\
languages.h\
message.h\
mycurses.h\
mysocket.h\
text.h\
time.h\
user.h\
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
# Keep the alphabetical order!
_OBJ = \
date.o\
inOut.o\
languages.o\
main.o\
message.o\
mycurses.o\
mysocket.o\
text.o\
time.o\
user.o\
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
# these two lines should tell the compilator that my .o files depend by .c files, don't they?
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
Whatsapp: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
Obviously, all my *.c are in the current folder, so really I don't know what I am missing.
Just for more clarity, here is the content of the current folder:
urbijr#urbijr-VirtualBox:/media/sf_Whatsapp_CLIENT$ ls
constants.h indexbook.txt languages.c makefile message.h mycurses.h text.c time.h
date.c inOut.c languages.h message.c message.txt mysocket.c text.h user.c
date.h inOut.h main.c message_for_user.txt mycurses.c mysocket.h time.c user.h
Your dependencies are not as you have specified in your makefile. The line below specifies that all include files should be in the directory $(IDIR).
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
This is set as ../include, but it seems you have all the header files in the same directory. Either move them to ../include or change IDIR to . (the current directory).
You'll also need to create the output directory (obj) as make won't do this automatically.
This is running on FreeBSD which uses PMake instead of GMake.
This is my first Makefile. I used Google a lot to help create this as well as sources such as 'PMake — A Tutorial'. The only problem I can't solve is that every time I run the Makefile, it will compile every file even when there are no changes.
I have four directories. src for my source files, include for my headers, obj for the output and bin for the executable.
What I'm doing is scanning the source folder and creating a list of files to use for both the source and object as well as the headers. Typically I run 'make debug' for debugging and 'make myservice' otherwise.
If I run 'make clean', 'make debug', and 'make debug' it will clean my folders, make all files and then proceed to remake all files instead of doing nothing.
Based on my searching, I'm leaning towards the $(OBJ) rule being the problem, but I don't quite get that. In order for my target and debug rules to build they need to know how to build the objects.
CC = clang
BINDIR = $(.CURDIR)/bin
OBJDIR = $(.CURDIR)/obj
SRCDIR = $(.CURDIR)/src
INCDIR = $(.CURDIR)/include
CFLAGS = -Wall -I/usr/local/include -I$(INCDIR)
LFLAGS = -lm -lpq -lpthread
LIBDIR = -L/usr/local/lib
_SRC != ls $(SRCDIR)/*.c
SRC = ${_SRC:T}
INC != ls $(INCDIR)/*.h
OBJ = ${SRC:S/src/obj/g:.c=.o}
TARGET = myservice
$(TARGET): $(OBJ)
$(CC) -o $(BINDIR)/$# $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
debug: $(OBJ)
$(CC) -g -O0 -o $(BINDIR)/$(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h
$(CC) -c $< $(CFLAGS)
.PHONY: clean
clean:
rm -rf $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
edit - New Makefile
New Makefile. Doesn't rebuild if no changes. Has no debug, still issues figuring out debug.
CC = clang
BINDIR = $(.CURDIR)/bin
OBJDIR = $(.CURDIR)/obj
SRCDIR = $(.CURDIR)/src
INCDIR = $(.CURDIR)/include
CFLAGS = -Wall -I/usr/local/include -I$(INCDIR)
LFLAGS = -lm -lpq -lpthread
LIBDIR = -L/usr/local/lib
TARGET = $(BINDIR)/myservice
_SRC != ls $(SRCDIR)/*.c
SRC = ${_SRC:T}
INC != ls $(INCDIR)/*.h
OBJ = ${SRC:S/src/obj/g:.c=.o}
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -rf $(OBJDIR)/*.o $(TARGET)
edit - Working Makefile
Added if conditional for debugging purposes.
CC = clang
BINDIR = $(.CURDIR)/bin
OBJDIR = $(.CURDIR)/obj
SRCDIR = $(.CURDIR)/src
INCDIR = $(.CURDIR)/include
CFLAGS = -Wall -I/usr/local/include -I$(INCDIR)
.if make(debug)
CFLAGS += -g -O0
.endif
LFLAGS = -lm -lpq -lpthread
LIBDIR = -L/usr/local/lib
TARGET = $(BINDIR)/myservice
_SRC != ls $(SRCDIR)/*.c
SRC = ${_SRC:T}
INC != ls $(INCDIR)/*.h
OBJ = ${SRC:S/src/obj/g:.c=.o}
all: $(TARGET)
debug: $(TARGET)
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
$(OBJ): $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -rf $(OBJDIR)/*.o $(TARGET)
The second make debug cannot do nothing, debug is phony target, not an actual output file, at least the link phase will be re-run.
Furthermore, re-running the link phase with -g -O0 would not recompile you source files with debug information and no optimizations.
Incidentally, the $(TARGET) rule is a phony rule too, it produces $(BINDIR)/$(TARGET), not $(TARGET).
You should rewrite your makefile with different rules to make object and binary output files in different directories for debug and release modes. gmake patterns make this easy to write, I don't know about pmake or cmake for this purpose.