Makefile: No rule to make target despite giving target? - c

While trying to use Make I get the following error:
make: *** No rule to make target `paging.c', needed by `obj/paging.o'. Stop.
But I have given the makefile the rule for making the target. Here's my makefile:
--------
C_SOURCES= main.c monitor.c common.c descriptor_tables.c timer.c paging.c \
fs.c initrd.c task.c syscall.c --------
S_SOURCES= boot.s interrupt.s gdt.s process.s
C_OBJECTS=$(patsubst %.c, obj/%.o, $(C_SOURCES))
S_OBJECTS=$(patsubst %.s, obj/%.o, $(S_SOURCES))
CFLAGS=-c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders
LDFLAGS=-Tlink.ld -melf_i386 --oformat=elf32-i386
ASFLAGS=-felf
all: kern/kernel
.PHONY: clean
clean:
-rm -f obj/*.o kern/kernel
kern/kernel: $(S_OBJECTS) $(C_OBJECTS)
ld $(LDFLAGS) -o $# $^
$(C_OBJECTS): obj/%.o : source/%.c
gcc $(CFLAGS) $< -o $#
vpath %.c source
$(S_OBJECTS): obj/%.o : %.s
nasm $(ASFLAGS) $< -o $#
vpath %.s asem
NOTE: the -------- is not in the original makefile, they are just used to pick the rule I have used.
make output:
nasm -felf asem/boot.s -o obj/boot.o
nasm -fenasm -felf asem/boot.s -o obj/boot.o
nasm -felf asem/interrupt.s -o obj/interrupt.o
nasm -felf asem/gdt.s -o obj/gdt.o
nasm -felf asem/process.s -o obj/process.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/main.c -o obj/main.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/monitor.c -o obj/monitor.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/common.c -o obj/common.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/descriptor_tables.c -o obj/descriptor_tables.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/timer.c -o obj/timer.o
make: *** No rule to make target `source/paging.c', needed by `obj/paging.o'. Stop.
Why is it coming out with the error despite giving it what it needs?

You will have to change the line
$(C_OBJECTS): obj/%.o : %.c
to
$(C_OBJECTS): obj/%.o : source/%.c
edit, in reflect of question change:
void page_fault(registers_t regs)
void page_fault(registers_t *regs);
Compare ;) The two should be the same. According to the code chunk from paging.c, the version in paging.h should be corrected (just remove the *).

Does the file paging.c exist in the same directory as the Makefile?
If it does not, Make will look for a rule to create it. Since there is no rule to create paging.c, it will give you this error.

The error is telling you that "make" cannot find the file "paging.c" anywhere in the vpath or in the current directory, and it has no rule to create "paging.c" from any other source file.
Make sure that you actually have "paging.c" where you think you do, and that it is actually called "paging.c" and not "paging.c " (extra space) or some other unicode special stuff that looks like "paging.c" when you print it out, but isn't.

Related

Program_name: linker input file unused because linking not done

I have 6 programs: HOSpital.c, GenPazienti.c, Triage.c, Paziente.c, Prestazione.c and Reparto.c.
No one of them includes any other.
How can i do the makefile?
I tried with:
all: HOSpital GenPazienti Paziente Prestazione Reparto Triage
HOSpital: HOSpital.o
gcc -o HOSpital HOSpital.c
HOSpital.o: HOSpital.c
gcc -c HOSpital HOSpital.c
GenPazienti: GenPazienti.o
gcc -o GenPazienti GenPazienti.c
GenPazienti.o: GenPazienti.c
gcc -c GenPazienti GenPazienti.c
Paziente: Paziente.o
gcc -o Paziente Paziente.c
Paziente.o: Paziente.c
gcc -c Paziente Paziente.c
Prestazione: Prestazione.o
gcc -o Prestazione Pretazione.c
Prestazione.o: Prestazione.c
gcc -c Prestazione Prestazione.c
Reparto: Reparto.o
gcc -o Reparto Reparto.c
Reparto.o: Reparto.c
gcc -c Reparto Reparto.c
Triage: Triage.o
gcc -o Triage Triage.c
Triage.o: Triage.c
gcc -c Triage Triage.c
clean:
rm -f *.o
But if i change something and i type "make" i get the error:
"Program_name: linker input file unused because linking not done"
Lets take a single example:
gcc -c HOSpital HOSpital.c
This will attempt to use HOSpital as an input file.
Either use the correct option to name the output file, -o, and name it correctly. Like in
gcc -c -o HOSpital.o HOSpital.c
Or don't specify the output file name at all, then the compiler will use the input source file and change the .c suffix to .o. Like in
gcc -c HOSpital.c
It's the same problem all over.
Not that it matters in the end, the rule is used so the object file will be built, but you don't actually use the object file:
gcc -o HOSpital HOSpital.c
Here you use the source file directly to create the program. I think you meant to use
gcc -o HOSpital.o HOSpital.o
And as with the previous problem, you make this mistake all over.
Finally some general tips.
First, build with more warnings enabled. It will help you in the long run to find mistakes in the code, and will help find out places where there's possible undefined behaviors. I recommend at least adding -Wall -Wextra -pedantic.
Then you don't need to list all the object files and their rules explicitly in the makefile. The make program already knows how to make e.g. object files through implicit rules.
That last point means you can shorten down the makefile to something like
CFLAGS = -Wall -Wextra -pedantic -pipe
LD = gcc
LDFLAGS = -pipe
HOSpital: HOSpital.o
$(LD) $(LDFLAGS) -o $# $^
GenPazienti: GenPazienti.o
$(LD) $(LDFLAGS) -o $# $^
Paziente: Paziente.o
$(LD) $(LDFLAGS) -o $# $^
Prestazione: Prestazione.o
$(LD) $(LDFLAGS) -o $# $^
Reparto: Reparto.o
$(LD) $(LDFLAGS) -o $# $^
Triage: Triage.o
$(LD) $(LDFLAGS) -o $# $^
clean:
-rm -f *.o
The variable $# is the target of the rule, and the variable $^ is all prerequisites. For e.g.
HOSpital: HOSpital.o
the variable $# is HOSpital and $^ is HOSpital.o.

What does "linker input file unused because linking not done" mean? (C makefile)

I have created a makefile to compile and link my program, however, I can't figure out why I am getting this error. Is it to do with SDL?
GCC = gcc
CFLAGS = -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g
SDL = -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer
all: ./game
game: global.o display.o player.o entities.o controls.o sound.o menu.o
$(GCC) $(CFLAGS) global.o display.o player.o entities.o controls.o sound.o menu.o -o game
global.o: global.c
$(GCC) $(CFLAGS) $(SDL) global.c
display.o: display.c
$(GCC) $(CFLAGS) $(SDL) display.c
player.o: player.c
$(GCC) $(CFLAGS) $(SDL) player.c
entities.o: entities.c
$(GCC) $(CFLAGS) $(SDL) entities.c
controls.o: controls.c
$(GCC) $(CFLAGS) $(SDL) controls.c
sound.o: sound.c
$(GCC) $(CFLAGS) $(SDL) sound.c
menu.o: menu.c
$(GCC) $(CFLAGS) $(SDL) menu.c
clean:
rm *o game
Your linking command expands to:
gcc -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g global.o display.o player.o entities.o controls.o sound.o menu.o -o game
which, as you can see, has the -c flag in it. The -c flag tells gcc not to do linking. So it has nothing to actually do. (.o files can only be used for linking, and you've disabled linking, which is why you get that message)
You don't want to use the same flags for compiling and linking. For compiling you probably want -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -g, and for linking you want -lm -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -g.
there are several small oversights in the posted makefile.
Amongst them:
library names are only used during the link step, not the compile step
suggest using the 'wildcard' make operator to get a list of the source files. Then use a patterm replacement operator to get a list of the object files:
for instance:
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
when a target (all, clean) will not produce a file of the same name, then insert a .PHONY: statement early in the make file:
similarly to:
.PHONY : all clean
the posted make file has no facilities to handle the associated header files, There are several ways to handle that. This follows the OPs lead and does not handle the header files, so changing a header file will not recompile/relink the effected source files.
this line: rm *o game will not remove the name.o files as it is missing the '.' between the root name and the 'o' extension. Also, the '-f' flag should be used with the 'rm' command.
suggest:
rm -f *.o game
this line: all: ./game can create problems
suggest:
all: game
once the list of object files is created (as above) then the compile rules can be reduced:
by using the make operators:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $# -I.
the -g parameter to the compiler and linker allows for a debugger to be used. If that debugger is gdb then a better parameter is -ggdb
almost always, there is no need to evaluate a macro definition more than once, so rather than using = in a macro definition, use :=
If you want the game to be executable, then insert a chmod command as the last line in the 'link' rule
Suggest reading about the special operators that can be employed in a makefile to help you understand the following, suggested makefile
It is usually best to replace calls to the shell recognized commands with macros.
CC := /user/bin/gcc
RM := /usr/bin/rm
CFLAGS := -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -ggdb
LFLAGS := -std=c99 -O3 -ggdb
SDL := -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer
SRC := $(wildcard *.c)
OBJS := $(SRC:.c=.o)
.PHONY : all clean
all: game
game: $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o $# $(SDL) -lm
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $# -I.
clean:
$(RM) -f *.o game
Do not put -lm or the SDL libraries into CFLAGS, library operands go to the end of the command line. Instead, use an extra variable LDLIBS and modify your game rule like this:
game: global.o display.o player.o entities.o controls.o sound.o menu.o
$(GCC) $(CFLAGS) -o $# global.o display.o player.o entities.o controls.o sound.o menu.o $(LDLIBS)
The -lm operand (it's not an option) and the operands for SDL only apply when linking, thus it should not be part of CFLAGS and should not be specified when compiling without linking (i.e. when -c is supplied).

Makefile fails with warning message

This is a makefile that fails to link the .o files to make an executeable.
enter code here
CC = c99
CFLAGS = -g -Wall -Wextra -O0
OBJECTS = main.o getoptions.o
P = testprog
$(P): $(OBJECTS)
$(CC) $(OBJECTS) -o $(P)
main.o : main.c
$(CC) $(CFLAGS) $(OBJECTS) -c main.c
getoptions.o : getoptions.c getoptions.h
$(CC) $(CFLAGS) -c getoptions.o
I get this warning:
gcc: warning: getoptions.o: linker input file unused because linking not done
When I manually use:
c99 *.o -o testprog
linking succeeds.
Two issues here:
First, in your target for getoptions.o, you're passing getoptions.o for the -c option. You should be giving it the value of the source file getoptions.c
Second, get rid of $(OBJECTS) in the target for main.o. You don't need to pass in the object files for this step.
With those fixes you'll get a successful compilation:
c99 -g -Wall -Wextra -O0 -c main.c
c99 -g -Wall -Wextra -O0 -c getoptions.c
c99 main.o getoptions.o -o testprog
Edit:
The target line for main.o should be:
main.o : main.c getoptions.h
That way, if getoptions.h changes, main.o gets rebuilt.

"make clean" causes "make all" failure

When I execute this Makefile without clean, it functions OK and both the shared library and the main executable are created correctly. However, when I add the clean target, the "make all" fails. What could be the reason?
CC = gcc
CFLAGS = -fPIC -Wall -Werror
LDFLAGS = -shared
TARGET_LIB= libnsd.so
lib: nsd.o nd.o
$(CC) $(LDFLAGS) -o ${TARGET_LIB} nsd.o nd.o -lm
nd.o : nd.c nd.h
$(CC) -c $(CFLAGS) nd.c
nsd.o : nsd.c nsd.h
$(CC) -c $(CFLAGS) nsd.c
all: main.c
$(CC) -o -I. -L. main.c -lnsd
clean:
rm -f libnsd.so nd.o nsd.o
Your all: target needs to depend on the lib target, so the library is built first.
The -o argument to the compiler also needs a name for executable it should create.
all: lib main.c
$(CC) -o main -I. -L. main.c -lnsd
Normally you want the target name to be the file that you create, otherwise things get rebuilt when it's not needed. (the lib: target has the same issue) but as an exampe for the executable:
.PHONY: all
all: lib main
main: lib main.c
$(CC) -o main -I. -L. main.c -lnsd
nos's answer is on the right track.
It only appeared to work before, because you happened to run make in the right order. It won't work after a clean operation because, as nos points out, you have not declared all of your prerequisites. The rule that links main.o must depend on the shared library target, so make knows the right order to build things.
Also, you REALLY want your targets to be the actual file you're building. If they're something else, then make will always think they're out of date even if you haven't changed anything, and always rebuild them.
Something like this will be better:
CC = gcc
CFLAGS = -fPIC -Wall -Werror
CPPFLAGS = -I.
LDFLAGS = -shared
PROGRAM = main
TARGET_LIB= libnsd.so
all: $(PROGRAM)
$(PROGRAM): main.o $(TARGET_LIB)
$(CC) -o $# -L. main.o -lnsd
$(TARGET_LIB): nsd.o nd.o
$(CC) $(LDFLAGS) -o $# nsd.o nd.o -lm
nd.o : nd.c nd.h
nsd.o : nsd.c nsd.h
clean:
rm -f libnsd.so *.o

how to write a simple makefile for c

I need to write a simple make file for my.c, and so after
make
then my program can be run by
./my
my.c can be compiled by this:
gcc cJ/cJ.c my.c -lcrypto -o my -lm
Thanks
I put this in my makefile
all:my
my: cJ.o my.o
gcc cJ.o -lcrypt my.o -o my
cJ.o: cJ/cJ.c
gcc -c cJ/cJ.c
my.o: my.c
gcc -c my.c -lm
help please
Well, makefiles are just kind of special scripts. Every is unique, for such simple task this would be sufficient:
Makefile:
CC=gcc
CFLAGS=-lm -lcrypto
SOURCES=my.c cJ/cJ.c
all: my
my: $(SOURCES)
$(CC) -o my $(SOURCES) $(CFLAGS)
Later you may want to use some other options such as wildcards %.c to compile in multiple files without having to write them in.
Alternatively:
CC=gcc
CFLAGS=-lm -lcrypto
MY_SOURCES = my.c cJ/cJ.c
MY_OBJS = $(patsubst %.c,%.o, $(MY_SOURCES))
all: my
%o: %.c
$(CC) $(CFLAGS) -c $<
my: $(MY_OBJS)
$(CC) $(CFLAGS) $^ -o $#
Note that lines following each target ("my:", ...) must start with tab (\t), not spaces.
Just a minor correction: put the -lm to the linking step, and there after all object files.
all: my
my: cJ.o my.o
gcc cJ.o my.o -o my -lcrypt -lm
cJ.o: cJ/cJ.c
gcc -c cJ/cJ.c
my.o: my.c
gcc -c my.c
And then, you could work more with automatic variables:
all: my
my: cJ.o my.o
gcc $^ -o $# -lcrypt -lm
cJ.o: cJ/cJ.c
gcc -c $^
my.o: my.c
gcc -c $^
where $# is the target of the current rule and $^ are the prerequisites.
See also http://www.gnu.org/software/make/manual/make.html.
simple make file for your program is
build :
gcc /your_full_path_to_c_file/cJ.c my.c -lcrypto -o my -lm
just copy this in one file keep name of that file as makefile
then run as make build

Resources