Trying to add a 'clean' target to a Makefile - makefile

CC = g++
CFLAGS = -g -Wall -O0 -std=c++11
graph: graph.o
${CC} -o graph ${CFLAGS} graph.cpp
How do i go about putting clean in here to get rid of the .o files?

You would be looking at:
clean:
rm -f *.o
this will remove all files ending with a .o extension, calling would be
make clean
also simply googling this will give you tons of answers

Related

Can't use LAPACK in makefile

I have program (in fortran) where I'm using three custom modules, which make use of LAPACK. Until now I've compiled my program using the following shell script:
filestring="main"
gfortran -c mod_exp.f90 mod_genmat.f90 mod_print.f90 $filestring.f90
gfortran mod_exp.o mod_genmat.o mod_print.o $filestring.o -llapack -lblas
rm mod_exp.o mod_genmat.o mod_print.o $filestring.o exponentiate.mod genmat.mod printing.mod printing_subrtns.mod
mv a.out $filestring
Since I've been using more and more modules and different programs using them, I've decided to start using makefiles. Following a tutorial, I managed to write the following:
FC = gfortran
FFLAGS = -Wall -Wextra -llapack -lblas #-fopenmp
SOURCES = mod_print.f90 mod_genmat.f90 mod_exp.f90 main.f90
OBJ = ${SOURCES:.f90=.o} #substitute .f90 with .o
%.o : %.f90 #creation of all *.o files DEPENDS on *.f90
$(FC) $(FFLAGS) -c -O $< -o $#
main: $(OBJ)
$(FC) $(FFLAGS) -o $# $(OBJ)
clean:
#rm -f *.o *.mod main
However, when executing make, it says that the LAPACK functions are not recognized. One such mistake is the following:
/usr/bin/ld: mod_exp.o: in function `__exponentiate_MOD_diagun':
mod_exp.f90:(.text+0x37f): undefined reference to `zgees_'
...
collect2: error: ld returned 1 exit status
One possible mistake I've seen is that I need to specify the location of the libraries. However, it would seem strange since I didn't need to do it before; also, I don't know how to find it.
Please show the link command that make invoked, that caused the error to be generated.
I'm confident that if you cut and paste that exact command line to your shell prompt, you will get the same error you see when make runs it. So the problem is not make, but your link command.
The problem is that you have put the libraries before the objects in the link line. Libraries should come at the end, after the objects, else when the linker examines the libraries it doesn't know what symbols will need to be included (because no objects have been parsed yet to see what symbols are missing).
This is why LDLIBS is traditionally a separate variable:
FC = gfortran
FFLAGS = -Wall -Wextra #-fopenmp
LDLIBS = -llapack -lblas
SOURCES = mod_print.f90 mod_genmat.f90 mod_exp.f90 main.f90
OBJ = ${SOURCES:.f90=.o} #substitute .f90 with .o
%.o : %.f90 #creation of all *.o files DEPENDS on *.f90
$(FC) $(FFLAGS) -c -O $< -o $#
main: $(OBJ)
$(FC) $(FFLAGS) -o $# $(OBJ) $(LDLIBS)

Makefile: "No such file or directory" for target file

First, I should admit makefiles are something that I'm very inexperienced at, so I apologize if this is an error that I should have been able to solve myself, but I have spent several hours on this, including reading the various answers on this site, and have been unable to discover a solution.
With that said, I have created the following makefile to compile my code on a Linux machine; it completes the sub compilations just fine, but when it comes to making the output itself, xPlatST, it throws an error.
g++ -std=c+=11 -g -Wall -pthread -c -o xPlatST.o xPlatST.cpp
g++ -std=c+=11 -g -Wall -pthread -c -o stdafx.o stdafx.cpp
g++ -std=c+=11 -g -Wall -pthread -c xPlatST xPlatST.o stdafx.o -L../hwloc
g++ error: xPlatST: No such file or directory
make: *** [xPlatST] Error 1
I believe it seems to think that the xPlatST is one of it's compilation files and thus can't find it, but for the life of me I can't work out why.
hwloc is a third party library, and should be unrelated to this issue. The code compiles just fine when compiled from the command line directly.
My files are xPlatST.cpp, xPlatST.h, stdafx.cpp, stdafh.h
Code is as follows:
CXX = g++ -std=c++11
INCLUDES =
LIBS = -L../hwloc
CXXFLAGS = -Wall -g -pthread
OBJS = xPlatST.o stdafx.o
xPlatST: ${OBJS}
${CXX} ${CXXFLAGS} ${INCLUDES} -c $# ${OBJS} ${LIBS}
clean:
-rm xPlatST *.o
Any help would be greatly appreciated; thank you in advance.
Your assumption is correct. Your recipe is trying to use xPlatST as a source. Change the -c into a -o in your rule:
${CXX} ${CXXFLAGS} ${INCLUDES} -o $# ${OBJS} ${LIBS}
The -c flag tells the compiler to take all files, compile, and assemble them into an object file (.o). The -o flag specifies the destination file.

