Program_name: linker input file unused because linking not done - c

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.

Related

I have been working on this makefile for hours. It keep getting the error: make: *** No rule to make target 'hangman.c', needed by 'hangman.o'. Stop

CFLAGS=-std=c99 -Wall
CC=gcc
hangman: hangman.o hangman.c
$(CC) $(CFLAGS) hangman.o hangman.c -o hangman
hangman.o: hangman.c
$(CC) $(CFLAGS) -c hangman.c
clean:
rm -f hangman *.o
Well, hangman (the program binary) only depends of hangman.o, but not of hangman.c, which has already been compiled into hangman.o (at compilation phase).
In Makefile, you only state the direct dependencies, while make(1) does the rest of the work.
I use to designate all the objects to a program in a variable, as they will be used several times. In this way:
# Makefile -- make file for hangman.
targets = hangman
hangman_objs = hangman.o
hangman: $(hangman_objs)
$(CC) $(LDFLAGS) -o hangman $(hangman_objs)
and nothing else, as make(1) has an automatic rule, that is
.c.o:
$(CC) $(CFLAGS) -o $# -c $<
which is the equivalent to this rule:
hangman.o: hangman.c
$(CC) $(CFLAGS) -o hangman.o -c hangman.c
(and the same for each .c and .o file you can have.)
By the way, the error you are receiving, is that make has found a dependency on hangman.c but doesn't find any file called hangman.c so it needs to build it, but you don't provide this file. You have probably erased your hangman.c file (which is something that sometimes happen if you mispell files in the Makefile, make ends erasing files that are important for you) In this case, it tries to build handman which depends on handman.o which depends on handman.c, so no finding handman.c makes make(1) to say, I have a dependency on handman.c but no such file is found (and I have no dependency to follow that allows me to build it)
If your project is a single source project, then you can avoid the generation of hangman.o and create a Makefile like this:
hangman: hangman.c
$(CC) $(CFLAGS) $(LDFLAGS) -o hangman hangman.c
Which states an explicit, direct reference from the binary to the source code. In this case, you don't use the -c flag to the compiler to just compile, and don't link, and build your executable directly with one command. This is not used in large projects, as normally you want to just compile the sources that have changed. As in this example:
hangman_objs = hang.o man.o foo.o bar.o a.o b.o c.o
hangman: $(hangman_objs)
$(CC) $(LDFLAGS) -o hangman $(hangman_objs)
if you expand the variable, you'll get this rule:
hangman: hang.o man.o foo.o bar.o a.o b.o c.o
cc -o hangman hang.o man.o foo.o bar.o a.o b.o c.o
#all this are automatic dependencies generated from
# .c.o:
# $(CC) $(CFLAGS) -c $< -o $#
# for the files hang.o man.o foo.o bar.o a.o b.o c.o
hang.o: hang.c
cc -O2 -pipe -c hang.c -o hang.o
man.o: man.c
cc -O2 -pipe -c man.c -o man.o
foo.o: foo.c
cc -O2 -pipe -c foo.c -o foo.o
bar.o: bar.c
cc -O2 -pipe -c bar.c -o bar.o
a.o: a.c
cc -O2 -pipe -c a.c -o a.o
b.o: b.c
cc -O2 -pipe -c b.c -o b.o
c.c: c.c
cc -O2 -pipe -c c.c -o c.o
but you must not use both, the object code and the source code in the linking phase of your program. The compiler will link the file you provide hangman.o and will compile it also (which generates a new hangman.o) and will try to link both (two versions of the same code) and that can generate new errors.
My approach to your program would be:
# main targets to build (programs)
targets = hangman
# toclean maintains everything must be erased on clean.
toclean = $(targets)
# object files of hangman target
hangman_objs = hangman.o foo.o
# add all those objects to the toclean variable.
toclean += $(hangman_objs)
# libraries
hangman_ldflags = -L path/to/libbar
hangman_libs = -lbar
# main target all
all: $(targets)
# ... and clean
clean:
rm -f $(toclean)
# just the link phase, the compiling is automatically done.
hangman: $(hangman_objs)
$(CC) $(LDFLAGS) $($#_ldflags) -o $# $($#_objs) $($#_libs)

How to resolve GNU make producing a "circular main.c" error

//makefile.conf
.SUFFIXES : .c .o
cc = gcc
CFLAG = -c
OFLAG = -o
O2FLAG = -O2
WPIFLAG = -lwringPi
RM = rm -rf
TARGET_SRCS = main.c
TARGET_OBJS = $(TARGET_SRCS:$.c=$.o)
TARGET_NAMES = $(TARGET_SRCS:$.c=$)
BINARY_NAME = LED_TEST
// makefile
include makefile.conf
$(TARGET_OBJS) : $(TARGET_SRCS)
$(CC) $(O2FLAG) $(CFLAG) $(OFLAG) $^
I'm trying to figure out how gnu make works and how to use it. Yet, I'm a beginner.
I'm trying to use make on my assignment (not mandatory, just my passion) for running simple code which lights up LED by using wiringpi.
Actually there's only one main.c and what I want to make is the makefile that runs
gcc -O2 -c -o main.o main.c
gcc -o main main.o -lwiringPi
Since my last code didn't worked, (constantly getting circular main.c <- main.c dependency dropped error)
I tried to make a code that only runs
gcc -O2 -c -o main.o main.c
but I still get circular main.c error and I don't know what that means.
I tried to look up gnu make manuals but I thought through that, it will take my life to understand.
So I'm trying to see the codes and make one with what I saw.
I think I understand the concept of makefile.conf but still don't understand the function of .SUFFIXES.
I understood it as noticing make that I'll make a rule with .c and .o, codes after that in makefile.conf defines the variables those will be used in makefile.
How can I correct the code? When actual 'assignment' took only five minute including adding comments.
First makefile:
main:
gcc -O2 -c -o main.o main.c
gcc -o main main.o -lwiringPi
When that works perfectly, second makefile:
main: main.o
gcc -o main main.o -lwiringPi
main.o: main.c
gcc -O2 -c -o main.o main.c
When that works perfectly, third makefile:
main: main.o
gcc -o $# $^ -lwiringPi
main.o: main.c
gcc -O2 -c -o $# $<
When that works perfectly, you will be ready for more advanced techniques.
If you are really new, it's often helpful to start off with simple makefiles till you need the extra features.
main: main.c
gcc -O2 -o main -lwiringPi main.c
Note the white space before the gcc is a single tab character.
Once you get the hang of that, you can then substitute various items to make your "make rules" easier to duplicate and maintain. For example, %^ means "every dependent source, so a rewrite of the rule would be
main: main.c
gcc -O2 -o main -lwiringPi $^
Occasionally, you might want to offer easy reconfiguration of the compiler, so if you had a dozen rules, and wanted to configure the compiler all in one place
CC=gcc
main: main.c
$(CC) -O2 -o main -lwiringPi $^
would expand the CC variable to the value gcc at make time. There's an upper limit to the utility of this expansion, for example, if something is "one of many of the same thing" You might not want to declare a variable for that individual item. For example, your WPIFLAG is likely always required, and probably not very successfully reconfigurable. Mabye a loader flags variable makes more sense.
LDFLAGS=-lwiringPi -lm -lwhatever
and a compiler flags variable
CFLAGS=-O2 -Werror -Wfatal-errors
Which would lead to the more sensible
main: main.c
$(CC) $(CFLAGS) -o main $(LDFLAGS) $^
Finally, you can replace the target main in this case, with another special variable. $# which means "the target being built"
main: main.c
$(CC) $(CFLAGS) -o $# $(LDFLAGS) $^
Note that for object files, you are listing all your objects as being dependent on all of your sources. If you want to support independent rules for object building, you need to do something different
main: main.o
$(CC) $(CFLAGS) -o $# $(LDFLAGS) $^
And you'll need rules for each object.
main.o: main.c
$(CC) $(CFLAGS) -c -o $# $(LDFLAGS) $^
but it will become a labor typing this rule for each object. To automate this rule, you will use a pattern based on the file suffixes, and a suffix rule.
.SUFFIXES : .o .c
.c.o :
$(CC) $(CFLAGS) -c $<
Note the rule above relies on the default behavior of $(CC) which is to generate a something.o when something.c is compiled with the -c flag. If you wanted to make the output file explicit
.SUFFIXES : .o .c
.c.o :
$(CC) $(CFLAGS) -c -o $# $<
This Suffix Rule acts as a macro. When someone needs thing.o, it will build it from thing.c if thing.c exists, even if there isn't an explicit rule for thing.c
With this, you can then collect all your object on the original main target. (We will remove CFLAGS, as no compiling will be happening, only linking)
main: main.o other.o first.o list.o end.o
$(CC) -o $# $(LDFLAGS) $^
But some find listing the object to be a pain, and like to put them in a variable
main: $(OBJS)
$(CC) -o $# $(LDFLAGS) $^
which means you will need to declare and set OBJS
OBJS = main.o other.o first.o list.o end.o
But it's sort of weird to track intermediate files, so why not track the actual sources
SOURCES = main.c other.c first.c list.c end.c
Ok, but how will we get the required OBJS from SOURCES? We will derefence SOURCES, modifying the suffixes to .o
OBJS = ${SOURCES:.c=.o}
The end result
SOURCES = main.c other.c first.c list.c end.c
OBJS = ${SOURCES:.c=.o}
CC=gcc
CFLAGS=-O2 -Werror -Wfatal-errors
LDFLAGS=-lwiringPi -lm -lwhatever
.SUFFIXES : .o .c
.c.o :
$(CC) $(CFLAGS) -c -o $# $<
main: ${OBJS}
$(CC) -o $# $(LDFLAGS) $^

"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 ignores -std=c99 flag when compiling and linking a C program

I've tried to get my makefile to compile a file that requires -std=c99 to run. In this case, its to get a "for-loop" through.
This is my code, (its been used "tab" before "$(CC)" ):
CC = gcc
CFLAGS = -c -std=c99
...
Download.o : Download.c
$(CC) $(CFLAGS) Download.c
Download.c contains methods used to download elements from the web
Error message
$ make
gcc -c -std=c99 Download.c
gcc Download.c -o Program
Download.c: In function ‘downloadImageparts’:
Download.c:11:2: error: ‘for’ loop initial declarations are only allowed in C99 mode
Download.c:11:2: note: use option -std=c99 or -std=gnu99 to compile your code
Download.c:13:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
make: *** [comp] Error 1
Attemt to debug
If I run gcc -c -std=c99 Download.c in terminal it works fine.
This problems appears when run in Linux.
SOLVED:
I created a dummy project to show my lecturer, in an attempt to solve my problem. In the dummy project all works fine with the code described. For some reason my code works on place but not in the other. If someone reading this having the same problem as me and would like to see an example project. let me know and I'll write the code here. Thanks
You're looking at the wrong rule. Download.c is actually compiling fine, but the linking stage is wrong.
$ make
gcc -c -std=c99 Download.c # Compile
gcc Download.c -o Program # Link
Fix the make rule that links the program. It should probably look something like this:
Program: a.o b.o c.o
$(CC) $(LDFLAGS) -o $# $^ $(LIBS)
While you're at it, I suggest a more complete Makefile will look something like this:
all: Program
clean:
rm -f Program *.o
.PHONY: all clean
# -c is implicit, you don't need it (it *shouldn't* be there)
# CC is also implicit, you don't need it
CFLAGS := -std=c99 -g -Wall -Wextra
Program: a.o b.o c.o
$(CC) $(LDFLAGS) -o $# $^ $(LIBS)
# Make will automatically generate the necessary commands
# You just need to name which headers each file depends on
# (You can make the dependencies automatic but this is simpler)
a.o: a.c header.h
b.o: b.c header.h header2.h
c.o: c.c header.h
Examples of how to do it wrong
Linker flags are actually fairly touchy! Be sure to type in the line above exactly as I have written it, and don't assume that what you've written is equivalent. Here are some examples of slightly different commands that are wrong and should not be used:
# WRONG: program must depend on *.o files, NOT *.c files
Program: a.c b.c c.c
$(CC) ...
# WRONG: -c should not be in CFLAGS
CFLAGS := -c -std=c99
Program: a.o b.o c.o
# WRONG: $(CFLAGS) should not be here
# you are NOT compiling, so they do not belong here
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
# WRONG: $(LIBS) MUST come at the end
# otherwise linker may fail to find symbols
$(CC) $(LDFLAGS) -o $# $(LIBS) $^
# WRONG: do not list *.o files, use $^ instead
# otherwise it is easy to get typos here
$(CC) $(LDFLAGS) -o $# a.o b.o c.o $(LIBS)
# WRONG: $(LDFLAGS) must be at the beginning
# it only applies to what comes after, so you
# MUST put it at the beginning
$(CC) -o $# $(LDFLAGS) $^ $(LIBS)
# WRONG: -c flag disables linking
# but we are trying to link!
$(CC) $(LDFLAGS) -c -o $# $^ $(LIBS)
# WRONG: use $(CC), not gcc
# Don't sabotage your ability to "make CC=clang" or "make CC=gcc-4.7"
gcc $(LDFLAGS) -o $# $^ $(LIBS)
# WRONG: ld does not include libc by default!
ld $(LDFLAGS) -o $# $^ $(LIBS)
I see the same results if I use spaces instead of tabs inside the makefile, and the output of make shows that the rule isn't being used:
$ make
cc -c -o Download.o Download.c
Download.c: In function ‘main’:
Download.c:4:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
Download.c:4:3: note: use option -std=c99 or -std=gnu99 to compile your code
make: *** [Download.o] Error 1
Try a tab before the line starting with gcc.
After seeing the update to the original question:
$ make
gcc -c -std=c99 Download.c
gcc Download.c -o Program
The first (compile) line shows no errors.
It's the second line, which re-compiles Download.c, that fails.
I think you want to link the .o files to create the executable Program here, as Dietrich Epp suggests.

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