No such file or directory error when using make - c

I am still relatively new to Linux, but I have an assignment in my operating systems class that involves several files. My professor gave us his makefile, but it isn't working for me. Make just returns errors. I know that I have all of the same files as my professor and, although mine aren't done yet, there is no reason I see for the code to not compile.
Here is the Makefile:
sync: sync.c prodcons.c prodcons.h producer.c producer.h consumer.c consumer.h Makefile
${CC} -g -Wall -pthread -o sync ssync.c prodcons.c producer.c consumer.c ln -sf sync assn4
and here is the error message I am getting:
J_studentid#cs3060:~/assn4$ make
cc -g -Wall -pthread -o sync sync.c prodcons.c producer.c consumer.c ln -sf sync assn4
cc: error: ln: No such file or directory
cc: error: sync: No such file or directory
cc: error: assn4: No such file or directory
cc: error: unrecognized command line option ‘-sf’; did you mean ‘-Hf’?
Makefile:2: recipe for target 'sync' failed
make: *** [sync] Error 1
J_studentid#cs3060:~/assn4$
I saw the professor compile and run the code in class, so I know it has the potential to work, but it is giving me problems. I am more than happy to provide more information or code, but I don't think the contents of the files is relevant to the compilation errors. Thank you!

I am pretty sure that this is the intended source code of your makefile that is both valid and working:
all:
${CC} -g -Wall -pthread -o sync ssync.c prodcons.c producer.c consumer.c
ln -sf sync assn4
Issues with your makefile were:
No default target, i.e. missing all:
ln -sf sync assn4 were used as compiler arguments
Also, please make sure that the command lines (e.g., ${CC} ...) always start with a TAB character. I cannot tell whether there was some in your codeblock since they are changed to spaces automatically here but wanted to point out.

Related

Creating a makefile - (C)

I am trying to create a simple makefile. I have one headerfile: "guiBuilder.h". I have another file that will be using it: "client.c". The makefile that I am using is:
HEADERS = guiBuilder.h
default: program
program.o: client.c $(HEADERS)
gcc -c client.c -o client.o
program: client.o
gcc client.o -o Client
I found the code for the makefile here:
How do I make a simple makefile for gcc on Linux?
I now get this error when i run it:
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:9: recipe for target 'program' failed
make: *** [program] Error 1
Rules in a make file are of the form:
target: dependency1 dependency2 etc
command to build target
target is the name of the file you want to build. So the line
program: client.o
gcc client.o -o Client
Is trying to build a file called program. However, the command does not create a file called program, it creates a file called Client. This is less of a problem than you might think, it just means that the rule is always executed whether Client is up to date or not. However, you should change it so the target is the file you are building.
Client: client.o
gcc client.o -o Client
By the way, in most *nixes, file names are case sensitive Client and client are different files on Linux, for example.
That rule has a single dependency: client.o. Unfortunately, your make file does not know how to build client.o - there is no target called client.o.
I am speculating the cause of your error is that you have an old client.o hanging about that doesn't have a main() function in it. This is why the link (the gcc command in the program target) is failing.
The target program.o has the same problem as the target program. You are not building program.o, you are building client.o. This target needs to be changed to
client.o: client.c $(HEADERS)
gcc -c client.c -o client.o
which is happily the dependency for your Client target.
Note The indentation for the command part of a make rule has to be done with a tab. If copy-pasting my answer or any of the other answers, or the answers in the linked question, please make sure your indents are tabs, not spaces.
Update (the issue with test() being an undefined reference)
If you have a function in guiBuilder.c that has a prototype in guiBuilder.h you'll need to compile guiBuilder.c and add it to the link phase.
Your rule for guiBuilder.o will look very similar to the rule for client.o
guiBuilder.o: guiBuilder.c $(HEADERS)
gcc -c guiBuilder.c -o guiBuilder.o
Then you need to add guiBuilder.o as a dependency of Client
Client: client.o guiBuilder.o
gcc client.o guiBuilder.o -o Client
You may have noticed that you now have two rules for creating .o files that are identical other than the names of the source and object files. The accepted answer to the question that you linked shows how you modify the make file so you only need to define the rule once.
I will suggest you to read the GNU Make manual to get a better understanding of how make command and makefile works.
To answer your question, in short, Makefile consists of several things out of which the basic things are target, dependency and recipe. In the following manner
target: dependency
recipe
When you run make command, it searches for a file with name Makefile or makefile and it starts parsing target and dependency and executes the recipe for that target.
In your makefile you want to create final binary with name program but you don't have program.c so your makefile should go something like below:
HEADERS = guiBuilder.h
all: program
client.o: client.c $(HEADERS)
gcc -c client.c
program: client.o
gcc client.o -o program