gmake compile and link source files in different directories

I'm trying to compile and link several files in different folders using gfortran, and GNU Make 3.81 on a windows machine. I learned how to use wildcards from this reference:
gmake compile all files in a directory
And I want to do something similar to this reference:
Makefiles with source files in different directories
But the difference is that I want to build only one executable in my root directory from the source files in several other directories. I tried reading the make manual:
http://www.gnu.org/software/make/manual/make.html
But it seems primarily directed towards c/c++ programming and non-windows syntax.
My current makefile looks like this:
FC = gfortran
MOD_DIR = "bin"
FCFLAGS = -O0 -Og -Wall -pedantic -fbacktrace -fcheck=all
FCFLAGS += -J$(MOD_DIR) -fopenmp -fimplicit-none -Wuninitialized
TARGET = test
SRCS_C = $(wildcard *.f90) $(TARGET).f90
OBJS_C = $(patsubst %.f90,%.o,$(SRCS_C))
all: $(TARGET)
$(TARGET): $(OBJS_C)
$(FC) -o $# $(FCFLAGS) $(OBJS_C)
$(OBJS_C): $(SRCS_C)
$(FC) $(FCFLAGS) -c $(SRCS_C)
clean:
del *.o $(MOD_DIR)\*.mod
Which works fine when all of my source files are in the root directory. And so I thought this would work:
FC = gfortran
MOD_DIR = "bin"
FCFLAGS = -O0 -Og -Wall -pedantic -fbacktrace -fcheck=all
# FCFLAGS += -J$(MOD_DIR) -I$(INCLUDE_DIR) -fopenmp -fimplicit-none -Wuninitialized
FCFLAGS += -J$(MOD_DIR) -fopenmp -fimplicit-none -Wuninitialized
TARGET = test
SRCS_C =\
"solvers/"$(wildcard *.f90) \
"user/"$(wildcard *.f90) \
$(wildcard *.f90) $(TARGET).f90
OBJS_C = $(patsubst %.f90,%.o,$(SRCS_C))
all: $(TARGET)
$(TARGET): $(OBJS_C)
$(FC) -o $# $(FCFLAGS) $(OBJS_C)
$(OBJS_C): $(SRCS_C)
$(FC) $(FCFLAGS) -c $(SRCS_C)
clean:
del *.o $(MOD_DIR)\*.mod
Where I don't mind just entering the names of the folders where a list of source files can be taken from. I've also tried using -I$(INCLUDE_DIR), but this didn't work either. The error from what I have above is:
gmake: *** No rule to make target `"user/"gridFun.f90', needed by `"user/"gridFu
n.o'. Stop.
Any help is greatly appreciated!
To accomplish what you want with SRCS_C, consider using:
SRCS_C =\
$(wildcard solvers/*.f90) \
$(wildcard user/*.f90) \
$(wildcard *.f90) $(TARGET).f90
Also note that (TARGET).f90 will also be matched by $(wildcard *.f90), in your cases causing test.f90 to be included twice in SRCS_C. You can safely omit $(TARGET).f90 in this example.

extra CFLAGs with Makefile

I'm reading through Foundations of GTK+ and in so doing decided to write a simple makefile that would let me run "make " to compile the example program I'd just written. I also stumbled upon a list of compiler directives here that the Gnome team specified will help moving from GTK2 to GTK3, so I wanted to include those.
I'm a make noob for all intents and purposes, so this is what I came up with:
CC = gcc
CFLAGS += -Wall
GTK_DFLAGS = -DGTK_DISABLE_SINGLE_INCLUDES -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGSEAL_ENABLE
GTK_CFLAGS = $(shell pkg-config --cflags gtk+-3.0)
GTK_LDFLAGS = $(shell pkg-config --libs gtk+-3.0)
%.o: %.c
$(CC) $(CFLAGS) $(GTK_DFLAGS) $(GTK_CFLAGS) -c -o $# $<
%: %.o
$(CC) $(CFLAGS) $(GTK_DFLAGS) $(GTK_CFLAGS) $(GTK_LDFLAGS) -o $# $<
.PHONY: clean
clean:
rm -f *.o *~
And as you might guess, it doesn't work quite right. I know running pkg-config from inside the makefile isn't an ideal solution, but this is for my small-scale learning projects and not for deployment of any sort. That said, the output is weird to me; it seems like make just ignores any variables after CFLAGS.
Something like:
[patrick#blackbox ch2]$ make helloworld
gcc -Wall helloworld.c -o helloworld
helloworld.c:1:21: fatal error: gtk/gtk.h: No such file or directory
#include <gtk/gtk.h>
^
compilation terminated.
<builtin>: recipe for target 'helloworld' failed
make: *** [helloworld] Error 1
If I add have the contents of GTK_DFLAGS simply tacked onto the end of CFLAGS, they appear on the command line, but the pkg-config variables are still missing.
It's obvious to me that I messed something simple up, but after an hour of vaguely worded Googling, I'm fresh out of ideas as to what it is.
Found the answer, and of course the vocabulary I was missing when asking this question/doing earlier searches.
CC = gcc
CFLAGS += -Wall -std=c11
GTK_DFLAGS = -DGTK_DISABLE_SINGLE_INCLUDES -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGSEAL_ENABLE
GTK_CFLAGS := $(shell pkg-config --cflags gtk+-3.0)
GTK_LDFLAGS := $(shell pkg-config --libs gtk+-3.0)
%: %.c
$(CC) $(CFLAGS) $(GTK_DFLAGS) $(GTK_CFLAGS) $(GTK_LDFLAGS) -o $* $*.c
.PHONY: clean
clean:
rm -f *~
This does what I want, which is to compile a single .c file of any name into a program of the same name with the GTK flags I was looking to use.
Thanks to those who contributed!
You need a target for helloworld in your Makefile. Something like this:
helloworld: helloworld.o
$(CC) -o helloworld helloworld.o $(LDFLAGS) $(GTK_LDFLAGS)

How to define rules in the Makefile to compile only that *.cpp files which was modified (and their dependencies), not all *.cpp files

Lets say I have files:
Libs:
one.cpp, one.h
two.cpp, two.h
three.cpp, three.h
Program:
program.cpp
Is there way, to create Makefile which will compile only that *.cpp which were modified from last compilation?
Currently I have something like that:
SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)
all: $(OBJS) program
.cpp.o:
g++ -Wall -c $<
program:
g++ -Wall $(OBJS) program.cpp -o program
clean:
rm -f $(OBJS) program
I works fine, but when I compile my program and then change two.cpp or two.h I need to run "make clean" first, because when I secondly run "make" I get:
Nothing to be done for 'all'.
I would like to change my Makefile in that way, it would recognize my changes and recompile that file and its dependencies (if one.cpp uses code from two.cpp which was modified, both files should be recompiled).
So if I modify two.cpp, make should do:
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
But if one.cpp uses code from two.cpp which was modified, make shold do:
g++ -Wall -c one.cpp
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
First we make the object files prerequisites of the executable. Once this is done, Make will rebuild program whenever one of the SRCS changes, so we don't need OBJS as an explicit target:
all: program
program: $(OBJS)
g++ -Wall $(OBJS) program.cpp -o program
Then we make the header files prerequisites of the objects, so that if we change three.h, Make will rebuild three.o:
$(OBJS): %.o : %.h
And finally since one.cpp uses code from two.cpp by means of two.h (I hope), we make two.h a prerequisite of one.o:
one.o: two.h
And to make things cleaner and easier to maintain we use automatic variables:
program: $(OBJS)
g++ -Wall $^ program.cpp -o $#
Put it all together and we get:
SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)
all: program
$(OBJS): %.o : %.h
one.o: two.h
.cpp.o:
g++ -Wall -c $<
program: $(OBJS)
g++ -Wall $^ program.cpp -o $#
clean:
rm -f $(OBJS) program
There are a few more things we could do (like adding program.o to OBJS), but this is enough for today.
Add the files a command depends upon to run to the right of the target name.
Example:
default: hello.c
gcc -o hello.bin hello.c
install: hello.bin
cp hello.bin ../
All you need to do is tell make that the .o file depends on the .cpp file:
%.cpp.o: %.cpp
g++ -Wall -c -o $# $<

Resources