'make clean' not working - makefile

so I made a makefile for a c program. For some reason my 'clean' is not working. Here's a little bit of my makefile:
CC=gcc
FLAGS=-c -Wall -I.
CLEANC=rm -rf *.o
move.o: move.c
$(CC) $(FLAGS) move.c
/*Lot more codes like this^^^*/
clean:
$(CLEANC)
When I run 'make clean' in command prompt, I'm shown the following:
rm -rf *.o
process_begin: CreateProcess(NULL, rm -rf *.o, ...) failed.
make (e=2): The system cannot find the file specified.
makefile:116: recipe for target 'clean' failed
make: *** [clean] Error 2
I can't figure out what I'm doing wrong. I've tried changing CLEANC to
rm -f *.o
rm *.o
rm *o
rm -f *.o test.exe //test.exe is executable
but it still gave me the same error no matter what I tried. I could really use the help. Thanks in advance.

Judging from the CreateProcess appearing in your error output I assume you are running make under Windows.
This means that there is no rm command, you should use del instead and -rf flags should also be adjusted accordingly.

OBJS = $(addprefix $(OBJ_DIR)/,$(patsubst %.c,%.o,$(notdir $(SRCS))))
DELOBJS = $(addprefix .\obj\,$(patsubst %.c,%.o,$(notdir $(SRCS))))
.PHONY: clean
clean:
del xxx
del $(DELOBJS)
del does not work because Windows uses \ to distinguish file paths,so you have to take OBJS with \path, that is, DELOBJS I wrote

Related

Simple makefile command not found

I was given a makefile that looks like this, and told not to change it.
all: clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp clean: rm -f lex.yy.c rm -f parser.tab.*pp rm -f hw2
I am trying to run this makefile in a folder with files named: scanner.lex, parser.ypp, output.hpp and output.cpp
I copied it to a file like this:
all:
clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp
clean:
rm -f lex.yy.c rm -f parser.tab.*pp rm -f hw2
When I run the make command in my terminal I get an error:
clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp
/bin/sh: clean: command not found
make: *** [all] Error 127
Am I doing something wrong? Again, I was given this line and told not to change it.
Thanks a lot.
Line breaks are essential in most computer environments. If you were given a Makefile without the line breaks and you try to cut it randomly you will have difficulties before if finally works. Try this, maybe:
all: clean
flex scanner.lex
bison -d parser.ypp
g++ -std=c++11 -o hw2 *.c *.cpp
clean:
rm -f lex.yy.c
rm -f parser.tab.*pp
rm -f hw2
And use tabs to indent the indented lines, not spaces.
Explanations: all and clean are what is called a target in make parlance. They are the names of the things you want make to do. clean to delete some files, all to do everything else. The
target: prerequisite1 prerequisite2...
recipe1
recipe2
...
template is the basic make template. It means that target depends on prerequisite1, prerequisite2 and that in order to build it make shall pass recipe1 to the shell for execution, then recipe2...
Note that this Makefile is poorly written. As all and clean are not real file names they should be declared as phony, such that, if a file with that name exists make does the job anyway. As is, it wouldn't. Give it a try:
$ make all
$ touch clean
$ make clean
make: 'clean' is up to date.
See? Because a file named clean exists you cannot make clean anymore, make considers that there is nothing to do for clean. Add this at the beginning of your Makefile:
.PHONY: all clean
A second issue is that make works by comparing last modification times of targets and prerequisites to decide if targets must be rebuilt or not. With your Makefile make will always recompile everything, even if the inputs did not change and the outputs are up-to-date. This is a waste. A better (but untested) Makefile would be something like:
.PHONY: all clean
CFILES := $(filter-out lex.yy.c,$(wildcard *.c))
CPPFILES := $(filter-out parser.tab.cpp,$(wildcard *.cpp))
all: hw2
hw2: lex.yy.c parser.tab.cpp $(CFILES) $(CPPFILES)
g++ -std=c++11 -o $# $^
lex.yy.c: scanner.lex
flex $<
parser.tab.cpp: parser.ypp
bison -d $<
clean:
rm -f lex.yy.c
rm -f parser.tab.*pp
rm -f hw2
Understanding it and why it is better is left as an exercise.

using ifeq statement in makefile, missing separator even when indented with tab correctly

