GNU makefiles remaking existing targets - makefile

I have a simple makefile on my machine:
# Compiler: g++ for C++ source files
CC = g++
# Compiler flags:
CFLAGS = -std=c++14 -Wall -Wextra -pedantic -O0 -c
foo.o: foo.cpp
$(CC) $(CFLAGS) $?
bar.o: bar.cpp
$(CC) $(CFLAGS) $?
foobar: foo.o bar.o
$(CC) -o $# $?
When I run make it remakes each target, even if it already exists. I want the makefile to ignore existing targets. What am I doing wrong?

Doing this fixed my problem:
# Compiler: g++ for C++ source files
CC = g++
# Compiler flags:
CFLAGS = -std=c++14 -Wall -Wextra -pedantic -O0 -c
all: foo.o bar.o foobar
foo.o: foo.cpp
$(CC) $(CFLAGS) $<
bar.o: bar.cpp
$(CC) $(CFLAGS) $<
foobar: foo.o bar.o
$(CC) -o $# $^
and also
touch makefile

Related

Generate objects individually from variables

I'm doing a Makefile to make objects with the same gcc command. This file looks like this:
SRCLIB = main.c srv.c
OBJLIB = main.o srv.o
CC = gcc
CCFLAGS = -Wall -Werror
$(OBJLIB) : $(SRCLIB)
$(CC) $(CCFLAGS) -c $^ -o $#
The objetive is to execute this like:
gcc -Wall -c read_line.c -o read_line.o
gcc -Wall -c client.c -o client.o
But I don't know how to do it, and everything I tested is not working. Is it even possible to do this in a Makefile?
Your makefile expands to this, after the variables are expanded:
main.o srv.o : main.c srv.c
$(CC) $(CCFLAGS) -c $^ -o $#
In make, using multiple targets in explicit rules like this is the same as writing the rule multiple times, once for each target. So, this is the same as this:
main.o : main.c srv.c
$(CC) $(CCFLAGS) -c $^ -o $#
srv.o : main.c srv.c
$(CC) $(CCFLAGS) -c $^ -o $#
This means that if either of the source files changes, BOTH object files will be recreated (since each object depends on both sources, not just their own source file).
Further, in your compile line you use the variable $^ which expands to all the prerequisites. So your compile lines will expand to:
gcc -Wall -Werror -c main.c srv.c -o main.o
gcc -Wall -Werror -c main.c srv.c -o srv.o
which is illegal: if you use -c with the -o option you can only compile one source file.
Make has built-in rules that already know how to compile files, so there's no need to write your own. You can just write this:
SRCLIB = main.c srv.c
OBJLIB = main.o srv.o
CC = gcc
CCFLAGS = -Wall -Werror
.PHONY: all
all: $(OBJLIB)
and that's all you need.

Makefile not prompting compiler to use optimization flag

