Issue with Makefile - section executed twice - c++

I may not be a Makefile-guru, but I have some experience with them in the past. However, I've got a (rather unimportant) issue, which still baffles me.
Here's my Makefile :
#-------------------------
# Definitions
#-------------------------
APP = lgm
# Tools & commands
CC = gcc
LEX = lex
YACC = /usr/local/bin/bison
RM = rm
CP = cp
MV = mv
DMD = dmd
# Paths
SRC = src
BIN = bin
TEST = test
LIB = lib
# C stuff
CC_HEADERS = logramm.tab.h
CC_SOURCES = lex.yy.c logramm.tab.c
CC_OBJECTS = lex.yy.o logramm.tab.o
CC_LEXER = logramm.l
CC_PARSER = logramm.y
# D stuff
D_SOURCES = main.d
D_OBJECTS = main.o
D_LFLAGS = -m64
#-------------------------
# Main Functions
#-------------------------
all: ${APP} clean
${APP}: ${CC_OBJECTS} ${D_OBJECTS}
${DMD} ${CC_OBJECTS} ${D_OBJECTS} -of${APP} ${D_FLAGS}
${MV} ${APP} ${BIN}
${D_OBJECTS}:
${DMD} -c ${D_SOURCES}
${CC_OBJECTS}: ${CC_SOURCES}
${CC} -g -c ${CC_SOURCES}
${CC_SOURCES}: setup
${LEX} ${CC_LEXER}
${YACC} -d ${CC_PARSER}
setup:
${CP} ${SRC}/*.d .
${CP} ${SRC}/*.l .
${CP} ${SRC}/*.y .
clean:
${RM} *.d *.y *.l *.o *.hh *.c *.h
The trouble is :
When I'm looking at the output of make all, the ${CC_SOURCES} part is executed twice (2 lex, 2 bison commands). E.g. It outputs :
cp src/*.d .
cp src/*.l .
cp src/*.y .
lex logramm.l
/usr/local/bin/bison -d logramm.y
lex logramm.l
/usr/local/bin/bison -d logramm.y
gcc -g -c lex.yy.c logramm.tab.c
dmd -c main.d
dmd lex.yy.o logramm.tab.o main.o -oflgm
mv lgm bin
rm *.d *.y *.l *.o *.hh *.c *.h
rm: *.hh: No such file or directory
make: *** [clean] Error 1
Why is that? What am I doing wrong?
UPDATE :
I've just managed to fix it, by taking setup from ${CC_SOURCES} and putting it at the all section, like :
all: setup ${APP} clean
So, it's ok. However, I still don't understand why. Have I misinterpreted the way Makefiles are structured? Any input would be more than welcome! :-)

You have a basic misunderstanding of how make interprets rules with multiple targets: this makefile is really not going to work. Let's expand the rule that runs the lex/yacc:
lex.yy.c logramm.tab.c: setup
${LEX} ${CC_LEXER}
${YACC} -d ${CC_PARSER}
Make interprets this as if it were this (in an explicit rule, multiple targets create a separate rule for each target):
lex.yy.c: setup
${LEX} ${CC_LEXER}
${YACC} -d ${CC_PARSER}
logramm.tab.c: setup
${LEX} ${CC_LEXER}
${YACC} -d ${CC_PARSER}
Now you can probably see your issue. Make wants to build lex.yy.o and that depends on lex.yy.c, so make tries to build that. It sees that it depends on setup, which doesn't exist (because nothing creates it, but if someone WERE to create that file in your directory it would break badly). So, it run the lex and yacc steps (both, since that's the recipe) to build lex.yy.c.
Then it goes through exactly the same thing to build logramm.tab.c... thus the rules are run twice.
You have an identical problem with your object files; expanding that rule we see:
lex.yy.o logramm.tab.o: lex.yy.c logramm.tab.c
${CC} -g -c lex.yy.c logramm.tab.c
which is identical to:
lex.yy.o: lex.yy.c logramm.tab.c
${CC} -g -c lex.yy.c logramm.tab.c
logramm.tab.o: lex.yy.c logramm.tab.c
${CC} -g -c lex.yy.c logramm.tab.c
which is clearly not right.
Also, your setup rule (since it never exists) will cause everything to rebuild every time.
Your solution is better WRT setup, since the source files don't depend on it so they won't always be rebuilt. You still have the broken rules for object files. Also your solution will not work if you ever wanted to enable parallel builds, because the setup may be run in parallel with the other targets: you really WANT the dependency to ensure ordering.
In general when writing makefiles you should (a) have one rule to build one target, and (b) ensure the rule builds EXACTLY the target you told make it would build.
Try using this instead:
all: ${BIN}/${APP} clean
${BIN}/${APP}: ${APP}
${CP} $< $#
${APP}: ${CC_OBJECTS} ${D_OBJECTS}
${DMD} $^ -of$# ${D_FLAGS}
%.o : %.d
${DMD} -c $<
%.o: %.c
${CC} -g -c $<
%: ${SRC}/%
${CP} $< $#
lex.yy.c: ${CC_LEXER}
${LEX} $<
%.tab.c %.tab.h: %.y
${YACC} -d $<
clean:
${RM} *.d *.y *.l *.o *.hh *.c *.h

The trouble is that CC_SOURCES = lex.yy.c logramm.tab.c so the target line (plus actions):
${CC_SOURCES}: setup
${LEX} ${CC_LEXER}
${YACC} -d ${CC_PARSER}
is equivalent to:
lex.yy.c: setup
${LEX} ${CC_LEXER}
${YACC} -d ${CC_PARSER}
logramm.tab.c: setup
${LEX} ${CC_LEXER}
${YACC} -d ${CC_PARSER}
The setup rule has no dependencies, but isn't a (GNU make extension) .PHONY target either (and I'm not sure that being a phony target would help, either), so it doesn't exist. Therefore, when make is trying to ensure that lex.yy.c is up to date, it has to execute the rules for setup; ditto for logramm.tab.c; hence the double execution.
Your solution looks reasonable. You could explore .PHONY and see whether that helps if you're using GNU make and don't mind being tied to GNU make.

This comes down to the way make handles dependencies. You can always examine exactly what make is doing by passing the -d flag (at least for GNU Make, ymmv, also consider adding -r if you aren't using any built-in rules as they clutter the output substantially).
Here's what happens in the case where setup is a dependency of ${CC_SOURCES}
...
Does lex.yy.c exist? no, okay check its prerequisites
Does setup exist? no, okay check its prerequisites
No prerequisites, run the recipe
Prerequisites for lex.yy.c done, run the recipe
Does logramm.tab.c exist? yes, but check its prerequisites
We already built setup, so prune this prerequisite, but treat it as newer than logramm.tab.c
Prerequisites for logramm.tab.c done, run the recipe
...
Here's what happens in the case where setup is a dependency of all
...
Does setup exist? no, okay check its prerequisites
No prerequisites, run the recipe
...
Does lex.yy.c exist? no, okay check its prerequisites
No prerequisites, run the recipe
Does logramm.tab.c exist? yes, but check its prerequisites
No prerequisites, so done
...

Related

Using makefile arguments without foo=

I have a makefile I use to compile a single file. When I need to pass an argument, I use target=targetFile.
The script takes the argument, looks for the file (within the same directory) that has the same value as the argument and compiles it.
I use this for compiling problems from uhunt and uva, which use a single c++ file. So I dont' need multiple makefiles for multiple source files. Single makefile for multiple source files is the reason I made the makefile.
Here's the code I have so far
OBJS = $(target).o
CC = g++
CFLAGS = -Wall -g -std=c++11
INCLUDE = -I./$(target)
#default command to run
all : Main-$(target) clean run
#compile and build
Main-$(target) : $(OBJS)
$(CC) $(CFLAGS) $^ -o $#
%.o : %.cpp
$(CC) -c $(CFLAGS) $<
#remove object and any other garbage files.
clean:
rm -rf -d $(target).o *~ *% *# .#*
#remove the compiled file
clean-all:
$(clean) rm Main-$(target)
#run the compiled file
run:
./Main-$(target)
The command I use to compile is,
make target=sourceFile
Also I don't include the file extension, I have all my source file extensions to be cpp
What I want in the end is:
make sourceFile
Just a side note, for using the command clean and clean-all, I use
make target=sourceFile clean
make target=sourceFile clean-all
I'd prefer if I can use:
make sourceFile clean
make sourceFile clean-all
You may use common Makefile variable MAKECMDGOALS that contains all targets passed to make.
Please try this variant
CC = g++
CFLAGS = -Wall -g
MAKECMDGOALS := $(filter-out clean, $(MAKECMDGOALS))
.PHONY: $(MAKECMDGOALS)
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
clean:
rm -f *.o
Here the lines
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
will generate separate build targets for each word in MAKECMDGOALS.
Note, we need this Makefile to know that 'clean' is a target for removing stuff, but not to attempt build Main-clean. This why we remove clean from MAKECMDGOALS using filter-out function.
So if we run make a b clean, the build system will generate automatically targets for building Main-a and Main-b and then use already written clean target
Disclaimer -- this is a non-standard use of Make, and will therefore open up all kinds of corner cases, so I don't recommend it. This is better suited for a shell script calling make. That being said... it is an interesting question.
You can't do make xxx clean, and not have it try to build xxx (unless you do some really nasty cludge using recursive make, but I won't go there). You could do something like make clean-xxx though, as follows:
%:Main-%
Main-%:%.cpp
$(CC) $(CFLAGS) $< -o Main-$#
clean-%:
rm Main-$*
Notice that %-clean has a shorter stem, and therefor takes precedence over the % if the make target starts with clean-.

Why does GNU make always re-link my project?

I have the following Makefile in a directory full of .cpp and .h files:
CFLAGS=-g -std=c++0x -Wall -pedantic -Wextra -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -O0
CXX=g++
LDFLAGS=-lgmp -lmathsat -lz3
all: Foo.o Bar.o
$(CXX) $(CFLAGS) -o myexe Foo.o Bar.o $(LDFLAGS)
depend: .depend
.depend: $(wildcard *.cpp)
rm -f ./.depend
$(CXX) $(CFLAGS) -MM $^ > ./.depend
include .depend
%.o: %.cpp
$(CXX) $(CFLAGS) $(INCLUDE) $< -c
clean:
rm -f *.o myexe
When I hit make, it invariably executes the last step (linking) even when none of the .o files have changed. How can I prevent make from doing that? I'd expect make to output Everything up-to-date or something similar.
I'm on a i686 GNU/Linux machine with GNU Make 3.82 and g++ version 4.8.2.
Make relinks your project because it tries to build all. The rule for all does not create any file named all. Instead it produces myexe. Next time you run make, it will see that there's no all, but there's a rule to build one, so it dutifully executes that rule which happens to link myexe every time you run make.
In order to fix your problem you need to change your makefile to look roughly like this:
all: myexe
echo Build done
myexe: <myexe dependencies go here>
$(CXX) $(CFLAGS) -o myexe $(wildcard *.o) $(LDFLAGS)
Make always tries to build the top rule. For you, this is all. Since your all rule doesn't actually make an all file it will always be run.
Your probably want your all rule to be a myexe rule and, if you want an explicit all rule, have a dependency only rule: all: myexe.
(With GNU Make, you might want to explicitly declare those targets which aren't supposed to generate a real file with a .PHONY rule. e.g. .PHONY: all depend clean.)
make is a rule-based expert system.
You give it a heap of rules and a target (default target is the first one listed), and then it builds a complete dependency tree.
All parts are rebuilt iff they are non-existent resp. older than their dependencies, recursively.
The rule you are stumbling over is this: Because the target all does not create an output file all, make invokes the non-existent-or-outdated rule.
You can correct this by making the target all not do any work but instead just depend on the output file. Marking it .PHONY is also a good idea.

Makefile always recompiling a file

I am learning how to set up makefiles, and have ran into a problem. To demonstrate this I have created a simple "project" consisting of source files main.m and test.m.
I am trying to setup make to compile these files (only if somethings changed), and store the object files in somewhere else (here build/)
My Makefile:
OBJ = ./build
SOURCES=main.m test.m
OBJECTS=$(addprefix $(OBJ)/,$(SOURCES:.m=.o))
EXECUTABLE=test
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
gcc $(OBJECTS) -o $(EXECUTABLE)
$(OBJECTS): $(OBJ)/%.o: %.m build/
gcc -c $< -o $#
build/:
mkdir build
When I run it for the first time (with only the Makefile and the sources in the current directory) it does what I expect it to do:
gcc -c main.m -o build/main.o
gcc -c test.m -o build/test.o
gcc ./build/main.o ./build/test.o -o test
However if I run make again:
gcc -c main.m -o build/main.o
gcc ./build/main.o ./build/test.o -o test
What have I done wrong? Also noting any other errors in the Makefile is appreciated, as I am trying to learn to create "good" Makefiles.
EDIT:
What I spotted from make -d:
Finished prerequisites of target file `build/main.o'.
Prerequisite `main.m' is older than target `build/main.o'.
Prerequisite `build/' is older than target `build/main.o'.
No need to remake target `build/main.o'.
and
Finished prerequisites of target file `build/test.o'.
Prerequisite `test.m' is older than target `build/test.o'.
Prerequisite `build/' is newer than target `build/test.o'.
Must remake target `build/test.o'.
Your make -d output shows that make thinks your build directory has been updated, and so that file needs to be rebuilt.
I guess that happens because some operation either on your build system's part or by something else in your filesystem is causing some timestamp on that directory to be updated.
You can fix the problem by making build an order-only prerequisite by adding a | to that rule:
$(OBJECTS): $(OBJ)/%.o: %.m | build
I deleted the / too, since it wasn't doing anything.
Since you asked, some other editorial notes:
Add a clean target. Something like:
clean:
rm -rf $(EXECUTABLE) $(OBJ)
You don't need the ./ when you set OBJ. Just OBJ = build is enough.
You don't need the / on build as mentioned above. But that doesn't really matter, since you shouldn't be referring it to it anyway. Repalce build with $(OBJ) wherever you see it.
mkdir will fail if the directory already exists. You probably should prefix that command with a -:
$(OBJ):
-mkdir $(OBJ)
Note that I've done the replacement with $(OBJ) that I mentioned in #3 above.
Auto-generation of dependencies is very helpful. Your project as shown isn't big enough to really need it, but it's easy enough to add, so why not. You'll need to do a couple of things. First, get the appropriate dependency file names:
DEPFILES = $(addprefix $(OBJ)/,$(SOURCES:.m=.d))
Then get the compiler to generate them by adding the -MMD flag:
gcc -MMD -c $< -o $#
Lastly, include them in your makefile if they're available, by adding a line at the end of your makefile:
-include $(DEPFILES)

How to merge two Makefiles (each builds scripts with certain environment variables set) into a single Makefile?

I have two different directories with two different C++ source codes each of them execute different program. Directories have their own Makefiles each of them builds scripts with certain environment variables set.
Now, I want to put both directories' contents into a single directory as I want to mix both C++ source codes in order to develop a new C++ source code that utilizes both programs capabilities.
So far, I placed all files in a single directory, and I can successfully build each of the original source codes when I place the corresponding Makefile. Now, I want to have a single Makefile that allows me to build each of the original source codes (without replacing the Makefile), and hopefully this would allow me to build the new mixed C++ source file...
I tried a trivial solution and I placed the contents of both Makefiles into a single Makefile and this didn't work ...
I think it is useful to post my two Makefiles
Here is the first one
# A simple $(MAKE)file to cause make to go look in the top directory. A simple
# convenience.
all: lib
$(MAKE) -C .. examples
lib:
$(MAKE) -C .. lib/libAria.so
%.so: ../lib/libAria.so %.cpp
$(MAKE) -C .. examples/$#
%: ../lib/libAria.so %.cpp
$(MAKE) -C .. examples/$#
%Static: ../lib/libAria.a %.cpp
$(MAKE) -C .. examples/$#
clean:
$(MAKE) -C .. cleanExamples
../lib/libAria.so: FORCE
$(MAKE) -C .. dirs lib/libAria.so
../lib/libAria.a: FORCE
$(MAKE) -C .. dirs lib/libAria.a
FORCE:
.PHONY: all FORCE clean lib
And the second Makefile is
LDLIBS = -lm
CXXFLAGS = -O3 -finline-functions -I. -I./qpoases/INCLUDE -I./qpoases/SRC
CFLAGS = -O3
CC = g++
OBJECTS = \
./qpoases/SRC/QProblemB.o \
./qpoases/SRC/Bounds.o \
./qpoases/SRC/Constraints.o \
./qpoases/SRC/SubjectTo.o \
./qpoases/SRC/Indexlist.o \
./qpoases/SRC/CyclingManager.o \
./qpoases/SRC/Utils.o \
./qpoases/SRC/MessageHandling.o \
./qpoases/solver.o \
integrator.o \
condensing.o \
gauss_newton_method.o
.PHONY: all
all: test libacado_exported_rti.a
test: ${OBJECTS} test.o
./qpoases/solver.o : ./qpoases/solver.hpp
integrator.o : acado.h
condensing.o : acado.h
gauss_newton_method.o : acado.h ./qpoases/solver.hpp
test.o : acado.h ./qpoases/solver.hpp
libacado_exported_rti.a: ${OBJECTS}
ar r $# $?
${OBJECTS} : ./qpoases/solver.hpp
.PHONY : clean
clean :
-rm -f *.o *.a ./qpoases/SRC/*.o ./qpoases/SRC/*.a test
I check all stackoverflow questions related to my question and the only closest situation to mine is a question titled (multiple makefiles in one directory);however, this is not exactly what I want to do...
Thanks a lot !
Why would you want to merge your source directories? I assume they are seperated for a reason. Instead, I'd leave them be and create a new make file in the directory above them that calls each of the sub makes files below it - either via includes or via shelling directly to each makefile. I would not mix the code just to make it "easier" to get inheritance or whatever working.
BTW, here's a link for you:Stack Overflow shows you how

Implicit Build Rules: GNU Make Multiple Makefiles Multiple Directories

I have the following directory structure:
.
..
./Graphic/
./Graphic/SymbolXLib
There are several other directories in this project but I won't list them for simplicities sake.I want a main makefile that drives the build of other Makefiles stored in their own directories. There are several project comming together, so I can't just move source around.
The main makefile is defined as:
[mehoggan#hogganz400 Core]$ cat ./Makefile
CORE_LIBS_DIR = libs
OBJS_DIR = obj/symb_obj
include ./Graphic/SymbolXLib/Makefile
The Graphic makefile is defined as:
#
# make BUILD_MODE={release|debug} OS_ARCH={32|64}
#
# default is 32-bit release build
#
BUILD_MODE = release
OS_ARCH = 64
OBJS_DIR = $(BUILD_MODE)$(OS_ARCH)
SRC = \
./Graphic/SymbolXLib/CartoCursor.cpp \
...
./Graphic/SymbolXLib/TextureConversion.cpp \
$(NULL)
CC = gcc -fPIC
OBJS = $(SRC:%.cpp=$(OBJS_DIR)/%.o)
COPTS = -m$(OS_ARCH) -O2
CDEFS = -DLINUXx86 \
-I../../../SharedArcGIS/Include/GraphicsPipeline/Display/SymbolX/SymbolXLib \
-I../../../SharedArcGIS/Include/System/Geometry/GeometryXLib \
-I../../../ArcSDE/pe/include \
-I../../../ArcSDE/shape/include
CFLAGS = $(COPTS) $(CDEFS) $(CINCS)
TARGET = libSymbolXLib.a
all : $(OBJS_DIR) $(OBJS_DIR)/$(TARGET)
$(OBJS_DIR) :
mkdir -p $(OBJS_DIR)
$(OBJS_DIR)/$(TARGET) : $(OBJS)
ar qc $# $^
$(OBJS_DIR)/%.o : %.cpp
$(CC) -c $(CFLAGS) -o $# $<
The response at the previous post (Previous Post) helped only if I moved alot of things around. I can't do this. So the question still remains, how do I get make to recognize the implicit build in a subdirectory from the main Makefile?
The error I am getting is
make: *** No rule to make target `release64/./Graphic/SymbolXLib/CartoCursor.o', needed by `release64/libSymbolXLib.a'. Stop.
I have to think you'd have far better success if you avoided include and instead use recursive make. In the top-level Makefile, something like:
graphic:
$(MAKE) -C Graphic
And the Makefile in Graphic/Makefile can have its sub-projects:
symbolxlib:
$(MAKE) -C SymbolXLib
and so on. You might need to add each of the targets to a default target or something similar to hang them all together on a single execution. You could give each of these targets an actual dependency (they should be .PHONY: if they don't have a dependency...) to rebuild them only when necessary or when commanded to by an upper-level target that touch(1)es "command files".
Alternatively, this paper recommends a different approach to avoid recursive make, but I've not yet read it -- and have found recursive make works well enough in projects I've been a part of that I don't mind recommending it.
Does this gnumake documentation help you?