Primitive makefile failure for compiling - linux

I am trying to learn makefile, but I fail badly.
One example (which is very primitive) but I should understand it to go ahead is this one
f90_simple: f1.o
gfortran f1.o
mv a.out f90_simple
f90_simple.o: f1.f90
gfortran -c f1.f90
it does not work, and I get this error
I get this error
make: *** No rule to make target `f1.o', needed by `f90_simple'. Stop.
could you please advise me?
thanks

Your first rule says that before f90_simple can be built, the target f1.o must be built.
But there's no rule in your makefile that tells make how to build the target f1.o, and make can't find any built-in rule that can build it (based on the source files make has available), so it prints that error.
You do have a rule that tells make how to build a target f90_simple.o... but that's not the target make is looking for. Most likely you want your makefile to either be:
f90_simple: f1.o
gfortran $^
mv a.out $#
f1.o: f1.f90
gfortran -o $# -c $<
or else:
f90_simple: f90_simple.o
gfortran $^
mv a.out $#
f90_simple.o: f1.f90
gfortran -o $# -c $<
but you can't mix and match them, or make doesn't know what to do.
I think you would really benefit from reading at least the introductory chapters in The GNU Make Manual.

Related

Understand the basic concept of a Makefile

I have the following makefile which I am trying to upgrade, but there is a certain element which I am not able to understand what means:
$(OBJDIR)/%.o: %.f Makefile
#$(F90) $(FFLAGS) $(POPTIONS) -o $# $<
%.o: %.f Makefile
#make $(OBJDIR)/$#
I understand that $(OBJDIR)/%.o: is obtained by executing the f90 compiler with flags etc.
But why do I need the %.o rule, and what does #make mean. Am I missing a general understanding of how a Makefile work?
#make means invoke make but do not echo that in the output (# symbol). The correct way is #${MAKE} because make may not refer to the make being executed, whereas ${MAKE} does.
In makefiles rules must create the target file they promise to (unless the targed is marked as .PHONY). Here, that %.o rule promises to build that %.o, but what it does in fact is it builds $(OBJDIR)/%.o. This is a broken rule.

*** No rule to make target, Makefile error in Win10