I was just practising with GNU make and I was trying to write a clean target, the make file is this:
includePath := -I $(CURDIR)
outputDir = $(CURDIR)/output
COMPILER := g++
standard := -std=c++17
#sourceFiles
main.cpp := main.cpp
#output files
binaryPath = $(outputDir)
binary = main.out
#int_binaryPath = intermediate binary
int_binaryPath = $(outputDir)/int_binaries
int_binary = main.o
GPP = $(COMPILER) $(standard) $(includePath)
#print info while make is executing
# $(info $(includeDir) )
VPATH = outputDir/int_binaries $(CURDIR)/glad/src
#build=compile,link and run
$(binary): $(int_binary) glad.c -lGL -lGLU -lglfw -ldl
$(GPP) $(int_binaryPath)/main.o $(CURDIR)/glad/src/glad.c -o $(binaryPath)/$# -lGL -lGLU -lglfw -ldl
$(int_binary): $(main.cpp)
$(GPP) $(main.cpp) -c -o $(int_binaryPath)/$(int_binary)
build: $(binary)
$(binaryPath)/$(binary)
build#bg: $(binary)
$(binaryPath)/$(binary) &
rebuild: clean build
#echo "rebuild successful"
.PHONY: clean
clean:
ifeq($(wildcard $(outputDir)/$(binary)), $(outputDir)/$(binary))
rm -rf $(outputDir)/$(binary)
else ifeq($(wildcard $(outputDir)/$(int_binary)), $(outputDir)/$(int_binary))
rm -rf $(outputDir)/$(int_binary)
endif
now the part that is throwing up error is this:
.PHONY: clean
clean:
ifeq($(wildcard $(outputDir)/$(binary)), $(outputDir)/$(binary)) #this has spaces, line 47
rm -rf $(outputDir)/$(binary) #this has 2 tabs, but even 1 tab didn't work
else ifeq($(wildcard $(outputDir)/$(int_binary)), $(outputDir)/$(int_binary))
rm -rf $(outputDir)/$(int_binary)
endif
now, when I do make clean, it returns the following error:
makefile:47: *** missing separator. Stop.
What exactly am I doing wrong? Why isn't it working and what does the error mean?
You have to have a space between the ifeq and the open paren.
You have other issues; for example there's no comma between words in the wildcard function, so you're literally asking it to look for the file ./output/main.out, (including the ,) exists.
Anyway, this is not needed because rm -rf foo is simply a no-op if foo doesn't exist... you don't need all this complexity.

Make Error 1 on Windows for good del command?

My Makefile contains a clean rule, but for some reason it always fails, even though running the command by itself is always successful. What could possibly be causing this?
make clean
del /f *.o *.hex *.elf *.map
make: *** [clean] Error 1
Edit: Here is the whole makefile:
MCU = atmega324p
AVRDUDE_DEVICE = m324p -F
PORT = \\\\.\USBSER000
CFLAGS=-g -Wall -mcall-prologues -mmcu=$(MCU) -Os
CC=avr-gcc
OBJCOPY=avr-objcopy
OBJDUMP=avr-objdump
LDFLAGS=
TARGET=led_strip
all: $(TARGET).hex
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $#
%.elf: %.o
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $#
program: $(TARGET).hex
bootloadHID.exe -r $<
clean:
del /f *.o *.hex *.elf *.map
In the meantime, I realised that WinAVR very rudely overwrote my PATH variable when I installed it. I went and added MinGW back to my PATH and removed the WinAVR utils/ folder which contained commands like sh.exe, and that seems to have fixed the issue. I would still like to understand what exactly was causing the problem, though.

How to fix "make (e=2): The system cannot find the file specified."

i want to use mingW32_make.exe to compile a C code on command prompt. The error message shows
rm -f obj/*.o
process_begin: CreateProcess(NULL, rm -f obj/*.o, ...) failed.
make (e=2): The system cannot find the file specified.
makefile:11: recipe for target 'all' failed
mingw32-make.exe: *** [all] Error 2
The makefile is show below
CC=gcc
INC_DIR=../include
LIBS=-lregex
ODIR=obj
_OBJ=main.o BVPA.o BVPA-cube.o BVPA-cif.o BVPA-hk.o BVPA-path.o BVPA-math.o BVPA-cmd.o BVPA-gui.o BVPA-vesta.o MT19937AR.o
OBJ=$(patsubst %,$(ODIR)/%,$(_OBJ))
TARGET=../bin/BVPA_win.exe
CFLAGS=-I$(INC_DIR) -Wall -g
all: $(TARGET)
rm -f $(ODIR)/*.o
$(TARGET): $(OBJ)
$(CC) $(CFLAGS) -o $# $^ $(LIBS)
$(ODIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $# $^
clean:
rm -f $(ODIR)/*.o
'''
I have encountered the same question and here is the fix. The reason is given from other's comments:
Windows does not understand rm.
When you run make clean, it will clear out all .o files.
clean:
del *.o
The answer for this question is actually simple. There is no obj folder in your current directory so the compiler doesn't know where to add or remove. You can simply add a obj folder in your source code directory.
I come across the same issue, and my solution is below
del /f $(ODIR)\*.o
Note that if I use "$(ODIR)/*.o" in the makefile, the error would still exist.

Makefile clean all target is called twice when explicitly invoked

I am still figuring out why in the below Makefile, when I execute it in the command like make clean all it runs twice the "clean all" target part?
FLAGS = -g -Wall -Wextra -Werror
a.out : check.cpp
$(CXX) $(CFLAGS) -o $# $<
clean all:
rm -rf *.o *.out *.txt
The target "clean all:" is equivalent to:
clean:
rm -rf *.o *.out *.txt
all:
rm -rf *.o *.out *.txt
You can't have spaces in target names, each word would be considered a target. So when you do make clean all, make thinks you want to build target "clean" and target "all" and so you have 2 targets being executed. It does look like a mistake in the makefile since having all doing the same as clean is weird.

Resources