makefile same executable with different dependencies - makefile

I'm trying to write a makefile that creates the same executable (EXE) but for different purposes, (The *.o files in OBJ_DIR are built with a separate rule, not shown here)
FILE1 = ... some list of files ...
FILE2 = ... different list of files...
myexe1: $(patsubst %, $(OBJ_DIR)/%.o, $(FILE1))| $(BIN_DIR)
$(F90) -o $(EXE) $^ $(FFLAGS)
myexe2: $(patsubst %, $(OBJ_DIR)/%.o, $(FILE2))| $(BIN_DIR)
$(F90) -o $(EXE) $^ $(FFLAGS)
I can call the make with make myexe1 and make myexe2 and build the EXE.
But as the EXE is not myexe1 or myexe2, the build is triggered every time the make myexe1/myexe2 is called. But what I want, is when myexe1 is called it should check if EXE is updated and then it should trigger the build. I can make myexe1 a phony target to achieve this partially, like
FILE1 = ... some list of files ...
FILE2 = ... different list of files...
myexe1 : $(EXE)
$(EXE): $(patsubst %, $(OBJ_DIR)/%.o, $(FILE1))| $(BIN_DIR)
$(F90) -o $(EXE) $^ $(FFLAGS)
But then I can not run the myexe2 anymore. Is it possible that when myexe1 or myexe2 is called it should check if the EXE and the associated object files are updated, and only then it should trigger the build process?

This is an odd requirement. But I recommend you build the unique target, then copy it to the common target as a side-effect:
FILE1 = ... some list of files ...
FILE2 = ... different list of files...
myexe1: $(patsubst %, $(OBJ_DIR)/%.o, $(FILE1))| $(BIN_DIR)
$(F90) -o $# $^ $(FFLAGS)
cp $# $(EXE)
myexe2: $(patsubst %, $(OBJ_DIR)/%.o, $(FILE2))| $(BIN_DIR)
$(F90) -o $# $^ $(FFLAGS)
cp $# $(EXE)
Now whichever one of myexe1 or myexe2 was last built, will be the one in the $(EXE).

Related

Makefile - link input file from folder

I try to compile a project with generated object stored in a sub directory :
myproject:
|
src: .cpp, .cpp ...
|
release: .o, .o ...
Here's a part of Makefile:
SRC ?= src
OBJ_PATH = $(SRC)/Release
vpath %.o $(OBJ_PATH)
...
OBJS := $(addprefix $(OBJ_PATH)/,obj1.o obj2.o )
all: build
obj1.o: $(SRC)/Manager.cpp
$(EXEC) $(CC) $(INCLUDES) $(CCFLAGS) $(GNCD_FLGS) -c $(<) -o $(OBJ_PATH)/$# #-o $# -c $<
obj2.o: $(SRC)/Synth.cpp
$(EXEC) $(CC) $(INCLUDES) $(CCFLAGS) $(GNCD_FLGS) $(DEFS) -c $(<) -o $(OBJ_PATH)/$# #-o $# -c $<
myApp: obj1.o obj2.o
$(EXEC) $(CC) $(LDFLAGS) $(GNCD_FLGS) -o $# $(OBJS) $+ $(LIBS)
$(EXEC) mkdir -p $(OBJ_PATH)/$(TRGT_ARCH)/$(TRGT_OS)/$(BLD_TP)
$(EXEC) cp $# $(OBJ_PATH)/$(TRGT_ARCH)/$(TRGT_OS)/$(BLD_TP)
$(OBJECTS) : Stt.h
build: myApp
run: build
$(EXEC) ./myApp
..but i got an error link:
Could not open input file 'obj1.o'
Makefile:86: recipe for target 'myApp' failed
So it seems couldn't find object in src/Release dir;
any ideas ?
thank's
Your recipe for myApp use $+, which list the prerequisites. It expands in obj1.o obj2.o. But you build obj1.o and obj2.o in $(OBJ_PATH). So the linker try to find the objects in the root directory, but cannot find them, since they are in $(OBJ_PATH).
Since your recipe explicitely lists them (with $(OBJS)), you do not need the automatic variable.
Sidenote
According to Paul's Second rule of Makefiles, it is best that every rule updates a file corresponding exactly to the target name (including the path part) (in other words, always use $# in the recipe), in order to always know which is the exact file updated.
In your case, if you want to build the objects files in OBJ_PATH, you could use a rule of the form $(OBJ_PATH)/obj.o for each.
You could also replace the dependency of myApp by $(OBJS), and use the automatic variable (btw, is there a reason why you prefer $+ over $^ (does the same thing but do not conserv duplicates in the prerequisites list) ?).

