Makefile in C to get an executable - c

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

Related

I've created a Makefile in c that should creates more than one executable, but it does not work

WHAT I NEED TO DO
I'm trying to create a Makefile in c that should create three executable from three different .c files.
I'll want to create Lez4Es1, Lez4Es1v2 and Lez4Es3 as my executable compiling and linking in two different stages.
Something as:
gcc -std=c99 -Wall -pedantic Lez4Es1.c -c
gcc -std=c99 -Wall -pedantic Lez4Es1.o -o Lez4Es1
gcc -std=c99 -Wall -pedantic Lez4Es1v2.c -c
gcc -std=c99 -Wall -pedantic Lez4Es1.v2 -o Lez4Es1v2
gcc -std=c99 -Wall -pedantic Lez4Es3.c -c
gcc -std=c99 -Wall -pedantic Lez4Es3.o -o Lez4Es3
MY SOLUTION
Assuming to have all .c files in the same directory i created this Makefile but it does not work:
CC = gcc
CFLAGS += -std=c99 -Wall -pedantic -g
TARGETS = Lez4Es1 \
Lez4Es1v2 \
Lez4Es3 \
.PHONY: all clean cleanall
% : %.o
$(CC) $(CFLAGS) $^ -o $#
%.o : %.c
$(CC) $(CFLAGS) -c $^
all : $(TARGETS)
clean :
-rm *.o *~ core
cleanall :
-rm *.o *.txt -f $(TARGETS) *~ core
PROBLEMS
When i run $ make it creates executable from .c file and not from .o, this is output of compiler:
$ make
gcc -std=c99 -Wall -pedantic -g Lez4Es1.c -o Lez4Es1
gcc -std=c99 -Wall -pedantic -g Lez4Es1v2.c -o Lez4Es1v2
gcc -std=c99 -Wall -pedantic -g Lez4Es3.c -o Lez4Es3
How to fix to let him do the things i want to do?
There is a method to give executable files a different name than .o files?
Sorry for my bad english and if i didn't explain it well i'm ready to edit it and give you more details, thank you.
Try deleting the built-in rule that creates executables from source files:
% : %.c
(a pattern rule with no recipe cancels that rule).

Makefile fails with warning message

This is a makefile that fails to link the .o files to make an executeable.
enter code here
CC = c99
CFLAGS = -g -Wall -Wextra -O0
OBJECTS = main.o getoptions.o
P = testprog
$(P): $(OBJECTS)
$(CC) $(OBJECTS) -o $(P)
main.o : main.c
$(CC) $(CFLAGS) $(OBJECTS) -c main.c
getoptions.o : getoptions.c getoptions.h
$(CC) $(CFLAGS) -c getoptions.o
I get this warning:
gcc: warning: getoptions.o: linker input file unused because linking not done
When I manually use:
c99 *.o -o testprog
linking succeeds.
Two issues here:
First, in your target for getoptions.o, you're passing getoptions.o for the -c option. You should be giving it the value of the source file getoptions.c
Second, get rid of $(OBJECTS) in the target for main.o. You don't need to pass in the object files for this step.
With those fixes you'll get a successful compilation:
c99 -g -Wall -Wextra -O0 -c main.c
c99 -g -Wall -Wextra -O0 -c getoptions.c
c99 main.o getoptions.o -o testprog
Edit:
The target line for main.o should be:
main.o : main.c getoptions.h
That way, if getoptions.h changes, main.o gets rebuilt.

makefile compiling multiples targets

