no rule to make target but file exists, compiling - makefile

I can't seem to debug this, could someone please help? The *.f90 file does exists and the directory is correct. I am not sure what it could be, the gfortran compiler works fine outside of the makefile.
make[1]: Entering directory '/media/f/fv/ED-2.1/ED/build/bin'
make[1]: *** No rule to make target 'media/f/fv/ED-2.1/ED/src/utils/allometry.f90', needed by 'allometry.o'. Stop.
make[1]: Leaving directory '/media/f/fv/ED-2.1/ED/build/bin'
Makefile:24: recipe for target 'all' failed
This is the makefile
#----- Define path and compilation --------------------------------------------------------#
include paths.mk
include include.mk.$(OPT)
#----- Compiler commands. -----------------------------------------------------------------#
INCLUDES = $(PAR_INCS) -I$(ED_INCS) $(HDF5_INCS) $(MPI_INCS)
F90_COMMAND = $(F_COMP) -c $(F_OPTS) $(INCLUDES) $(PAR_DEFS)
FPP_COMMAND = $(F_COMP) -c -DUSE_INTERF=$(USE_INTERF) -DUSENC=$(USENC) -D$(CMACH) \
-DUSE_HDF5=$(USE_HDF5) -DUSE_COLLECTIVE_MPIO=$(USE_COLLECTIVE_MPIO) \
-DUSE_MPIWTIME=$(USE_MPIWTIME) $(F_OPTS) $(INCLUDES) $(PAR_DEFS)
CXX_COMMAND = $(C_COMP) -c $(C_OPTS) -D$(CMACH) $(HDF5_INCS) $(INCLUDES) $(PAR_DEFS)
#----- Define archive and executable names. -----------------------------------------------#
EXE=$(BASE)/ed_$(ED_VERSION)-$(OPT)
LIBMODEL=$(BASE)/ed_$(ED_VERSION)-$(OPT).a
include objects.mk
#----- Define targets. --------------------------------------------------------------------#
all:
make gendep
#$(info $$EXE is [${EXE}])
make $(EXE)
make $(EXE)
make $(EXE)
make $(EXE)
make $(EXE)
gendep:
#echo ""
./generate_deps.sh $(ED_ROOT)
#echo === Finished dependencies ===
$(EXE): $(LIBMODEL) $(MAINOBJ)
#echo ""
$(LOADER) -o $(EXE) edmain.o $(LOADER_OPTS) $(LIBMODEL) $(HDF5_LIBS) $(PAR_LIBS) \
$(NC_LIBS) $(LIBS) $(LOADER_OPTS)
#echo ""
#echo Finished building === $(EXE)
#echo ""
$(MAINOBJ): $(MAIN)
#echo ""
cp -f $< $(<F:.f90=.f90)
$(F90_COMMAND) $(<F:.f90=.f90)
rm -f $(<F:.f90=.f90)
$(LIBMODEL): $(OBJ_MODEL)
$(ARCHIVE) $(LIBMODEL) $(OBJ_MODEL)
FORCE:
install:
#echo ""
ln -fs `pwd`/$(EXE) ../run/$(BASE)
ln -fs `pwd`/$(EXE) ../test/$(BASE)
#echo ""
clean:
#echo ""
rm -f $(LIBMODEL) $(EXE) *.o *.mod *.F90 *.f90 *.stb *.d dependency.mk
rm -f ../$(EXE) ../$(LIBMODEL)
touch dependency.mk
#echo ""
#----- Define rules -----------------------------------------------------------------------#
include rules.mk

This makefile is a hot mess. Why do you have the same command make $(EXE) listed 5 times in a row in the all recipe? Why are you using $(<F:.f90=.f90) which just replaces the string .f90 with an identical string .f90, essentially a no-op?
Further, we don't have enough information here to answer your question: you haven't provided the definition of the variables MAINOBJ or OBJ_MODEL, or more importantly, MAIN. At least one of those is wrong. Unless you've mis-transcribed the error message (please always cut and paste actual errors, don't try to manually type them in!!), then this:
make[1]: *** No rule to make target 'media/f/fv/ED-2.1/ED/src/utils/allometry.f90', needed by 'allometry.o'. Stop.
tells you what the problem is; note there is no slash (/) at the beginning of this pathname, before media. So this is not an absolute path, it's a relative path. That means make is actually trying to find the file named /media/f/fv/ED-2.1/ED/build/bin/media/f/fv/ED-2.1/ED/src/utils/allometry.f90 which clearly won't exist.
We can't tell you why this is happening because you haven't provided the information about how these variables are set. Most likely the bad one is MAIN but it's hard to know for sure.

