I am going through an eg pgm to create a make file.
http://mrbook.org/tutorials/make/
My folder eg_make_creation contains the following files,
desktop:~/eg_make_creation$ ls
factorial.c functions.h hello hello.c main.c Makefile
Makefile
all:gcc -c main.c hello.c factorial.c -o hello
error:
desktop:~/eg_make_creation$ make all
make: *** No rule to make target `gcc', needed by `all'. Stop.
Please help me understand to compile this program.
The syntax of makefiles is very strict:
target:dependencies
build_rules
# ^ this space here _needs_ to be a tab.
What you wrote makes all depend on gcc, -c, ... which are not valid targets.
What you need is something like:
all: hello
hello: factorial.c functions.h hello.c main.c
gcc -o hello factorial.c hello.c main.c
(If you want to compile and link in one step, don't use the -c switch).
Mat nailed it.
In my particular case, I'm using vi and have the expandtab enabled by default!!
To see if this issue applies to you, open vi and do:
:set list
If you don't see a ^I where a tab should be, then you most likely have the et enabled.
To disabled it just:
:set expandtab!
Maybe it helps somebody else as well.
Another reason is because you have the wrong name in the list of source files. (nameWrong.o instead of nameRight.o) That was my issue.
After all: everything is target, shows dependency anything written after that should present that directory,as in your code gcc(as a file is not present) like wise -c too
all:gcc -c main.c hello.c factorial.c -o hello correct one is
all:main.c hello.c factorial.c -o hello
please Read more about it GNU MAKE
Related
I've used makefile to generate file.
gcc -c hello.c -o hello
and fixed the permission problem through:
chmod a+x ./hello
However, when I want to execute "hello" file.
./hello
the system told me that "cannot execute binary file"
Can someone help me? I am looking forward your reply badly.
The -c argument to gcc produces an object file which you later on must link in order to produce an executable. You can not execute the object file you produced.
Instead, to compile and link at the same time, suitable when you only have 1 .c file, do
gcc hello.c -o hello
Or if you want to break it down to separate compilation and linking steps, do
gcc -c hello.c -o hello.o
gcc hello.o -o hello
Check whether the GCC compiler is installed in your system correctly or not.
gcc -v
Compile your file:
gcc filename.cpp -o any-name
Running your program:
./any-name
As an alternative to compiling and linking at the same time you can use make:
make hello
Note: without the .c extension.
The terminal output should be:
cc hello.c -o hello
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
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.
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!
I am just starting out with C and now I am at the part where I want to learn about Makefiles. I am starting out small but already failing ;)
I have a very simple Makefile which just compiles the main.c to a main.o and then to an executable. But I get an error saying I have a syntax error. I use g++.
The command that i use are:
g++ make Makefile << name of the make file
And the Makefile is set up like this:
main.o: main.c main.h
[TAB] g++ -c main.c
main: main.o
[TAB] g++ main.o -o main
To run make on the Makefile (the default name), invoke the make command:
$ make
Don't try to call g++ with the makefile, the compiler knows nothing about makefiles.
EDIT: You say you don't have the make command, in a comment. Then you need to get it. :) There are several versions of make for Windows, here is GNU make (which is common in Linux and other Unix-like environments) ported to Windows.