C Makefile error: ld returned 1 exit

My teacher is not the best at explain C so I'm having a bit of trouble understanding the connection of makefiles. I have already added the code for complex.c, complex.h, and main.c. I'm just having trouble compiling it all using the make command. I followed the example on the powerpoint he handed up and I don't understand why its failing to get to complex.
makefile
complex: main.o complex.o
gcc -o complex main.o complex.o
main.o: main.c complex.h
gcc -c main.c -lm
complex.o: complex.c complex.h
gcc -c complex.c -lm
clean:
rm*.o complex
ls
main.o
main.o: complex.h
gcc -c main.c
complex.o
complex.o: complex.h
gcc -c complex.c
Error
mason% make
gcc -o complex main.o complex.o
ld: fatal: file main.o: unknown file type
ld: fatal: file processing errors. No output written to complex
collect2: error: ld returned 1 exit status
*** Error code 1
make: Fatal error: Command failed for target `complex'
It looks like you have put Makefile fragments inside main.o and complex.o. These should be generated by the compiler, not by you.
Delete these files, and make again.
Additionally, your make clean rule is missing a space.
clean:
rm *.o complex
ls
One more thing. No need for -lm in the compile lines.
main.o: main.c complex.h
gcc -c main.c
complex.o: complex.c complex.h
gcc -c complex.c
You should add -lm at the linking phase.
complex: main.o complex.o
gcc -o complex main.o complex.o -lm
The "Makefile" defines and controls the build dependencies.
For example, you can't build the main executable binary without first building the binary object/module files that go with it. In this case, those are main.o and complex.o.
Generally any object file you need also needs a rule (though some rules can use "wildcards" to build more).
This is all rather academic. Best to take errors at their word and try to disprove them (this one basically says that main.o exists and is incorrect). In this case the hypothesis that main.o exists is supported by the fact that it didn't compile when you ran the make command.
Until you learn more you could invoke "make" using "targets". Like: make clean and make complex. It might help bring clarity.
A lot of makefiles put an "all" target to sort of reset the build. That then depends on "clean" and the executable and library targets. Like:
all: clean complex
So then you "make all" to clean and build.
A good tutorial is here. Mrbook Makefile Tutorial

C Makefile compilation error - "linker input file unused because linking not done"

I'm having a problem with a C Makefile.
This is the code for the Makefile in bash:
CC=gcc
CFLAGS=-g -Wall
CCLINK=$(CC)
OBJS=flight.o runway.o airport.o main.o
RM=rm -f
# Creating the executable (airport)
airport: $(OBJS)
$(CCLINK) -o airport $(OBJS)
# Creating object files using default rules
main.o: main.c airport.h ex2.h flight.h runway.h
airport.o: airport.c airport.h ex2.h flight.h runway.h
runway.o: runway.c runway.h ex2.h flight.h
flight.o: flight.c flight.h ex2.h
# Cleaning old files before new make
clean:
$(RM) airport *.o *.bak *~ "#"* core
When I make the file, it says that:
make: `airport` is up to date.
After that - I can call "airport" in bash and it lets me enter some inputs the way I want it to be.
BUT- when I'm trying to check if "airport" is compiled by:
gcc -g -Wall -c airport
I get an error says that:
gcc: airport: linker input file unused because linking not done
Does someone know what could be the problem?
Thanks!
Gavriel.
The aim of Makefile is to avoid recompiling a file if its source is unchanged; when it happens, make says that the file is up to date.
This might be annoying if you want to check again the warnings. Then, simply call make to recompile everything, by typing
make clean ; make
Another goal of Makefile is to avoid typing the gcc commands by yourself, prone to errors. For instance, at the end of your question, you ask to make an object file from an executable (option -c), which is wrong. The good way to make an object file is to call make :
make airport.o
Finally, to produce the executable, you can either type
make airport
or, since airport: is the first target, type
make

make rules with existing target, existing prerequisites but no recipe

I was looking at the net-snmp code and I found something odd in the Makefile of the snmplib itself. The last couple of thousands of lines are nothing but rules in this form:
./dir_utils.lo: ../include/net-snmp/output_api.h
for EVERY library object and header file. Even those that are not compiled, depending on which flags are selected in the configure script.
I looked at the "make" manual but I didn't find this exact case. It may be (as stated in 5.9) that they do this to exclude the possibility that an implicit recipe is called on the target, but other than that I have no idea.
Another reason might be to "break" the compilation if the library is tampered with (deleting whatever header in the project causes in fact the makefile to crash because it can't execute the rule).
This is an educated guess but I would like to know the theory behind this. I mean the makefile already builds whatever it has to build, why include all these rules in explicit form?
Thanks
As I expect you know, the Makefile is generated by the ./configure script.
All the lines that interest you are auto-generated dependencies. Actually,
they are just the appended contents of the file Makefile.depend in the same
directory, which is part of the distribution and was generated with the aid
of gcc ahead of time.
So e.g.
./dir_utils.lo: ../include/net-snmp/output_api.h
just informs make of the vitally important fact that ./dir_utils.lo
depends on ../include/net-snmp/output_api.h. Then if ./dir_utils.lo
is older than ../include/net-snmp/output_api.h, make will re-make
./dir_utils.lo provided it has some recipe to do that, which it has.
Here is a project:
main.c
#include "hw.h"
#include <stdio.h>
int main(void)
{
puts(HW);
return 0;
}
hw.h
#ifndef HW_H
#define HW_H
#define HW "Hello World"
#endif
Makefile
CC := gcc
.PHONY: all clean
all: hw
hw: main.o
$(CC) -o $# $<
clean:
rm -f hw main.o
Build and run it:
$ make && ./hw
gcc -c -o main.o main.c
gcc -o hw main.o
Hello World
But there's a bug in the makefile. It doesn't know that main.o
depends on hw.h:
$ touch hw.h
$ make
make: Nothing to be done for 'all'.
Append that dependency to the makefile:
main.o: hw.h
and retry:
$ make
gcc -c -o main.o main.c
gcc -o hw main.o
Bug fixed.

How to create makefile for program using curses.h

I am struggling with making a makefile for the sample code below using curses.h.
#include <stdio.h>
#include <stdlib.h>
#include<curses.h>
int main(){
WINDOW *initscr(void);
initscr();
int endwin(void);
return 0;
}
I included library and header in Netbeans, but when I try to build with makefile:
CC=C:\TDM-GCC-64\bin\gcc
CFLAGS=-std=gnu99 -Werror -Wall -lm -lncurses
DEPS=curses.h
OUTPUT=main
all:
echo "Building all"
$(CC) $(CFLAGS) render.c -o $(OUTPUT)
it gives me :
echo "Building all"
Building all
C:\TDM-GCC-64\bin\gcc -std=gnu99 -Werror -Wall -lm -lncurses render.c -o main
render.c:3:19: fatal error: curses.h: No such file or directory
#include<curses.h>
^
compilation terminated.
make.exe": *** [all] Error 1
BUILD FAILED (exit value 2, total time: 150ms)
Just add -I. -L. to your CFLAGS macro, this adds the project library to the search paths of both the preprocessor and linket. This should work provided you have curses header and library files in your project folder. If the header or library files are in different folders just modify -I or -L flags accordingly.
Your last comment suggested that the preprocessing and compilation went fine but the linker could not locate the library file.
As a general note, it would be a good idea to put compiler flags to CFLAGS and linker flags to a different macro, say LDFLAGS.
Macro DEPS should also be used to enable incremental compilation. It is usually used as a dependency to the compilation rule but since you don't have it separately you could put it besides all such as this:
all : $(DEPS)
Here is what I did, it works, but it still returns 8 errors.
Solution to fix 1 of the 8 errors is listed further down.
I cd to the location of thadgavin.c
( for me it is "pset1/source")
For ubuntu (I used 16.04)
$ cc thadgavin.c -lm -lncurses
$ ./a.out
You can rename a.out to thadgavin (same as "make" would have done if it would have worked).
$ mv a.out thadgavin
There you go, hope this helps resolve the last of the errors.
Note:
There is an easy error fix in main(), you need to specify it as an int first. I believe it is on line 61?
Eg;
"int main()" shows only as "main()" due to "int" being up at the top with the abstracted layout syntax I do not believe it knows it has been called as an int. I may be wrong, hopefully someone else can shed light to this problem.
https://youtu.be/oOUgU0z4qeY
If you solve any of the rest of the errors, please post to my video or email Python253#gmail.com for others to benefit from your solution.
Thank you,
My name is Daniel Paul Evans
.... And this is CS50!

Resources