Related

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 dependency doesn't trigger rebuild

I'm want to have .h files to be included as my dependencies for a given .o file. I followed these instructions and adapted them to my Makefile. However when I do touch myhfile.h a corresponding .o file is not rebuilt. It seems to me dependencies are correct and are included into the Makefile. Just can't figure out why it is not working. Any help is appreciated. Makefile is included below
ROOT=.
BUILDDIR=$(ROOT)/build
LIBDIR=$(BUILDDIR)/lib
OBJDIR=$(BUILDDIR)/obj
INCLUDEDIR=$(BUILDDIR)/include
DEPDIR=$(BUILDDIR)/dep
LIB=mylib
XCOMPILE=arm-linux-gnueabihf-
CC=$(XCOMPILE)gcc
AR=$(XCOMPILE)ar
DEPFLAGS+=\
-MT $# \
-MMD \
-MP \
-MF \
$(DEPDIR)/$*.Td
CFLAGS+=\
-Wall \
-Wextra \
-Werror \
-pedantic \
-std=gnu11 \
-fPIC
CPPFLAGS+=\
$(INCLUDE)
SRCDIRS+=\
$(ROOT)/../3rdparty/log/src \
$(ROOT)/LTC2947/src \
$(ROOT)/i2c/src \
$(ROOT)/spi/src \
$(ROOT)/sensors/src \
$(ROOT)/telegraf/src \
$(ROOT)/uart-packet/src \
$(ROOT)/STCN75/src \
$(ROOT)/utils/src
DEPDIRS+=\
$(SRCDIRS) \
$(ROOT)/addresses-ports/src
VPATH+=\
$(SRCDIRS)
SRC+=$(shell find $(SRCDIRS) -type f -name "*\.c")
DEP+=$(shell find $(DEPDIRS) -type f -name "*\.h")
OBJ=$(patsubst %.c, $(OBJDIR)/%.o, $(notdir $(SRC)))
INCLUDE=$(addprefix -I,$(sort $(dir $(DEP))))
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
release: CFLAGS+=-O3
release: all
debug: CFLAGS+=-ggdb
debug: CPPFLAGS+=-DDEBUG
debug: all
all: lib include
lib: $(LIBDIR)/$(LIB).a $(LIBDIR)/$(LIB).so
include: $(INCLUDEDIR)
$(LIBDIR)/$(LIB).a: $(OBJ) | $(LIBDIR)
$(AR) rcs $# $^
$(LIBDIR)/$(LIB).so: $(OBJ) | $(LIBDIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -shared $(LDFLAGS) -lc $^ -o $#
$(INCLUDEDIR): $(DEP)
if [[ ! -d $# ]]; then mkdir -p $#; fi
cp $^ $#
touch $#
%.o: %.c
$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d | $(DEPDIR) $(OBJDIR)
$(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c $< -o $#
$(POSTCOMPILE)
$(DEPDIR):
mkdir -p $#
$(LIBDIR):
mkdir -p $#
$(OBJDIR):
mkdir -p $#
.PHONY: clean
clean:
rm -rf $(BUILDDIR)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))))
EDIT
$(info $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))))) produced an empty string. $(info $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC)))) produced a right list of dependencies
./build/dep/./../3rdparty/log/src/log.d ./build/dep/./uart-packet/src/uart_packet.d ./build/dep/./utils/src/utils.d ./build/dep/./telegraf/src/telegraf.d ./build/dep/./i2c/src/myproject_i2c.d ./build/dep/./spi/src/myproject_spi.d ./build/dep/./LTC2947/src/LTC2947.d ./build/dep/./sensors/src/sensors.d ./build/dep/./STCN75/src/STCN75.d
So I removed $(wildcard ...) function
However that didn't solve the problem.
To test the it I decided to run:
1. make clean
2. make
3. touch telegraf/src/telegraf.h
4. make build/obj/telegraf.d
5. make build/obj/telegraf.Td
6. make build/obj/telegraf.o
Steps 1-3 worked fine. However steps 4-6 didn't work.
Step 4 produced a following result:
make: *** No rule to make target 'buid/dep/telegraf.d'. Stop.
Step 5 produced a following result:
make: *** No rule to make target 'buid/dep/telegraf.Td'. Stop.
Step 6 simply didn't rebuild the target.
I took a look at build/dep/telegraf.d after step 2 and here is what I have there:
$ cat build/dep/telegraf.d
build/obj/telegraf.o: telegraf/src/telegraf.c ../3rdparty/log/src/log.h \
telegraf/src/telegraf.h utils/src/utils.h
../3rdparty/log/src/log.h:
telegraf/src/telegraf.h:
utils/src/utils.h:
It seems to me dependencies are generated correctly.
I also tried running make -d build/obj/telegraf.o. Unfortunately I can't post a whole output for it (stackoverflow won't allow it, message becomes to large). But here is the end of the output. (For those who are interested, full output can be seen here)
No need to remake target 'telegraf.c'; using VPATH name './telegraf/src/telegraf.c'.
Considering target file 'build/dep/telegraf.d'.
Looking for an implicit rule for 'build/dep/telegraf.d'.
Trying pattern rule with stem 'telegraf'.
Found an implicit rule for 'build/dep/telegraf.d'.
Finished prerequisites of target file 'build/dep/telegraf.d'.
No need to remake target 'build/dep/telegraf.d'.
Considering target file 'build/dep'.
Finished prerequisites of target file 'build/dep'.
No need to remake target 'build/dep'.
Considering target file 'build/obj'.
Finished prerequisites of target file 'build/obj'.
No need to remake target 'build/obj'.
Finished prerequisites of target file 'build/obj/telegraf.o'.
Prerequisite './telegraf/src/telegraf.c' is older than target 'build/obj/telegraf.o'.
Prerequisite 'build/dep/telegraf.d' is older than target 'build/obj/telegraf.o'.
Prerequisite 'build/dep' is order-only for target 'build/obj/telegraf.o'.
Prerequisite 'build/obj' is order-only for target 'build/obj/telegraf.o'.
No need to remake target 'build/obj/telegraf.o'.
make: 'build/obj/telegraf.o' is up to date.
It looks to that this line is the issue, Prerequisite 'build/dep/telegraf.d' is older than target 'build/obj/telegraf.o'.. Somehow I need to make it younger but I'm not sure how.
Any help is appreciated.
Unfortunately you've gone running off in the wrong direction here :).
You should not have removed the $(wildcard ...); that is needed/wanted.
The fact that it returned the empty string is THE problem you're having and rather than just remove it you needed to figure out why and fix it. The fact that your .d files look like ./build/dep/./../3rdparty/log/src/log.d is the problem... that is NOT the path to the .d files you are creating. You are creating files like ./build/dep/log.d
The problem is this: you are creating .d files in the recipe using this rule:
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
Here, $* is the stem of the file so for ./build/obj/log.o the value of $* will be log. So you are creating ./build/dep/log.d.
But when you convert your SRC variable to .d files in the include line, you use the basename function. This merely strips off the suffix of the path, it doesn't remove the directory. So if your source file is ./../3rdparty/log/src/log.c then basename yields ./../3rdparty/log/src/log and your wildcard matches the wrong thing.
You need to compute your wildcard for your include line like this:
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(notdir $(basename $(SRC)))))
Adding the notdir to strip out the paths, as well, will give you the dependency file you want: ./build/dep/log.d etc.

