Object files to different executables - makefile

I have objects files like:
task1.o task2.o task3.o task4.o tasks.o comm.o
I need to link every of task*.o with two of tasks.o comm.o.
manually it looks like:
gcc -Wall -o task1 task1.o tasks.o comm.o
gcc -Wall -o task2 task2.o tasks.o comm.o
So in result i will have 4 executables, task1.exe etc. but when i try to do this with makefile like:
TASKS= task1 task2 task3 task4
TASK_OBJECTS= task1.o task2.o task3.o task4.o
OBJS_SOURCES= tasks.c comm.c
OBJS= tasks.o comm.o
CC=gcc
CFLAGS= -Wall -c -o
all: $(TASKS)
$(TASKS): $(TASK_OBJECTS) $(OBJS)
$(CC) -o $# $(TASK_OBJECTS) $(OBJS)
$(TASK_OBJECTS): %.o: %.c
$(CC) $(CFLAGS) $# $<
$(OBJS): %.o: %.c
$(CC) $(CFLAGS) $# $<
clean:
rm -rf *.o task1 task2 task3 task4
I get:
gcc -Wall -c -o task1.o task1.c
gcc -Wall -c -o task2.o task2.c
gcc -Wall -c -o task3.o task3.c
gcc -Wall -c -o task4.o task4.c
gcc -Wall -c -o tasks.o tasks.c
gcc -Wall -c -o comm.o comm.c
gcc -o task1 task1.o task2.o task3.o task4.o tasks.o comm.o
instead of
gcc -Wall -c -o task1.o task1.c
gcc -Wall -c -o task2.o task2.c
gcc -Wall -c -o task3.o task3.c
gcc -Wall -c -o task4.o task4.c
gcc -Wall -c -o tasks.o tasks.c
gcc -Wall -c -o comm.o comm.c
gcc -o task1 task1.o tasks.o comm.o
gcc -o task2 task2.o tasks.o comm.o
gcc -o task3 task3.o tasks.o comm.o
gcc -o task4 task4.o tasks.o comm.o
What am i doing wrong?

Here:
$(TASKS): $(TASK_OBJECTS) $(OBJS)
$(CC) -o $# $(TASK_OBJECTS) $(OBJS)
You're constructing each executable from all objects. Instead, you should use a static pattern rule (like the one you already use for $(TASK_OBJECTS)):
$(TASKS): % : %.o $(OBJS)
$(CC) -o $# $^
(Note that $^ is the automatic variable for "all prerequisites".)

Related

Why does ```CFLAGS:=$(CFLAGS) -O3``` not work as expected?

Makefile like this:
CFLAGS := $(CFLAGS) -O3
test: main.o
gcc $(CFLAGS) -o $# $^
clean:
rm test *.o -f
compile 1: command: make, output: gcc -O3 -o test main.c
compile 2: command: make CFLAGS="-Wall -Werror", output: gcc -Wall -Werror -o test main.c
question: why not output: gcc -Wall -Werror -O3 -o test main.c ?
use override directive:
override CFLAGS := $(CFLAGS) -O3
or
override CFLAGS += -O3

How to execute multiple programs in Makefile

Here is part of my Makefile:
FLAGS = -Wall -Werror -std=c99
DEPENDENCIES = p.h
test: s d
#./s < input.dat > output.txt
#./d < output.txt
s: s.o helper.o
gcc -Wall -o $# $^
d: d.o helper.o
gcc -Wall -o $# $^
%.o: %.c ${DEPENDENCIES}
gcc -Wall -c $<
Why is error 1 showing up whenever I call "make test". Is this the proper way of compiling two programs and then executing it through Makefile?
The output:
cc -c -o s.o s.c
cc -c -o helper.o helper.c
gcc -Wall -Werror -std=c99 -o s s.o helper.o
cc -c -o d.o d.c
gcc -Wall -Werror -std=c99 -o d d.o helper.o
make: *** [test] Error 1

Whats worng with the make file format