I have a simple makefile that I am using in bash to compile a C++ program and its associated .h files, not every .h file has a .cpp file associated with it. I wrote a makefile where each dependency was called out explicitly and the CFLAG macro was used for each specific dependency and it did compile with the -O3 flag and ran nearly 3 times faster. However, when I use this simpler, but somewhat more sophisticated makefile, it does not compile with the -O3 flag even though it is clearly included with the CFLAG macro. Can someone point out to me what I am missing, I would greatly appreciate it.
OBJS = main.o Output_Files.o Calendar.o Random_Number_Generator.o \
Algorithm.o Statistics.o
DEPS = Output_Files.h Calendar.h Random_Number_Generator.h Algorithm.h \
Statistics.h
CC=c++
CFLAGS=-c -Wall -O3
all: economics
%o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $# $<
economics: $(OBJS)
$(CC) $(OBJS)
main.o: main.cpp Data_Parser.h PDF_and_CDF.h
$(CC) $(CFLAGS) main.cpp
The rule:
%o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $# $<
should be written with an extra dot:
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $<
Also, you don't want $# in the command line, or (if you must have it) you need to prefix it with -o.
The makefile is not using the faulty rule but instead uses the default rule for building C++ object files, and that most probably doesn't use $(CFLAGS) but uses $(CXXFLAGS) instead.
CC is the macro for the C compiler, not the C++ compiler. Normally, that is CXX. Also, the rule to build economics actually creates a.out and not economics.
I'd prefer it if you wrote:
SRCS = main.cpp Output_Files.cpp Calendar.cpp Random_Number_Generator.cpp \
Algorithm.cpp Statistics.cpp
OBJS = ${SRCS:.cpp=.o}
…
economics: $(OBJS)
$(CC) -o $# $(OBJS)
Putting it all together gives this new.makefile:
SRCS = main.cpp Output_Files.cpp Calendar.cpp Random_Number_Generator.cpp \
Algorithm.cpp Statistics.cpp
OBJS = ${SRCS:.cpp=.o}
DEPS = Output_Files.h Calendar.h Random_Number_Generator.h Algorithm.h \
Statistics.h
CC = c++
CFLAGS = -c -Wall -O3
all: economics
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) $<
economics: $(OBJS)
$(CC) -o $# $(OBJS)
main.o: main.cpp Data_Parser.h PDF_and_CDF.h
$(CC) $(CFLAGS) main.cpp
Running make -n with the old makefile
$ make -n -f old.makefile
c++ -c -Wall -O3 main.cpp
c++ -c -o Output_Files.o Output_Files.cpp
c++ -c -o Calendar.o Calendar.cpp
c++ -c -o Random_Number_Generator.o Random_Number_Generator.cpp
c++ -c -o Algorithm.o Algorithm.cpp
c++ -c -o Statistics.o Statistics.cpp
c++ -o economics main.o Output_Files.o Calendar.o Random_Number_Generator.o Algorithm.o Statistics.o
$
Running make -n with the new makefile
$ make -n -f new.makefile
c++ -c -Wall -O3 main.cpp
c++ -c -Wall -O3 Output_Files.cpp
c++ -c -Wall -O3 Calendar.cpp
c++ -c -Wall -O3 Random_Number_Generator.cpp
c++ -c -Wall -O3 Algorithm.cpp
c++ -c -Wall -O3 Statistics.cpp
c++ -o economics main.o Output_Files.o Calendar.o Random_Number_Generator.o Algorithm.o Statistics.o
$
This is still an abnormal way of writing the make rules on a number of grounds, one being the $(CC) vs $(CXX) change. Normally, the -c option is not included in $(CFLAGS) or $(CXXFLAGS). Normally, you include $(CFLAGS) or $(CXXFLAGS) in the link line too (because some of the flags might affect linking). Often, you need libraries and related flags in the linker line too.
This leads to a more orthodox naming convention:
SRCS = main.cpp Output_Files.cpp Calendar.cpp Random_Number_Generator.cpp \
Algorithm.cpp Statistics.cpp
OBJS = ${SRCS:.cpp=.o}
DEPS = Output_Files.h Calendar.h Random_Number_Generator.h Algorithm.h \
Statistics.h
CXX = c++
CXXFLAGS = -Wall -O3
LDFLAGS =
LDLIBS =
all: economics
%.o: %.cpp $(DEPS)
$(CXX) -c $(CXXFLAGS) $<
economics: $(OBJS)
$(CXX) -o $# $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS)
main.o: main.cpp Data_Parser.h PDF_and_CDF.h
$(CXX) -c $(CXXFLAGS) main.cpp

CFLAGS are ignored in Makefile

I am using the following makefile to build my project:
CC = /usr/bin/g++
CFLAGS = -Wall -pedantic -std=c++0x
LDFLAGS =
OBJ = main.o pnmhandler.o pixmap.o color.o
pnm: $(OBJ)
$(CC) $(CFLAGS) -o pnm $(OBJ) $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) -c $<
As I run make I get the following error:
/usr/include/c++/4.9.1/bits/c++0x_warning.h:32:2: error: #error This
file requires compiler and library support for the ISO C++ 2011
standard. This support is currently experimental, and must be enabled
with the -std=c++11 or -std=gnu++11 compiler options.
As I can read from the following line, the CFLAGS are not properly included, but I have no idea what I am doing wrong:
g++ -c -o main.o main.cpp
Also tried -std=c++11 and -std=gnu++11, without any results. Any ideas?
If I run make -Bn, I get:
g++ -c -o main.o main.cpp
g++ -c -o pnmhandler.o pnmhandler.cpp
g++ -c -o pixmap.o pixmap.cpp
g++ -c -o color.o color.cpp
/usr/bin/g++ -Wall -pedantic -std=c++0x -o pnm main.o pnmhandler.o pixmap.o color.o
EDIT: Replacing the rule %.o: %.c with %.o: %.cpp fixes my problem.
The reason you see
g++ -c -o main.o main.cpp
is that Make is invoking its standard rule to create the object file:
%.o: %.cpp
# recipe to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
The command expands to
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $# $<
Instead of setting CC and CFLAGS in your makefile, you should set CXX and CXXFLAGS, which are meant for C++ rather than C. That allows the built-in rule above to work for you, and then you just need to make sure the right linker is used, e.g. with
pnm: LINK.o=$(LINK.cc)
pnm: $(OBJ)
You also don't need the %.o: %.c rule, as you have no C sources.
Complete Makefile:
CXX = /usr/bin/g++
CXXFLAGS = -Wall -pedantic -std=c++0x
OBJ = main.o pnmhandler.o pixmap.o color.o
pnm: LINK.o=$(LINK.cc)
pnm: $(OBJ)
clean::
$(RM) pnm
.PHONY: clean