Why is makefile recompiling entire set of files if I only change one?

Here is my makefile... Why does it recompile all sources even if only one changes??
CC = g++
CFLAGS = -w -g -c
LIBS = -lm
EXEC = DFMS_PDS_L2_to_L3
.PHONY : clean tgz wdtgz
HOMEDIR = ../
BIN = bin
SRC = src
OBJ = obj
SRCFILES := $(wildcard $(SRC)/*.cc)
OBJFILES := $(patsubst %.cc, $(OBJ)/%.o, $(notdir $(SRCFILES)))
OBJS := $(patsubst %.cc, %.o, $(notdir $(SRCFILES)))
# Executable Targets
all: $(EXEC)
$(EXEC) : $(OBJS)
$(CC) $(LIBS) $(OBJFILES) -o $(BIN)/$(EXEC)
# Dependencies
%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $(OBJ)/$#
# Miscellaneous Targets
clean:
rm -rf $(BIN)/$(EXEC) obj/*.o *~
tgz:
tar cvzf $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild --exclude=data
cp $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild.tgz.allow
wdtgz:
tar cvzf $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild
cp $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild.tgz.allow
I'm running on Linux 3.0 with gnu make
Is it in the $(EXEC) definition?
My guess is that this recompiles all of the sources even if none changes.
Look at these two rules:
$(EXEC) : $(OBJS)
$(CC) $(LIBS) $(OBJFILES) -o $(BIN)/$(EXEC)
%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $(OBJ)/$#
Suppose foo.cc is the only source file. The first rule says that the target depends on foo.o, but actually builds it from obj/foo.o. The second can be invoked to build foo.o (which the first rule demands), but it actually builds obj/foo.o. So the first time you run Make it will build the executable correctly (and obj/foo.o). But every time thereafter, Make sees that foo.o does not exist and attempts to build it and rebuild the executable.
The solution is to rewrite the rules so that they build -- and depend on -- what they claim:
all: $(BIN)/$(EXEC)
$(BIN)/$(EXEC) : $(OBJFILES)
$(CC) $(LIBS) $^ -o $#
$(OBJ)/%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $#

Makefile rebuilds everything every time, why?

I have simple makefile here:
SOURCES= $(wildcard *.c)
OBJECTS= $(patsubst %.c, %.o, $(SOURCES))
NAMES= $(patsubst %.c, %, $(SOURCES))
CC=gcc
CFLAGS= -Wall -c -o
TASKS_IN_DIRS= $(addprefix obj/,$(OBJECTS)) $(addprefix bin/,$(NAMES))
all: $(NAMES)
$(NAMES): %: %.o $(OBJECTS)
$(CC) -o bin/$# obj/$^
$(OBJECTS): %.o: %.c
$(CC) $(CFLAGS) obj/$# $<
clean:
rm -rf $(TASKS_IN_DIRS)
Getting all the c files names.
Making from them simple names(without extension) and object names.
Doing things
And what matters - all works, but works every time i print make(compiling and linking all the files). even if i don't changed anything and i do it few times in row, is something wrong with dependencies?
I expected something like "blabla is up to date" instead.
$(OBJECTS): %.o: %.c
$(CC) $(CFLAGS) obj/$# $<
is looking in your current directory for your .o files. Since they're not there it's rebuilding them.
The following does what you want.
SOURCES= $(wildcard *.c)
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
OBJECTS:= $(addprefix obj/,$(OBJECTS))
NAMES:= $(patsubst %.c, %, $(SOURCES))
NAMES:= $(addprefix bin/,$(NAMES))
CC=gcc
CFLAGS= -Wall -c -o
TASKS_IN_DIRS=$(OBJECTS) $(NAMES)
all: $(NAMES)
$(NAMES): $(OBJECTS)
$(CC) -o $# $<
obj/%.o: %.c
$(CC) $(CFLAGS) $# $<
clean:
rm -rf $(TASKS_IN_DIRS)
You lied to make. You promised that each of the$(NAMES) targets creates its object file in the current directory, but due to $(CC) -o bin/$# obj/$^ it is created in the bin directory.
At the next make invocation, it can't find the object files and runs each command again.
Hard and Fast Rule for Makefiles: each non-PHONY target must use a plain $# somewhere in its commands to indicate the file it creates.

How to depend on targets of a previous make invocation

I have a lib (say mylib) and two executables and one of these (say exe1) depends on lib. In file system i have:
src
Makefile
...
lib
mylib
Makefile
...
exe1
Makefile
...
exe2
Makefile
...
and by launching make in src dir all is builded.
Makefile in src:
EXE=exe1 exe2
LIB=mylib
all: $(LIB) $(EXE)
.PHONY: $(LIB) $(EXE)
$(LIB):
$(MAKE) -C lib/$#
$(EXE): $(LIB)
$(MAKE) -C $#
and, for example, Makefile for exe1 is:
...
all: exe1 copy
exe1: exe1.o
$(CC) $(CFLAGS) $(OBJ) $(LDFLAGS) -o $#
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
...
My problem is that if i change a file in mylib dir the library is correctly rebuilded but exe1 obsiously no...is there a way to teel make that exe1 target depends on a target (mylib) that is specified in a previous invocation of make without specifing dependencies on mylib's files in exe1 Makefile?
Thank you all.
#tripleee and #JackKelly (curse his name) are right, this is not a healthy makefile system.
You can get something like what you want by changing src/Makefile:
EXE=exe1 exe2
LIB=lib/mylib/mylib
all: $(LIB) $(EXE)
.PHONY: $(EXE)
$(LIB):
$(MAKE) -C lib/mylib
exe1: $(LIB)
$(EXE):
$(MAKE) -C $#
and changing exe1/makefile so that it will always rebuild exe1:
.PHONY: exe1
This still has many problems, but at least it will correctly rebuild lib/mylib/mylib and src/exe1/exe1 when you run Make in src. (It will not work if you run Make in src/exe1/.)

Generate object files in subdirectory using a Makefile

I am trying to create a Makefile in order to generate object files in a subdirectory rather than let them in the src/ folder.
Here is the structure of the project:
Trunk
- Server
- src/
- include/
- Common
- src/
- include/
The Makefile is located in Trunk/Server. Source files are located both in Server/src and Common/src, so the Makefile currently has something like this:
SRC = src/main.cpp \
src/Network.cpp \
../Common/src/SQLManager.cpp \
../Common/src/Utils.cpp
I woud like to put generated object files in respective obj folders, so Trunk/Server/obj and Trunk/Common/obj. How can I achieve this? I've found many ways to generate object files in subdirectories (vpath, patsubst and many more) but I can't make any of them work for this folder organization.
Edit: If there is a way to put all object files in Server/obj/, that would be ok too.
Here's the complete Makefile (minus some source files and linked libraries):
Edit2: Updated with Didier Trosset's changes
CXX = g++
RM = rm -vf
NAME = Server
SRC = src/main.cpp \
src/Network.cpp \
../Common/src/SQLManager.cpp \
../Common/src/Utils.cpp
OBJ = $(subst src/,obj/, $(subst .cpp,.o, $(SRC)))
LDFLAGS = -lpthread -lm
CPPFLAGS = -std=c++0x -pedantic -Wextra -Wall -Wconversion -Iinclude -I../Common/include
all: Server
%.o: %.cpp
$(CXX) $< -o $#
Server: $(OBJ)
$(CXX) -o $(NAME) $(OBJ) $(LDFLAGS)
clean:
$(RM) $(OBJ) *~
fclean: clean
$(RM) $(NAME)
re: fclean Server
.PHONY: all clean fclean Server
Given these definitions, subst should be used to substitute the src part of the directory, and the file extension.
OBJ = $(subst src/,bin/,$(subst .cpp,.o,$(SRC)))
Then, you have to add new pattern rules to compile your source files. (You have to write one pattern rule per directory where your source files are.)
obj/%.o: src/%.cpp
$(CXX) -c $< -o $#
../Common/obj/%.o: ../Common/src/%.cpp
$(CXX) -c $< -o $#
I'm not sure that this will work, but I would try something like:
OBJ := $(join $(addsuffix ../obj/,$(dir $(SRC))),$(notdir $(SRC))
# or, as Didier suggested:
# OBJ := $(subst src/,obj/,$(SRC))
%.o: ../src/%.cpp
$(CXX) $< -o $#
It's not clear exactly what you're trying to do, but this should come close:
OBJ = $(subst src/,obj/,$(SRC:.cpp=.o))
obj/%.o : src/%.cpp
$(CXX) $< -o $#
../Common/obj/%.o : ../Common/src/%.cpp
$(CXX) $< -o $#

Resources