I wrote a makefile for my mini-project with gedit.
when I run "make", all *.o and executable created.
once I change one of my file (without make clean or make -B)
it's show it compile the chaneged file again and link all object again.
But the executable file works like nothing change.
(after "make -B" the executable file run ok)
CC = g++
CFLAGS = -Wall
OBJS = pawn.o knight.o bishop.o rook.o queen.o king.o board.o
movement.o game.o
all: ex1
ex1: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o ex1
pawn.o: chess/tools/pawn.cpp chess/tools/tool.hpp
$(CC) $(CFLAGS) -c chess/tools/pawn.cpp
knight.o: chess/tools/knight.cpp chess/tools/tool.hpp
$(CC) $(CFLAGS) -c chess/tools/knight.cpp
bishop.o: chess/tools/bishop.cpp chess/tools/tool.hpp
$(CC) $(CFLAGS) -c chess/tools/bishop.cpp
rook.o: chess/tools/rook.cpp chess/tools/tool.hpp
$(CC) $(CFLAGS) -c chess/tools/rook.cpp
queen.o: chess/tools/queen.cpp chess/tools/tool.hpp
$(CC) $(CFLAGS) -c chess/tools/queen.cpp
king.o: chess/tools/king.cpp chess/tools/tool.hpp
$(CC) $(CFLAGS) -c chess/tools/king.cpp
board.o: chess/board.cpp chess/board.hpp
$(CC) $(CFLAGS) -c chess/board.cpp
movement.o: chess/movement.cpp
$(CC) $(CFLAGS) -c chess/movement.cpp
game.o: chess/game.cpp
$(CC) $(CFLAGS) -c chess/game.cpp
clean:
rm *.o
If there is another problem or suggestion with the design of the make file, I will be glad to hear about it.
Edit
1)The program is not print nothing to the screen.
2)The change is in king.cpp file (located in another folder) print Print Change to screen
[av#ArchlinuxAvichai chess]$ ls
chess ex1 Makefile
[av#ArchlinuxAvichai chess]$ ls chess
board.cpp board.hpp game.cpp movement.cpp tools
[av#ArchlinuxAvichai chess]$ ls chess/tools
bishop.cpp king.cpp knight.cpp pawn.cpp queen.cpp rook.cpp tool.hpp
[av#ArchlinuxAvichai chess]$ make
g++ -Wall -c chess/tools/pawn.cpp
g++ -Wall -c chess/tools/knight.cpp
g++ -Wall -c chess/tools/bishop.cpp
g++ -Wall -c chess/tools/rook.cpp
g++ -Wall -c chess/tools/queen.cpp
g++ -Wall -c chess/tools/king.cpp
g++ -Wall -c chess/board.cpp
g++ -Wall -c chess/movement.cpp
g++ -Wall -c chess/game.cpp
g++ -Wall pawn.o knight.o bishop.o rook.o queen.o king.o board.o movement.o game.o -o ex1
[av#ArchlinuxAvichai chess]$ ./ex1
[av#ArchlinuxAvichai chess]$ *** AT this stage i change the file
[av#ArchlinuxAvichai chess]$
[av#ArchlinuxAvichai chess]$ make
g++ -Wall -c chess/tools/king.cpp
g++ -Wall pawn.o knight.o bishop.o rook.o queen.o king.o board.o movement.o game.o -o ex1
[av#ArchlinuxAvichai chess]$ ./ex1
[av#ArchlinuxAvichai chess]$
[av#ArchlinuxAvichai chess]$ make -B
g++ -Wall -c chess/tools/pawn.cpp
g++ -Wall -c chess/tools/knight.cpp
g++ -Wall -c chess/tools/bishop.cpp
g++ -Wall -c chess/tools/rook.cpp
g++ -Wall -c chess/tools/queen.cpp
g++ -Wall -c chess/tools/king.cpp
g++ -Wall -c chess/board.cpp
g++ -Wall -c chess/movement.cpp
g++ -Wall -c chess/game.cpp
g++ -Wall pawn.o knight.o bishop.o rook.o queen.o king.o board.o movement.o game.o -o ex1
[av#ArchlinuxAvichai chess]$ ./ex1
Print Change
[av#ArchlinuxAvichai chess]$
Try the following makefile:
CXX := g++
CXXFLAGS := -Wall
OBJS := pawn.o knight.o bishop.o rook.o queen.o king.o board.o movement.o game.o
COMPILE_CMD = ${CXX} -c -o $# ${CXXFLAGS} -MD -MP $<
LINK_CMD = ${CXX} -o $# ${LDFLAGS} $^
all: ex1
ex1: ${OBJS}
${LINK_CMD}
%.o : chess/tools/%.cpp
${COMPILE_CMD}
%.o : chess/%.cpp
${COMPILE_CMD}
-include $(OBJS:%.o=%.d)
clean:
rm -f *.o *.d
.PHONY: clean all
Changes:
Use ${CXX} for C++ code.
Auto-generate header dependencies.
Use pattern rules to avoid repetition.
Specify .o output files.
Mark targets clean and all as .PHONY.
Use LDFLAGS for linking.

generic makefile to create multiple executable using different flags

I would like to create a generic Makefile that builds several executables using different compiler flags for each executable without using shell commands. The executable file name should be composed from the source file and a unique post fixed name. It should also produce an assembly or preprocessor file per source file if needed.
For the target BIN_BDG_FILES, the "$<" (exercise-1.1.0.c ) is always the first item from the list (exercise-1.1.0.c exercise-1.1.1.c exercise-1.2.0.c exercise-1.2.1.c) as expected. I tried without success to modify the SRC_FILES using the filter-out function. My intent was to remove the first item from the list for each Target, so that the first item corresponds to the correct target. I am not sure this is the correct approach. Your comments are welcome.
i.e.
This is my attempt at using built in make constructs.
$(BIN_DBG_FILES): $(SRC_FILES)
$(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#
echo SRC_FILES := $(filter-out $<, $(SRC_FILES))
Makefile
SHELL = bash
SRC_FILES = $(wildcard *.c)
BIN_FILES = $(patsubst %.c,%,$(SRC_FILES))
BIN_DBG_FILES = $(patsubst %.c,%-dbg,$(SRC_FILES))
SRC_PRE = $(patsubst %.c,%-pre,$(SRC_FILES))
CC = gcc
WARNINGS := -Wall
CFLAGS = -O2 -std=c99 $(WARNINGS)
DBG_CFLAGS = -g -O -std=c99 $(WARNINGS)
PRE_FLAG = -E
IFLAGS = -I.
all: $(BIN_FILES) $(BIN_DBG_FILES) MK-BASH
$(BIN_DBG_FILES): $(SRC_FILES)
$(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#
MK-BASH::
for src in $(SRC_FILES); do \
echo $(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(PRE_FLAG) $$src > $${src%.c}-pre; \
done
clean:
rm -f $(BIN_FILES) *-dbg *-pre
This is the output from executing make command.
This is the output from the target BIN_FILES.
gcc -O2 -std=c99 -Wall exercise-1.1.0.c -o exercise-1.1.0
gcc -O2 -std=c99 -Wall exercise-1.1.1.c -o exercise-1.1.1
gcc -O2 -std=c99 -Wall exercise-1.2.0.c -o exercise-1.2.0
gcc -O2 -std=c99 -Wall exercise-1.2.1.c -o exercise-1.2.1
This is the output from target BIN_DBG_FILES which uses the first source file on the list to build all targets. It should use the appropriate file (exercise-1.1.1.c) to build each target file (exercise-1.1.1-dbg).
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.1.0-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.1.1-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.2.0-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.2.1-dbg
This is the output from the target MK-BASH using shell commands.
for src in exercise-1.1.0.c exercise-1.1.1.c exercise-1.2.0.c exercise-1.2.1.c; do \
echo gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -E $src > ${src%.c}-pre; \
done
output:
gcc -g -O -std=c99 -Wall -I. exercise-1.1.0.c -o exercise-1.1.0-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.1.1.c -o exercise-1.1.1-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.2.0.c -o exercise-1.2.0-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.2.1.c -o exercise-1.2.1-dbg
Use a pattern rule:
DBG: $(BIN_DBG_FILES)
%-dbg: %.c
#echo $(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#

make is ignoring some depedencies

Here is my Makefile:
CC=gcc
CFLAGS=-Wall -std=gnu99
OBJ1=mknlrescs.o collisionsys.o csheader.o utils.o labels.o csdata.o
OBJ2=mknrescs.o utils.o
all: mknlrescs mknrescs
mknlrescs: $(OBJ1)
$(CC) $(CFLAGS) -o $# $<
mknrescs: $(OBJ2)
$(CC) $(CFLAGS) -o $# $<
%.o: %.c %.h
$(CC) $(CFLAGS) -c $<
When I type make mknlrescs I get the following:
$ make mknlrescs
gcc -Wall -std=gnu99 -c -o mknlrescs.o mknlrescs.c
gcc -Wall -std=gnu99 -c collisionsys.c
gcc -Wall -std=gnu99 -c csheader.c
gcc -Wall -std=gnu99 -c utils.c
gcc -Wall -std=gnu99 -c labels.c
gcc -Wall -std=gnu99 -c csdata.c
gcc -Wall -std=gnu99 -o mknlrescs mknlrescs.o -lm
mknlrescs.o: In function `main':
mknlrescs.c:(.text+0x4b): undefined reference to...
And a bunch of other "undefined reference to..." errors.
The rest of the objects are not being linked. Notice it only linked the first object file. How can I correct this?
The automatic variable $< stands for the first prerequisite of the rule that defined the recipe.
If you want to use ALL the prerequisites, use $^ instead.
See Automatic Variables for a full list.

Resources