First of all, please, don't just tell me this is a duplicate. I know, but the many questions I've looked through have all been given far too specific answers to assist me, and quite frankly half of it went over my head. I'm very new to using Makefiles and I'm baffled by why mine isn't working.
I'm sure it's something painfully simple but please lend a hand, if you need any more information I'll be happy to try to find it, and bear with me because I'm doing all this from my phone because my university's IT department is run by apes. Currently, this is my Makefile:
Makefile for Assignment 1
finish : main.o
g++ -o finish main.o
main.o :
g++ -c -g -Wall main.cpp
clean :
del main.o
(Sorry, it's not being cooperative, I want to make clear that there is the necessary tab in front of the commands)
I'm running this on Windows 10, using a GNU compiler. From what I can see it looks exactly the same as the example Makefile we were provided, aside from filenames. I know I'm in the right directory, nothing is misspelled, the source file should exist cause I'm staring at it sitting next to the makefile. Those are the generic fixes I remember seeing.
The main.o command works perfectly and compiles the source file, but the other two just give me the error
make: *** No rule to make target 'finish/clean'. Stop.
I'm confused, annoyed, new to Makefiles and Stack Overflow and just looking for a helping hand. Any advice would be greatly appreciated.
I am pasting my example:
CC = g++
CFLAGS = -g
test.o: test.cpp
$(CC) $(CFLAGS) -c test.cpp
last.o: last.cpp
$(CC) $(CFLAGS) -c last.cpp
program: test.o last.o
$(CC) $(CFLAGS) -o program test.o last.o
clean:
$(RM) test.o last.o
I was facing similar issue, Try using $(RM) instead of "del"

The effect of the following Makefile lines is?

Can somebody explain the effect of the following MACRO command please?
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
When make is called with the target that equals what is contained in the variable $(EXECUTABLE) (only you can say what that might be), then execute the c compiler with the defined linker flags and compile the objects into the outfile which is named like the target.
So a call to make myprog would result in the c compiler creating the executable myprog.

makefile with multiple dependencies for a single file

I have a makefile similar to the following:
SRCS = a.c b.cpp
OBJS = objs/a.o objs/b.o
all: $(OBJS)
objs/%.o: %.c
gcc -c $< -o $#
objs/%.o: %.cpp
gcc -c $< -o $#
It seems to work. But I don't really understand why.
Why doesn't it try to generate a.cpp and b.c?
as I read it : a.cpp is a prerequisite for objs/a.o and it should try to generate it. And because it doesn't find a matching rule for it - it should fail
Where am I wrong?
P.S - I execute my makefile using -r -R to avoid builtin rules
Make does not combine the prerequisite lists of different pattern rules.
When Make is looking for a way to build objs/a.o, it finds that the first pattern rule matches the target, and the prerequisite (a.c) exists. The second pattern rule matches the target, but the prerequisite (a.cpp) does not exist and cannot be built, so Make uses the first rule. Likewise, Make chooses the second rule over the first when looking for a way to build objs/b.o.
Make would try to generate a.cpp and b.c if these files depended on something else. However it is not the case here, these two files are leaves in the dependency tree, so Make has no reason to try to generate them.

makefile under freebsd does not compile (works on linux)

I got the below makefile which works perfectly fine under linux as well as mac os. However it fails to do anything on FreeBSD, and I have no clue why. It gives the following output:
19:31:35 user#host:~/libhttp++/src> make
-
Making HTTP++ library..
make[1]: don't know how to make obj/libhttp++.a. Stop
make[1]: stopped in /usr/home/user/libhttp++/src/obj
*** Error code 2
Stop.
make: stopped in /usr/home/user/libhttp++/src
I also tried gmake, which gives the following output:
19:31:35 user#host:~/libhttp++/src> gmake
-
Making HTTP++ library..
Building Lib ...
ar -rs obj/libhttp++.a obj/html.o obj/http.o obj/object.o
ar: warning: creating obj/libhttp++.a
ar: warning: can't open file: obj/html.o: No such file or directory
ar: warning: can't open file: obj/http.o: No such file or directory
ar: warning: can't open file: obj/object.o: No such file or directory
ar: fatal: Failed to open 'obj/libhttp++.a'
*** Error code 70
Stop.
make[1]: stopped in /usr/home/user/libhttp++/src
gmake: *** [all] Error 1
One issue might be that i'm trying to keep all intermediate object files as well as the lib itself in a separate subdirectory ("obj").
The problem is, I dont know much about makefiles, and the freebsd handbook as well as any example makefiles i could find via google did not help much. The makefile is basically copied from a working linux makefile I found somewhere, and well, it works on linux and mac os. Is there a way to convert it to a format which works on all 3 platforms? any help would be much appreciated.
makefile:
#--------------------------------------------------------------------------
# defines
#--------------------------------------------------------------------------
LIBDIR = ../lib
INCDIR = ../include
OBJDIR = obj
CXX = g++
doLib = ar -rs
doCompile = $(CXX) $(CXXFLAGS)
doLink = $(CXX) $(LFLAGS)
doClean = rm -f *.o *~ *.a
#--------------------------------------------------------------------------
# Library
#--------------------------------------------------------------------------
OBJECTS = $(OBJDIR)/html.o \
$(OBJDIR)/http.o \
$(OBJDIR)/object.o
LIBXMLPATH=~/Development/libxml2_2
LIBCURLPATH=~/Development/libcurl
#CDEF += -D__FORIOS__
CXXFLAGS ?= -I ./ -I $(LIBXMLPATH)/include -I $(LIBCURLPATH)/include/curl $(CDEF) -c -ggdb -Wreturn-type -Wformat -pedantic -Wunused-variable -Wunused-label -Wunused-value -Wno-long-long
DISTLIB = http++
#--------------------------------------------------------------------------
# compile lib objects
#--------------------------------------------------------------------------
lib: all
all:
#(echo -; echo Making HTTP++ library..; make $(OBJDIR)/lib$(DISTLIB).a)
$(OBJDIR)/lib$(DISTLIB).a: $(OBJECTS)
#echo Building Lib ...
$(doLib) $# $(OBJECTS)
clean:
#(echo Cleanup HTTP++ library)
$(doClean)
(cd $(OBJDIR); $(doClean))
install:
#(echo Installing HTTP++ library in ../include ../lib)
(mkdir -p $(LIBDIR); mkdir -p $(INCDIR))
(cp -p *hpp *h $(INCDIR)/ ; cp -p $(OBJDIR)/lib$(DISTLIB).a $(LIBDIR)/)
#--------------------------------------------------------------------------
# Compiler Call
#--------------------------------------------------------------------------
$(OBJDIR)/%.o: %.cc
#echo Compile "$(*F)" ...
$(doCompile) $(*F).cc -o $#
#--------------------------------------------------------------------------
# dependencies
#--------------------------------------------------------------------------
CHECK = def.h
$(OBJDIR)/html.o : html.cc $(CHECK) html.hpp
$(OBJDIR)/http.o : http.cc $(CHECK) http.hpp
$(OBJDIR)/object.o : object.cc $(CHECK) object.hp
GNU make has a number of extensions beyond the make on BSDs (which is sometimes available on non-BSD boxes as bsdmake). You can look at the FreeBSD man page for make to see the differences, but the most salient one is that the syntax
%.target: %.source
is only available on GNU make (there's a similar syntax, though less flexible, in BSD make).
I'd have thought that gmake would work, though. Hmm...
Looking at the makefile, I can't see anything that creates $(OBJDIR), so it might be that that's the problem – it's the first thing I'd try to fix, at any rate. If so, then just mkdir obj beforehand might work.
Yesterday I found the problem:
all:
#(echo -; echo Making HTTP++ library..; make $(OBJDIR)/lib$(DISTLIB).a)
This line is bad when the makefile is used with gmake, because it calls make instead of gmake. So the fix is:
all:
#(echo -; echo Making HTTP++ library..; gmake $(OBJDIR)/lib$(DISTLIB).a)
Now it works perfectly without any adjustments when using gmake.

Resources