Whats worng with the make file format - makefile

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.

Related

How to get prerequisites with respect to the target in Makefile (GNU Make)?

Is there a way to get the prerequisite corresponding to a target in the Makefile (GNU Make)?
For instance, consider the following Makefile:
CXX = g++
CFLAGS = -Wall
MODULE_NAME = myRenderer
BUILD_DIR = bin
SOURCE_FILES = renderer/tracer.cpp renderer/lights/DiffuseLight.cpp renderer/materials/ScatterUtils.cpp
OBJECT_FILES = $(patsubst %,$(BUILD_DIR)/%, $(notdir $(SOURCE_FILES:.cpp=.o)))
$(BUILD_DIR)/$(MODULE_NAME): $(OBJECT_FILES)
$(CXX) -o $# $^
$(OBJECT_FILES): $(SOURCE_FILES)
#mkdir -p "$(BUILD_DIR)"
$(CXX) $(CFLAGS) -I. -c $< -o $#
when I run make, I can see that the following commands get executed:
g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/DiffuseLight.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/ScatterUtils.o
g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o
And obviously, this fails to build the executable as it's using only the first prerequisite i.e. renderer/tracer.cpp to generate all the object files because I am using the $< automatic variable in the recipe command for the $(OBJECT_FILES) target.
I wish to know how to fix my Makefile to be able to execute these commands:
g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
g++ -Wall -I. -c renderer/lights/DiffuseLight.cpp -o bin/DiffuseLight.o
g++ -Wall -I. -c renderer/materials/ScatterUtils.cpp -o bin/ScatterUtils.o
g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o
I cannot seem to find the right automatic variable or a way to fetch the right source file to build a given object file.
As suggested by Matt you have (at least) two options:
A compilation rule:
# $(1): source file
define MY_RULE
$$(patsubst %.cpp,$$(BUILD_DIR)/%.o,$$(notdir $(1))): $(1)
#mkdir -p "$$(BUILD_DIR)"
$$(CXX) $$(CFLAGS) -I. -c $$< -o $$#
endef
$(foreach f,$(SOURCE_FILES),$(eval $(call MY_RULE,$(f))))
Note the $$ used to escape the first expansion (see The eval Function for a detailed explanation).
The vpath directive:
vpath %.cpp $(dir $(SOURCE_FILES))
$(BUILD_DIR)/%.o: %.cpp
#mkdir -p "$(BUILD_DIR)"
$(CXX) $(CFLAGS) -I. -c $< -o $#

Loop through list of files in Makefile

