MakeFile creation - c

I want to make a makefile but I am so confused and I need it immediately.
I have four files(.c) an one file(.h). Three of them have main and the fourth hasn't.
main.c has main
readers.c has main
writers.c has main
funs.c has NOT main
The 3 of the files ( that have main ) need the functions in funs.c .
This is my makefile till now:
all: read write main
funs.o:funs.c
gcc -o funs funs.c
read:funs.o
gcc -o read readers.c funs.c
write:funs.o writers.c
gcc -o write writers.c funs.c
main:funs.o main.c
gcc -o main main.c funs.c -lpthread
Can you help? Thanks in advance!

You need to compile funs.o with
gcc -c -o funs funs.c
The -c option makes gcc not try to link the file as a program with main.

There are two steps:
Create a static library for linking
Create each binaries
For example:
all: a b c
STATIC_LIBS=s.o
s.o: share.c
gcc -c -o $# $<
a: a.c $(STATIC_LIBS)
gcc $(STATIC_LIBS) -o $# $<
b: b.c $(STATIC_LIBS)
gcc $(STATIC_LIBS) -o $# $<
c: c.c $(STATIC_LIBS)
gcc $(STATIC_LIBS) -o $# $<
$# is the target
$< is the first dependent object

Well thanks all for your help. This is the answer:
all:read write main
funs.o:funs.c
gcc -c -o funs funs.c
read:readers.c funs.o
gcc -o read readers.c funs.c
write:writers.c funs.o
gcc -o write writers.c funs.c
main:main.c funs.o
gcc -o main main.c funs.c -lpthread

Related

Make two c programs in one makefile

