how to write a simple makefile for c - 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

Related

How to link math.h library in a makefile?

i need to compile 3 files- part1.c, part2.c, and part3.c in a makefile.
only part3.c needs to use the <math.h> library.
Before a makefile, this is what the gcc commands will look like:
gcc -g -o part1 part1.c
gcc -g -o part2 part2.c
gcc -g -o part3 part3.c -lm
When i try to use a makefile to run the "make" command, i keep getting errors and it does not recognize any of the math functions from the math.h library.
This is what i have in my makefile so far that is not working:
CC = gcc
CFLAGS = -Wall -g
all: driver1
clean:
rm -f *.o driver1
part1.o: part1.c
$(CC) $(CFLAGS) -c part1.c
part2.o: part2.c
$(CC) $(CFLAGS) -c part2.c
part3.o: part3.c
$(CC) $(CFLAGS) -c part3.c -lm
driver1: part1.o part2.o part3.o
$(CC) $(CFLAGS) -o driver1 part1.o part2.o part3.o
i had tried to run the makefile i provided, but it was giving me errors. any help will be appreciated
part3.o does not need to link with the library although it uses its header file. You need the library when linking everything into driver1:
# ...
part3.o: part3.c
$(CC) $(CFLAGS) -c part3.c
driver1: part1.o part2.o part3.o
$(CC) $(CFLAGS) -o driver1 part1.o part2.o part3.o -lm

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).

"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

Make: Totally ignoring a rule

I am trying to compile my project after adding a new source(processHandling.c) and I am getting this as a result when I 'make'
gcc -gstabs -W -Wall -std=gnu99 -c main.c
gcc -gstabs -W -Wall -std=gnu99 -c inputHandling.c
gcc -gstabs -W -Wall -std=gnu99 -c syscallsWrapper.c
gcc -gstabs -W -Wall -std=gnu99 -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
gcc: error: processHandling.o: No such file or directory
make: *** [myShell] Error 1
This is the makefile
CC = gcc
CFLAGS = -gstabs -W -Wall -std=gnu99
myShell: main.o inputHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
main.o: main.c
$(CC) $(CFLAGS) -c main.c
inputHandling.o: inputHandling.c
$(CC) $(CFLAGS) -c inputHandling.c
processHandling.o: processHandling.c
$(CC) $(CFLAGS) -c processHandling.c
syscallsWrapper.o: syscallsWrapper.c
$(CC) $(CFLAGS) -c syscallsWrapper.c
clean:
-rm myShell *.o
I tried running make with the -d flag and it seems make for some reason is totally ignoring the rule to compile processHandling.o; what could the problem be?
Also note that if I compile processHandling manually using gcc -c everything works fine.
Add processHandling.o to the dependency list for the myShell target:
myShell: main.o inputHandling.o processHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
By the way, using automatic variables can help reduce the repeated file names. For example:
myShell: main.o inputHandling.o processHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o $# $^
You need to add "processHandling.o" as a prerequisit of myShell. Otherwise when making myShell, the rule for processHandling.o will not be applied because the makefile thinks that that processHandling.o is not needed for myShell. You can simply add it like this
myShell: main.o inputHandling.o syscallsWrapper.o processHandling.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
Check if you really have the file processHandling.c. This error implies that the source file has not been found.

Resources