Reputation: 43
So I made a program that contains the files header.h, main.c, printd.c and printd.h. I've been trying to create a Makefile to compile it all together but I'm having trouble understanding it.
header.h
#ifndef SPOVAJA1_HEADER_H
#define SPOVAJA1_HEADER_H
typedef struct {
int size;
char* tag[3][3];
char* text[3][128];
} header;
#endif //SPOVAJA1_HEADER_H
printd.h
#ifndef SPOVAJA1_PRINTD_H
#define SPOVAJA1_PRINTD_H
#include "header.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void printd(header* format, int i, char* niz);
#endif //SPOVAJA1_PRINTD_H
printd.c
//
// Created by Admin on 9. 03. 2021.
//
#include "printd.h"
void printd(header* format, int i, char* niz){
char *messageOutput;
messageOutput = (char *) malloc(sizeof(niz) + 2*sizeof(char*) +sizeof(format->text[i][0]));
strcpy(messageOutput, format->text[i][0]);
strcat(messageOutput, niz);
printf("%s", messageOutput);
free(messageOutput);
}
main.c
#include "header.h"
#include "printd.h"
header format = {
.size = 3,
.tag[0] = "INF",
.tag[1] = "DBG",
.tag[2] = "ERR",
.text[0] = "INFO: ",
.text[1] = "DEBUG: ",
.text[2] = "ERROR: "
};
int main() {
printd(&format, 2, "oops, error");
return 0;
}
I used CLion to generate the function and header files on windows. Now I wanted to make my own Makefile to run it on Linux and I can't seem to get it right.
Makefile
CC=gcc
CFLAGS=-m32
all: main printd
demo_printd: main.c printd.c
gcc -o main main.c printd.c -I
clean:
rm demo_printd
Upvotes: 0
Views: 60
Reputation: 12708
If you want your makefile
to make the minimum number of compilations then you need to first think what are your dependencies.
demo_printd
, which should depend on the object files (just linked only) main.o
and printd.o
(in case one of these files is modified, you should recreate the program by linkingcc -o demo_printd main.o printd.o
Main.o
depends on main.c
, header.h
and printd.h
(if any of these files gets modified, you need to compile main) with:cc -c main.c
printd.c
depends on printd.h
only. So in case you change printd.h
or printd.c
then printd.c
needs to be recompiled.cc -c printd.c
#include <header.h>
in printd.h
that makes that everything that depends on printd.h
will also need recompiling if header.h
is modified, so anything that depends on printd.h
will also depend on header.h
.So we have already all the data necessary to build our rule set. The rules will be:
demo_printd: main.o printd.o
. To handle this rule, we execute the linker.main.o: main.c header.h printd.h
. To handle this rule, we recompile main.c
.printd.o: printd.c printd.h header.h
(remember that everything that depends on printd.h
also depends on header.h
). This means recompiling printd.c
.So our minimum Makefile
should be:
demo_printd: main.o printd.o
cc -o demo_printd main.o printd.o
main.o: main.c header.h printd.h
cc -c main.c
printd.o: printd.c printd.h header.h
cc -c printd.c
Now, you'll see that the include files are dependencies in all the compilations, so as their names are repeated, we can store the list of includes in a makefile variable... this also happens with the object files list, so we can rearrange this into (we will introduce some very useful variables here):
demo_printd_objs = main.o printd.o
headers = printd.h header.h
demo_printd: $(demo_printd_objs)
$(CC) $(LDFLAGS) -o demo_printd $(demo_printd_objs)
main.o: main.c $(headers)
$(CC) $(CFLAGS) -c main.c
printd.o: printd.c $(headers)
$(CC) $(CFLAGS) -c printd.c
And this is only the beginning. For a full text on using make
I recommend you to continue reading on make, with some very good online references (one is the GNU MAKE textinfo documentation, that you can also get straight from your linux system, or the book on BSD's pmake
, which you can get from the FreeBSD.Org site
Upvotes: 0
Reputation: 101041
You want to understand that makefile so tather than just rewrite your makefile for you, I'll try to help you understand it. Let's look at it:
CC=gcc
CFLAGS=-m32
Here you're setting two variables CC
and CFLAGS
. Why? What is the goal of setting these variables?
all: main printd
Here you're telling make that there's a target all
and it depends on two targets main
and printd
. Why? What do you expect this to do?
demo_printd: main.c printd.c
Here you are saying that a target demo_printd
depends on two files main.c
and printd.c
, which is fine. However:
gcc -o main main.c printd.c -I
What does this compile line do? What output file does it generate? If you type that into your shell prompt (which is basically what make is going to do, except in an automated way) what happens?
Upvotes: 2