CPPUTestMakeFile Help linking

I am trying to make a makefile, which can make an exe for CppUTest. It can not find the headers, what have I done wrong? First time making a makefile, not 100% sure what I'm doing.
#The compiler to use
CC = g++
LINK = -g -pedantic -Wall -lstdc++ -lpthread -ldl -lm -Wl,-rpath,.
COMPILE = -g -O3 -D_THREAD_SAFE -pedantic -Wall -c -Wno-deprecated
#Name of the EXE file to create.
EXE = ./Tests
SRCS = $(shell ls *.cpp)
OBJS = $(subst .cpp,.o,$(SRCS))
#Extra flags to give to the C compiler.
CFLAGS =
#Libraries to include
LIBS= -lCppUTestExt -lCppUTest -lm
#Extra flags to give to the C++ compiler.
CXXFLAGS = -I/home/mg/DS-5-Workspace/Tests/include
#Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’,
#such as -L. Libraries (-lfoo) should be added to the LDLIBS variable
#instead.
LDFLAGS = -L/home/mg/DS-5-Workspace/Tests/cpputest/lib
#Extra flags to give to the C preprocessor and programs that use it (the C and
#Fortran compilers).
CPPFLAGS =
.SUFFIXES: .o .cpp
.cpp.o:
$(CC) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(COMPILE) $(LIBS) $<
all: $(OBJS)
$(CC) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(LIBS) $(OBJS) -o $(EXE) $(LINK)
-include depend.mak
depend:
g++ -MM $(SRCS) > depend.mak
#static:
#ar -crvs $(a) $(OBJS)
#shared: $(OBJS)
#$(CC) -shared -Wl,-soname -lc -o $(so) $(OBJS)
clean:
rm -rf $(OBJS) depend.mak $(EXE) $(so) $(a)
I have the following error:
error: CppUTest/CommandLineTestRunner.h: No such file or directory
Well, you're mixing up a lot of things.
Let's clean this up and keep only what is needed :
EXE := Tests
SRC_DIR := .
OBJ_DIR := obj
SRC := $(wildcard $(SRC_DIR)/*.cpp)
OBJ := $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
CPPFLAGS := -I/home/mg/DS-5-Workspace/Tests/include
CPPFLAGS += -MMD -MP -D_THREAD_SAFE
CXXFLAGS := -W -Wall -Wno-deprecated -pedantic -O3 -g
LDFLAGS := -L/home/mg/DS-5-Workspace/Tests/cpputest/lib
LDFLAGS += -Wl,-rpath,.
LDLIBS := -lCppUTestExt -lCppUTest -lm -lstdc++ -lpthread -ldl
.PHONY: all clean fclean re
all: $(EXE)
clean:
$(RM) -f -r $(OBJ_DIR)
fclean: clean
$(RM) -f $(EXE)
re: fclean all
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
# %.a: $(OBJ)
# $(AR) crvs $# $^
# ranlib $#
# %.so: CXXFLAGS += -fPIC
# %.so: $(OBJ)
# $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJ_DIR):
#mkdir -p $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
-include $(OBJ:.o=.d)
Some explanations :
Avoid the $(shell ...) function, because it'll be executed each time the variable is called if assigned with the = operator instead of := operator.
$(CC) is a built-in variable containing cc or gcc (should be equivalent). Use the built-in $(CXX) to use g++.
-g, -pedantic, -O3, -Wno-deprecated and -Wall are compiler flags, they should be in the CFLAGS (for C) or CXXFLAGS (for C++) built-in variables.
-I <path> and -D_THREAD_SAFE are preprocessor flag, thus should be in the CPPFLAGS built-in variable.
-MMD -MP will auto-generate dependency files (.d extension) for each .o file. You can read more here.
.cpp.o: is a suffix rule, and suffix rules are the old-fashioned way of defining implicit rules for make. You should just rely upon these implicit rules make already know about or make your own the modern way.
You don't need to define .SUFFIXES: by yourself for such widely used targets. The variable SUFFIXES is defined to the default list of suffixes before make reads any makefiles. Make 3.82 defines these suffixes by default :
.SUFFIXES: .out .a .ln .o .c .cc .C .cpp .p .f .F .m .r .y .l .ym .yl .s .S .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo .w .ch .web .sh .elc .el
If you have any questions, go on.

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