Prerequisite `myphony` of target `mytarget` does not exist when rebuilding - as if myphony was a file

My Makefile has been recompiling all my source files even if they haven't changed. I gave it a look with make -d and found stuff like this:
...
Prerequisite `setup' of target `bin/exception/Exceptions.o' does not exist.
Must remake target `bin/exception/Exceptions.o'.
...
Please note that this is what I get after bin/exception/Exceptions.o has already been compiled.
Now what on Earth does it mean by the prerequisite not existing? I've quite clearly declared it, and marked it as PHONY. This example should produce the same results for you (You should just be able to run this - I've made it produce all the necessary files for you)
OBJ_DIR=bin
SRC_DIR=src
OBJS=$(OBJ_DIR)/exception/Exception.o
.PHONY: all
all: $(OBJ_DIR)/app
.PHONY: setup
setup:
mkdir -p $(sort $(dir $(OBJS)))
# To make the source file for you
$(SRC_DIR)/%.cpp:
#mkdir -p $(dir $#)
touch $#
$(OBJ_DIR)/app: setup $(OBJS)
#echo CXX -o $#
#touch $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp setup
#echo CXX -c -o $#
#cp $< $#
If I take out the requirement for setup, then my program will not recompile unchanged sources as expected.
Why does make think it needs to rebuild?
[Phony targets] should not be [...] prerequisite[s] of a real target file.
That's from the manual section on Phony targets.
What you are seeing is part of why. make always considers a phony target as out-of-date and needing to be rebuilt. As a result (and since the file doesn't exist) that also applies to anything that depends on it.
There are two simple solutions to this problem.
The first is to make setup a Force Target instead of a .PHONY target which will allow it to operate normally (it might want to also be an Empty Target too but as long as it is touched at least once it should work).
The second is to make setup an order-only prerequisite:
$(OBJ_DIR)/app: $(OBJS) | setup
and
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | setup
You could also just make sure that the normal output target recipes create the output directory before trying to use it.
$(OBJ_DIR)/app: $(OBJS)
#mkdir -p $(#D)
#echo CXX -o $#
#touch $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
#mkdir -p $(#D)
#echo CXX -c -o $#
#cp $< $#

Issue with make

Let's consider this tiny example. Everything should work fine without the VILLAIN. Actually this word leads to an error but not where I was expecting it...
The error:
$ make
mkdir -p obj
zip out.exe obj/foo.o obj/bar.o obj/baz.o
zip warning: name not matched: obj/foo.o
zip warning: name not matched: obj/bar.o
zip warning: name not matched: obj/baz.o
zip error: Nothing to do! (out.exe)
Makefile:9: recipe for target 'out.exe' failed
make: *** [out.exe] Error 12
It seems make wants to go a bit too fast by executing a recipe where its dependencies are not already made (obj/foo.o ...). Actually I was expecting an error like: "Unable to find VILLAIN to make obj/foo.o"
The Makefile:
#!/usr/bin/env make
SRCDIR = src
OBJDIR = obj
SRC = $(addsuffix .c,foo bar baz)
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRC:c=o)))
out.exe: $(OBJ)
zip $# $^
$(OBJDIR)/%.o: $(SRCDIR)/%.c VILLAIN
cp $< $#
$(OBJ) : | $(OBJDIR)
$(OBJDIR):
mkdir -p $#
clean:
rm -f *.c
rm -rf $(OBJDIR)/ $(SRCDIR)/
mkdir -p $(SRCDIR)/
touch $(addprefix $(SRCDIR)/,$(SRC))
However if I remove the villain everything works fine:
$ make clean
rm -f *.c
rm -rf obj/ src/
mkdir -p src/
touch src/foo.c src/bar.c src/baz.c
$ make
mkdir -p obj
cp src/foo.c obj/foo.o
cp src/bar.c obj/bar.o
cp src/baz.c obj/baz.o
zip out.exe obj/foo.o obj/bar.o obj/baz.o
adding: obj/foo.o (stored 0%)
adding: obj/bar.o (stored 0%)
adding: obj/baz.o (stored 0%)
Why make try to make a target before building its prerequisite?
Pattern rules don't work like explicit rules in this respect. There can be many, many different pattern rules that could be used to create the same target (consider, a .o can be created from a C source file, C++ source file, FORTRAN source file, etc. etc.)
So, when make tries to find a pattern rule to build a target, in order to decide whether the pattern matches or not make will try to build all the prerequisites. If one of the prerequisites cannot be built, then it is not an error! Make simply goes on to the next pattern rule that matches and tries that. So the fact that VILLIAN doesn't exist and can't be built, just means that make will never select this pattern rule because the prerequisites cannot be satisfied... but this is not an error and no message will be printed (well, if you look at make's debug output you'll see a note about it).
So make will discover it has no rules that know how to build obj/foo.o. You'd expect to get an error at that point... but you won't because you've added this rule:
$(OBJ) : | $(OBJDIR)
By doing this you've declared obj/foo.o to be a target that make knows about and so it won't complain if the target doesn't exist. If you change this to add the order-only prerequisite into the pattern rule, then you'll get more comprehensible behavior:
$(OBJDIR)/%.o: $(SRCDIR)/%.c VILLAIN | $(OBJDIR)
cp $< $#
$(OBJDIR):
mkdir -p $#
Gives:
make: *** No rule to make target 'obj/foo.o', needed by 'out.exe'. Stop.

Resources