I compiling my C source files with this code:
CC=clang -std=c11
CFLAGS=-Wall -g
ASSEMBLY=-S -masm=intel
OPTIMIZE=-Ofast
FOLDER_SRC=./src/
FOLDER_BIN=./bin/
FOLDER_ASSEMBLY=./ass/
clean:
rm -f \
$(FOLDER_BIN)1.1-hello $(FOLDER_ASSEMBLY)1.1-hello \
$(FOLDER_BIN)1.2-fahrenheit $(FOLDER_ASSEMBLY)1.2-fahrenheit \
$(FOLDER_BIN)1.2-fahrenheit-floating $(FOLDER_ASSEMBLY)1.2-fahrenheit-floating
all:
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.1-hello.c -o $(FOLDER_BIN)1.1-hello
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit.c -o $(FOLDER_BIN)1.2-fahrenheit
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit-floating.c -o $(FOLDER_BIN)1.2-fahrenheit-floating
assembly:
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.1-hello.c -o $(FOLDER_ASSEMBLY)1.1-hello
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit.c -o $(FOLDER_ASSEMBLY)1.2-fahrenheit
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit-floating.c -o $(FOLDER_ASSEMBLY)1.2-fahrenheit-floating
I try to implement some kind of loop to write less. I added this code, but it just generating errors:
FILENAME_SRC := $(wildcard $(FOLDER_SRC)*.c)
FILENAME_BUILD := $(patsubst $(FOLDER_SRC)%.c,%,$(FILENAME_SRC))
echo : $(FILENAME_SRC)
#echo $^
#echo $(FILENAME_BUILD)
build : $(FILENAME_SRC)
$(CC) $(CFLAGS) $(OPTIMIZE) $^ -o $(FILENAME_BUILD)
make echo printing this to the console:
$ make echo
src/1.2-fahrenheit.c src/1.1-hello.c src/1.2-fahrenheit-floating.c
1.2-fahrenheit 1.1-hello 1.2-fahrenheit-floating
make build command generating this error:
$ make build
clang -std=c11 -Wall -g -Ofast src/1.2-fahrenheit.c src/1.1-hello.c src/1.2-fahrenheit-floating.c -o 1.2-fahrenheit 1.1-hello 1.2-fahrenheit-floating
clang.exe: error: no such file or directory: '1.1-hello'
clang.exe: error: no such file or directory: '1.2-fahrenheit-floating'
make: *** [Makefile:21: build] Error 1
I want the expected output to look like when I do make all:
$ make all
clang -std=c11 -Wall -g -Ofast ./src/1.1-hello.c -o ./bin/1.1-hello
clang -std=c11 -Wall -g -Ofast ./src/1.2-fahrenheit.c -o ./bin/1.2-fahrenheit
clang -std=c11 -Wall -g -Ofast ./src/1.2-fahrenheit-floating.c -o ./bin/1.2-fahrenheit-floating
Final solution
CC := clang -std=c11
GCC := gcc -std=c11
CFLAGS := -Wall -g
ASSEMBLY := -Wall -S -masm=intel
OPTIMIZE := -O3 -march=native
SRC := $(wildcard src/*.c)
BIN := $(patsubst src/%.c,bin/%,$(SRC))
ASS := $(patsubst src/%.c,ass/%,$(SRC))
clean:
rm -f bin/* ass/*
build: $(BIN)
$(BIN): bin/%: src/%.c
$(CC) $(CFLAGS) $(OPTIMIZE) $^ -o $#
assembly: $(ASS)
$(ASS): ass/%: src/%.c
$(CC) $(ASSEMBLY) $(OPTIMIZE) $^ -o $#
Really sorry for the clean ass/* though, it cannot be called assembly because the similar folder name in the project.
Your all rule needs to look something like
CC := clang
CFLAGS := -std=c11 -Wall -g -Ofast
targets := bin/1.1-hello bin/1.2-fahrenheit bin/1.2-fahrenheit-floating
.PHONY: all
all: $(targets)
$(targets): bin/%: src/%.c
$(LINK.c) $^ $(LDLIBS) -o $#

Make file not working?

Solution found. See below:
I'm trying to get my makefile to compile three c programs into one executable, but I get the following error:
cachesim.o: could not read symbols: File in wrong format
Yes, I'm using make clean every time I use it. The make file is as follow
CC = gcc
CFLAGS = -Wall -m32 -O -g
all: cachesim cache trace_file_parser
gcc -o cachesim cachesim.o cache.o trace_file_parser.o
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
cache: cache.c
$(CC) -c -o cache.o cache.c $(CFLAGS)
trace_file_parser: trace_file_parser.c
$(CC) -c -o trace_file_parser.o trace_file_parser.c $(CFLAGS)
clean:
rm -f *.o
I cannot figure out why this is....
I'm using make clean every time.
Attempting to compile:
[katiea#mumble-15] (34)$ make clean
rm -f *.o
[katiea#mumble-15] (35)$ ls
cache.c cache.h cachesim.c~ gcc_trace Makefile~ trace_file_parser.c
cache.c~ cachesim.c cache_structs.h Makefile strgen_trace trace_file_parser.h
[katiea#mumble-15] (36)$ make
gcc -c -o cachesim.o cachesim.c -Wall -m32 -O -g
gcc -c -o cache.o cache.c -Wall -m32 -O -g
gcc -c -o trace_file_parser.o trace_file_parser.c -Wall -m32 -O -g
gcc -o cachesim cachesim.o cache.o trace_file_parser.o
cachesim.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
make: *** [all] Error 1
SOLUTION
CC = gcc
CFLAGS = -Wall -m32 -O -g
all: cachesim.c cache.c trace_file_parser.c
$(CC) -o cachesim cachesim.c cache.c trace_file_parser.c $(CFLAGS)
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
cache: cache.c
$(CC) -c -o cache.o cache.c $(CFLAGS)
trace_file_parser: trace_file_parser.c
$(CC) -c -o trace_file_parser.o trace_file_parser.c $(CFLAGS)
clean:
rm -f *.o
Please read an intro to makefiles. This looks like homework to me.
One of the most basic tenets of makefiles is that the target should be the actual file you're building. These rules are all bogus:
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
(etc.) because the target is cachesim but the recipe (command line) builds the file cachesim.o.
Your makefile can be written as easily as this (taking advantage of make's built-in rules):
CC = gcc
CFLAGS = -Wall -m32 -O -g
LDFLAGS = -m32 -O -g
cachesim: cachesim.o cache.o trace_file_parser.o
clean:
rm -f *.o
That's all you need.
As for your error, it seems to me that the file cachesim.o must be in some bizarre format, maybe from back before you had the makefile set up properly.
If you run make clean then make again, do you get the same error? If so please show the compile and link lines.
ETA: use the -m32 flag on the link line as well as the compile line, if you want to create a 32bit program.

Makefile sometimes ignores variable in recipe

I have the following Makefile
CXX = g++
CXXFLAGS = -g -Wall
COMPILE = ${CXX} ${CXXFLAGS} -c
LINK = ${CXX} -lpthread
LIB_INC = -Ilib -Iwrappers -Iprocesses
src := $(wildcard lib/*.cpp) $(wildcard wrappers/*.cpp)
obj = $(src:.cpp=.o)
src_1 := processnetwork_part001.cpp sc_application_1.cpp
obj_1 = $(src_1:.cpp=.o)
src_2 := processnetwork_part002.cpp sc_application_2.cpp
obj_2 = $(src_2:.cpp=.o)
all : sc_application_1 sc_application_2
.PHONY : all
sc_application_1 : ${obj} ${obj_1}
${LINK} -o sc_application_1 $(obj) ${obj_1}
sc_application_2 : ${obj} ${obj_2}
${LINK} -o sc_application_2 $(obj) ${obj_2}
%.o : %.cpp %.h
${COMPILE} -o $# $< $(LIB_INC)
clean :
rm sc_application_1 sc_application_2 ${obj} ${obj_1} ${obj_2}
Where lib, wrappers and processes are subdirectories of the directory where the Makefile and the two main applications sc_application_1 and sc_application_2 are stored. When I run make, I get the following output (only the last few lines w/o compiler warnings).
g++ -g -Wall -c -o lib/Scheduler.o lib/Scheduler.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o wrappers/consumer_wrapper.o wrappers/consumer_wrapper.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o wrappers/generator_wrapper.o wrappers/generator_wrapper.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o wrappers/square_wrapper.o wrappers/square_wrapper.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o processnetwork_part001.o processnetwork_part001.cpp -Ilib -Iwrappers -Iprocesses
g++ -g -Wall -c -o sc_application_1.o sc_application_1.cpp
In file included from wrappers/wrappers.h:4:0,
from sc_application_1.cpp:10:
wrappers/generator_wrapper.h:4:28: fatal error: ProcessWrapper.h: No such file or directory
compilation terminated.
make: *** [sc_application_1.o] Error 1
Compilation fails because for some reason that I don't understand, the variable LIB_INC isn't added anymore to
g++ -g -Wall -c -o sc_application_1.o sc_application_1.cpp
But it is (as I intended) on all previous lines. Can anyone explain me this behaviour? Thank you.
edit: The error doesn't occur when I ommit the "%.h" in the "%.o" target.
I'm going to go out on a limb, and guess that there is no sc_application_1.h, but there is a header file for every previous source (e.g. Scheduler.h, consumer_wrapper.h ...).
Your %.o: %.cpp %.h rule doesn't apply if there is no %.h, so Make falls back on its default rule, which does not use LIB_INC. The simplest way to fix this is to add another %.o rule:
%.o : %.cpp %.h
${COMPILE} -o $# $< $(LIB_INC)
%.o : %.cpp
${COMPILE} -o $# $< $(LIB_INC)

Compiling error

I downloaded someone's source code for a program and i needed to make some changes.
Now i want to compile it but it doesn't seem to work.
PROGS = isotociso
COMMON = tools.o bn.o ec.o wiidisc.o rijndael.o
DEFINES = -DLARGE_FILES -D_FILE_OFFSET_BITS=64
LIBS = C:/Dev-Cpp/lib/libwsock32.a C:/Dev-Cpp/lib/libcrypto.a C:/Dev-Cpp/lib/libcomdlg32.a
CC = gcc
#CFLAGS = -Wall -W -Os -Ilibwbfs -I.
CFLAGS = -Wall -m32 -W -ggdb -Ilibwbfs -I.
LDFLAGS = -m32 -static
VPATH+=libwbfs
OBJS = $(patsubst %,%.o,$(PROGS)) $(COMMON)
all: $(PROGS)
$(PROGS): %: %.o $(COMMON) Makefile
$(CC) $(CFLAGS) $(LDFLAGS) $< $(COMMON) $(LIBS) -o $#
$(OBJS): %.o: %.c tools.h Makefile
$(CC) $(CFLAGS) $(DEFINES) -c $< -o $#
clean:
-rm -f $(OBJS) $(PROGS)
Output
C:\Users\Panda\Desktop\uloader_v4.1\src\isotociso\src>make
gcc -Wall -m32 -W -ggdb -Ilibwbfs -I. -DLARGE_FILES -D_FILE_OFFSET_BITS=64 -c i
sotociso.c -o isotociso.o
process_begin: CreateProcess((null), gcc -Wall -m32 -W -ggdb -Ilibwbfs -I. -DLAR
GE_FILES -D_FILE_OFFSET_BITS=64 -c isotociso.c -o isotociso.o, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [isotociso.o] Error 2
What would be the problem?
Looks to me as if gcc is not in your PATH.
It also looks like you need MinGW to get the libraries.
I am no expert in C(++) development under Windows, but my interpretation would be that it can't find the compiler itself. What development environment are you using?
It looks like it can't find a file. Are you sure you have all the required source files?

Resources