Is it possible to make two files in a single makefile? Essentially a program and a programtest. I have seen other answers, but their syntax went completely over my head. Right now my Makefile only makes one of the programs, and I cant figure out how to have it make both
Would it be possible for someone to provide a template for how a Makefile would be structured to compile two programs?
all: main test
test: objects/Math.o objects/Stack.o objects/Queue.o objects/myUnitTesting.o objects/test.o
gcc objects/test.o objects/Math.o objects/Stack.o objects/Queue.o objects/myUnitTesting -o test
main: objects/Stack.o objects/Queue.o objects/Math.o objects/Point.o objects/main.o
gcc objects/main.o objects/Stack.o objects/Queue.o objects/Point.o objects/Math.o -o main
objects/test.o: test.c
gcc -g -Wall -O -c -o objects/test.o test.c
objects/main.o: main.c
gcc -g -Wall -O -c -o objects/main.o main.c
objects/myUnitTesting.o: cs/myUnitTesting.c
gcc -g -Wall -O -c -o objects/myUnitTesting cs/myUnitTesting.c
objects/Math.o: cs/Math.c
gcc -g -Wall -O -c -o objects/Math.o cs/Math.c
objects/Stack.o: cs/Stack.c
gcc -g -Wall -O -c -o objects/Stack.o cs/Stack.c
objects/Queue.o: cs/Queue.c
gcc -g -Wall -O -c -o objects/Queue.o cs/Queue.c
objects/Point.o: cs/Point.c
gcc -g -Wall -O -c -o objects/Point.o cs/Point.c
clean:
rm -f objects/*o main
Then you only need to type:
make all
and it is going to compile your main.c and test.c files
You can multiple exes in one makefile, here is sample for building 2,
you need to do make all to build
prog1: prog1.o
gcc prog1.o -o prog1 2>>compile.log 1>&2
prog2: prog2.o
gcc prog2.o -o prog2 2>>compile.log 1>&2
all: prog1 prog2
.c.o:
gcc -o $# -c $*.c 2>>compile.log 1>&2
Here is a scenario where 2 targets are main1 and main2.
TARGET1 = main1
TARGET2 = main2
$(TARGET1): main1.o
gcc main1.o -o $#
$(TARGET2): main2.o
gcc main2.o -o $#
%.o: %.c
gcc -c $< -o $#
run1: $(TARGET1)
./$(TARGET1)
run2: $(TARGET2)
./$(TARGET2)
all: $(TARGET1) $(TARGET2)
./$(TARGET1)
./$(TARGET2)
Remember that the indentation is a <tab> character, not space characters.
The following command will compile and run main1 executable.
make run1
The following command will compile and run main2 executable.
make run2
The following command will compile and run main1 executable followed by main2 executable.
make all
It is possible.
Here is a simpler version of the Makefile:
all: program programtest
program:
gcc -o program program.c
programtest:
gcc -o programtest programtest.c
Then you just have to type make:
$ make
gcc -o program program.c
gcc -o programtest programtest.c

Creating several projects from one code in one makefile

I have one program and it uses static or shared library. Now I want to do something like
make static
or
make shared
to compile the project in two cases.
My Makefile looks like
shared: main.o libresult.so
gcc -o shared main.o -L. -lresult -Wl,-rpath,.
main.o: main.c
gcc -c main.c
libresult.so: func.o
gcc -shared -o libresult.so func.o
func.o: func.c
gcc -c -fPIC func.c
static: main.o libresult.a
gcc -o static main.o -L. -lresult
main.o: main.c
gcc -c main.c
libresult.a: func.o
ar cr libresult.a func.o
func.o: func.c
gcc -c func.c
clean:
rm -f *.o *.a *.so static shared
Off course, terminal gives some warnings. It works well, but I dont think that
is much beautiful :). How to make it better?
1) You have two copies of the main.o rule:
main.o: main.c
gcc -c main.c
Delete one of them.
2) You have two versions of the func.o rule:
func.o: func.c
gcc -c -fPIC func.c
func.o: func.c
gcc -c func.c
This is a more serious problem. The object you put in the shared library (libresult.so) must be compiled with -fPIC; the object you put in the static library (libresult.a) may be compiled with -fPIC, but there is no reason to do so and it may prevent the compiler form performing some optimisation. Make doesn't know your intentions, so it is better to make two versions of the object with different names:
func_so.o: func.c
gcc -c -fPIC func.c -o func_so.o
func_a.o: func.c
gcc -c func.c -o func_a.o
(Don't forget to modify the rules that rely on these objects.)
3) Use automatic variables to reduce redundancy and make your makefile cleaner. For example:
main.o: main.c
gcc -c $< -o $#
Further improvements are possible, once you are comfortable with these.

Makefile: make run command

Here is my my makefile. I know there is a shorter way to write it out, but I have a question on how to run it. My hw says I have to use the command: make run --- this command should cause the executable file to run using file redirection to read the input file data.
How would I go about setting that up?
Also i know the gcc is supposed to be tabbed.
test: main.o sum.o stack.o bSearch.o database.o db.o set.o parse.o bubble.o
gcc -o object main.o sum.o stack.o bSearch.o db.o set.o parse.o bubble.o
main.o: main.c sum.h
gcc -c main.c
sum.o: sum.c sum.h
gcc -c sum.c
stack.o: stack.c stack.h
gcc -c stack.c
bSearch.o: bSearch.c defs.h sortAndsearch.h
gcc -c bSearch.c
database.o: database.c defs.h parse.h
gcc -c database.c
db.o: db.c defs.h
gcc -c db.c
set.o: set.c set.h db.h
gcc -c set.c
parse.o: parse.c parse.h
gcc -c parse.c
bubble.o: bubble.c defs.h
gcc -c bubble.c
sortAndsearch.h: db.h
defs.h: set.h sortAndsearch.h
stack.h: set.h
clean:
rm *.o object
"run" is just like any other target in your Makefile such as "test" or "set.o" - but you have to add the rule to the Makefile for make to know what to do with it.
run:
./test < input.txt

Makefile in C to get an executable

How can I get a makefile of my C program that will build/compile my program and generates an
executable.This executive should be able to run my c program???
Save the makefile as makefile or Makefile:
.PHONY: all
all : progname
progname: all-objects
.PHONY to mark the target all as not a file-target
all is the first and thus default-target, depends on progname (Just so make all works)
progname depends on all the object-files, and will thus link them together.
The object-files are built using builtin rules.
If you want to override the default-action of a rule, write your own recipe.
Each command-line must be indented one tab (do not use spaces).
Reference of GNU make: http://www.gnu.org/software/make/manual/make.html
Reference of builtin rules: https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
Create a file called Makefile on the same path with this content:
CC = gcc
CFLAGS = -std=c99 -pedantic -Wall
OBJECTS = filename.o
all: appname
filename.o: filename.c
$(CC) $(CFLAGS) -c filename.c
appname: $(OBJECTS)
$(CC) $(OBJECTS) -o appname
Note: There must be a "tab" (not spaces) before
$(CC) $(CFLAGS) -c filename.c
and
$(CC) $(OBJECTS) -o appname
Then run:
make
EDIT: An example:
david#debian:~$ cat demo.c
#include <stdio.h>
int main(void)
{
return 0;
}
david#debian:~$ cat Makefile
CC = gcc
CFLAGS = -std=c99 -pedantic -Wall
OBJECTS = demo.o
all: demo
demo.o: demo.c
$(CC) $(CFLAGS) -c demo.c
demo: $(OBJECTS)
$(CC) $(OBJECTS) -o demo
david#debian:~$ make
gcc -std=c99 -pedantic -Wall -c demo.c
gcc demo.o -o demo

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.

Resources