This is my first post in this forum. Sorry for bothering but I've been looking for something similar and strangely I couldn't find it. Here's the issue.
I have three (main) files with no headers and I want to compile them either at once (if I simply type "make") or one by one (if I specify the name of the file with no extension). So I built my makefile but something is wrong in the command
$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c
where I got this error
make: *** No rule to make target....
here's the complete file
.SUFFIXES: .c
ROOT = $(addprefix $(PWD), /)
BUILDS_DIR = $(addprefix $(ROOT), builds/)
SRCS_DIR = $(addprefix $(ROOT), src/)
SRCS = $(wildcard $(SRCS_DIR)*.c)
TARGETS = ${SRCS:$(SRCS_DIR)%.c=%}
EXES = ${addprefix $(BUILDS_DIR), $(TARGETS)}
CC = gcc
CFLAGS = -Wall -O3
RM = rm -f
.PHONY: all $(TARGETS) clean
all: $(TARGETS)
$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c
$(CC) $(CFLAGS) \
$< \
-o $#
#echo -e "\n\n\t\t*** Compile successfully! ***\n" ;
clean:
$(RM) $(EXES) \
$(SRCS_DIR)*~
#echo -e "\n\n\t\t*** Cleanup complete! ***\n"
Where am I wrong? I guess the answer is very silly and probably based on a basic error.
thanks in advance
Assuming GNU Make (since you use its syntax).
The, or the first, problem is that you are trying to rewrite the target static pattern incorrectly, by trying to concatenate the target directory to the pattern, rather than simply using the target's filename.
You had:
$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c
$(CC) $(CFLAGS) $< -o $#
The solution is to use add the directory path on the command line
$(TARGETS): % : $(SRCS_DIR)%.c
$(CC) $(CFLAGS) $< -o $(BUILDS_DIR)$#
Lets assume that your three source files are file1.c, file2.c and file3.c. I would created the makefile to look like this (assuming GNU make)
CC = gcc
CFLAGS = -ansi -Wall -pedantic
RM = rm -f
OBJS = file1.o file2.o file3.o
PROG=my_program
$(PROG) : $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(PROG)
all : clean $(PROG)
file1 : file1.c
$(CC) $(CFLAGS) -c file1.c -o file1.o
file2 : file2.c
$(CC) $(CFLAGS) -c file2.c -o file2.o
file3 : file3.c
$(CC) $(CFLAGS) -c file3.c -o file3.o
clean :
$(RM) *.o $(PROG) *.*~
A sample using this make file is (I use the -n to show what rules would be run, but not actually run them because my source files are empty files for testing.)
[******#broadsword junk]$ make -n
gcc -ansi -Wall -pedantic -c -o file1.o file1.c
gcc -ansi -Wall -pedantic -c -o file2.o file2.c
gcc -ansi -Wall -pedantic -c -o file3.o file3.c
gcc -ansi -Wall -pedantic file1.o file2.o file3.o -o my_program
[******#broadsword junk]$ make -n file1
gcc -ansi -Wall -pedantic -c file1.c -o file1.o
We can shorten the above make file my making use of wild-cards;
CC = gcc
CFLAGS = -ansi -Wall -pedantic
RM = rm -f
OBJS = file1.o file2.o file3.o
PROG=my_program
$(PROG) : $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(PROG)
all : clean $(PROG)
% : %.c
$(CC) $(CFLAGS) -c $< -o $#.o
clean :
$(RM) *.o $(PROG) .~
We need to append a '.o' to the output file name so that we are creating files in the format defined by the $(OBJ) variable of the first build rule works correctly. Doing this gives the following example runs:
[******#broadsword junk]$ make -n
gcc -ansi -Wall -pedantic -c -o file1.o file1.c
gcc -ansi -Wall -pedantic -c -o file2.o file2.c
gcc -ansi -Wall -pedantic -c -o file3.o file3.c
gcc -ansi -Wall -pedantic file1.o file2.o file3.o -o my_program
[******#broadsword junk]$ make -n file2
gcc -ansi -Wall -pedantic -c file2.c -o file2.o
BTW, I personally don't mind typing an extra two characters and I like having my target match the output of the set of rules that get run, so I would write the rules as either
file1.o : file1.c
$(CC) $(CFLAGS) -c file1.c -o file1.o
or
%.o :%.c
$(CC) $(CFLAGS) -c $< -o $#
Finally I strongly suspect that when we execute make or make all, we are not running the file-specific rules in the lower part of the makefile, rather we are running the the built in rule described in the GNU manual as: "n.o is made automatically from n.c with a recipe of the form $(CC) $(CPPFLAGS) $(CFLAGS) -c".

GCC default parameters (-Werror -Wall..)

currently I'm using this command to compile my .c files in Mint
gcc -std=gnu99 -Wall -Werror filename.c -o filename [-lm]
How do I make these parameters default, perhaps include them in the make filename.c command? Thanks :)
You need to write makefile like
CC = gcc
EXEC = filename
OBJS = filename.o \
FLAGS = -std=gnu99 -Wall -Werror
LDLIBS = -lm
all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) $(FLAGS) -o $# $(OBJS) $(LDLIBS)
clean:
-rm -f $(EXEC) *.o
Then run make to compile your file

Makefile does not make all targets

I am trying to have the compiled obj files in two different folder
dobjects: where the objects have the debug symbol (gcc with -g option)
sobjects: where the objects are compiled without the debug symbols.
Source files are the same,
I have the following makefile.
CC = gcc
CFLAGS = -Wall
OBJS = a.o b.o
SRCS = a.c b.c
SOBJS_DIR = sobjects
DOBJS_DIR = dobjects
SOBJS = $(addprefix $(SOBJS_DIR)/, $(OBJS))
DOBJS = $(addprefix $(DOBJS_DIR)/, $(OBJS))
all: release debug
release: $(SOBJS)
debug: $(DOBJS)
$(DOBJS_DIR)/%.o: CFLAGS += -g
$(DOBJS_DIR)/%.o $(SOBJS_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm dobjects/*
rm sobjects/*
But every time I try "make" only one target is made.
$ make
gcc -Wall -c a.c -o sobjects/a.o
gcc -Wall -c b.c -o sobjects/b.o
$ make
gcc -Wall -g -c a.c -o dobjects/a.o
gcc -Wall -g -c b.c -o dobjects/b.o
any help would be greatly appreciated
This rule does not do what you think it does:
$(DOBJS_DIR)/%.o $(SOBJS_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
Pattern rules with multiple targets tell make that one single invocation of the recipe will build BOTH targets. So when make runs that rule to build $(DOBJS_DIR)/a.o, make believes that $(SOBJS_DIR)/a.o was also built, so it doesn't try to run the rule to build it. But your rule doesn't actually build it, so when you run make a second time it sees that object file is missing and runs the above rule again, to build the missing one.
You have to write this as two different rules:
$(DOBJS_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
$(SOBJS_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#

Resources