Makefile pattern rules differences - c++

What is the difference between .cpp.o:, .o: and %.o: %.c?
Here's a simple Makefile example:
CC=g++
CFLAGS=-c -Wall
SOURCES=file1.cpp file2.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=program
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $#
#.o:
#.cpp.o:
%.o: %.c
$(CC) $(CFLAGS) $< -o $#
all: $(SOURCES) $(EXECUTABLE)
clean:
rm -rf $(OBJECTS) $(EXECUTABLE)
I have noticed that the output is same, but I guess they are interpreted on a different way internally.
Is there a preferred way of doing this?

.cpp.o: # build *.o from *.cpp (old style notation)
%.o: %.c # build *.o from *.c (new style notation)
Both work but the new style is more powerful because it allows you to write more complicated constructions thanks to pattern matching:
%.uuu: %.vvv %.www

Related

Make, Endpoints that differ by precompiler-flag

Using make, I need to produce two versions of an executable, which differ by the use of a precompiler flag DXYZ. The way I have this working so far is to produce the *.o objects for the vanilla program, and, another set *.o_xyz for the objects that make use of the -DXYZ flag.
So basically I have two two rules to produce the objects, ie: $(OBJ)/%.o: %.cpp and $(OBJ)/%.o_xyz: %.cpp.
I am wondering if this is this the best way to achieve this? Is it possible to reduce this to a single rule?
CXX=g++
OBJ=./obj
BIN=./bin
INC=-I./inc
CXXFLAGS=-std=c++11 -Wall -Wno-comment
LDFLAGS=-lpthread
CXX_SOURCES=$(wildcard *.cpp)
CXX_OBJECTS=$(patsubst %.cpp, $(OBJ)/%.o,$(notdir $(CXX_SOURCES)))
.PHONY: all
all : program_xyz program
program_xyz: $(addsuffix _xyz,$(CXX_OBJECTS))
#mkdir -p $(BIN)
$(CXX) -o $(BIN)/$# $^ $(LDFLAGS) $(INC) -DXYZ
program: $(CXX_OBJECTS)
#mkdir -p $(BIN)
$(CXX) -o $(BIN)/$# $^ $(LDFLAGS) $(INC)
##Vanilla Endpoints
$(OBJ)/%.o: %.cpp
#mkdir -p $(#D)
$(CXX) -c $< -o $# $(INC) $(CXXFLAGS)
##Endpoint with DXYZ flag
$(OBJ)/%.o_xyz: %.cpp
#mkdir -p $(#D)
$(CXX) -c $< -o $# $(INC) $(CXXFLAGS) -DXYZ

How can I switch between compilers in the makefile?

I have the following makefile:
CFLAGS=-c -Wall -std=c++11
MCFLAGS=-c -Wall -std=c++11
LDFLAGS= -shared
MLDFLAGS=
MSOURCES=main.cpp MCC.cpp Point3D.cpp
SOURCES= mainDLL.cpp MCC.cpp Point3D.cpp
OBJECTS=$(SOURCES:.cpp=.o)
MOBJECTS=$(MSOURCES:.cpp=.o)
EXECUTABLE=h2r.dll
MEXECUTABLE=h2r
CC=i686-w64-mingw32-g++
CC=g++
all: clean $(MSOURCES) $(MEXECUTABLE)
dll: clean $(SOURCES) $(EXECUTABLE)
$(MEXECUTABLE): $(MOBJECTS)
$(CC) $(MLDFLAGS) $(MOBJECTS) -o $#
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm *.o $(MEXECUTABLE) $(EXECUTABLE)
How can I initialize the CC with the cross compiler(CC=i686-w64-mingw32-g++) when the make dll command is emitted and how can I use the gnu compiler when the make all is emitted?
To set a variable based on what target is being executed you can do something like:
all: CC=g++
all: clean $(MSOURCES) $(MEXECUTABLE)
dll: CC=i686-w64-mingw32-g++
dll: clean $(SOURCES) $(EXECUTABLE)
Define two different CC instead of redefining the one. Since you have different rules for the all and dll, you can just use the other compiler in the other rule. Somehow like this:
CCDLL=i686-w64-mingw32-g++
CCALL=g++
all: clean $(MSOURCES) $(MEXECUTABLE)
dll: clean $(SOURCES) $(EXECUTABLE)
$(MEXECUTABLE): $(MOBJECTS)
$(CCALL) $(MLDFLAGS) $(MOBJECTS) -o $#
$(EXECUTABLE): $(OBJECTS)
$(CCDLL) $(LDFLAGS) $(OBJECTS) -o $#
Your overwriting whatever is in the CC variable. Why don't you just have:
CC_DLL=i686-w64-mingw32-g++
CC=g++
And simply use the relevant one in your targets.

How to write specific rule for a target in makefile?

I know the title is quite ambiguous but I just don't know how to describe my problem concisely. Please edit that if you want.
Currently my makefile is like the following:
CC = g++
CFLAGS = -Wall -g
TARGET = foobar
SRC_FILES = foo.cpp bar.cpp main.cpp
OBJ_FILES := $(SRC_FILES:.cpp=.o)
$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $^ -o $#
%.o: %.cpp %.h
$(CC) $(CFLAGS) -c $<
clean:
rm -rf *.o $(TARGET)
The problem is that this structure requires main.cpp to have a main.h header file, which I don't really have. How can I handle this nicely?
GCC (and probably Clang) can build a list of dependencies for you; This way, you can simply make your object files from their source (cpp) file:
depend: .depend
.depend: $(SRC_FILES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ -MF ./.depend;
include .depend
%.o: %.cpp
$(CC) $(CFLAGS) -c $<
You might also find interest in the makedepend tool.

How to change my makefile to build into a separate folder

I have the following makefile:
CC=g++
CCOPTS=-Wall -Wextra -g
OBJS = manager.o tcpcon.o
TARGETS = manager
.PHONY: all clean
$(TARGETS) : $(OBJS)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
all: $(TARGETS) $(OBJS)
clean:
rm -f $(TARGETS) $(OBJS)
%: %.cpp
$(CC) $(CCOPTS) -o $# $<
Is there a way I can make my .o and bin files be built into a directory called build? I tried going through some tutorials, but I guess I just don't fully understand makefiles..
Don't feel too bad; I'm not sure anyone fully understands makefiles.
BUILD_DIR = build
OBJS = $(BUILD_DIR)/manager.o $(BUILD_DIR)/tcpcon.o
TARGETS = $(BUILD_DIR)/manager
...
$(BUILD_DIR)/%.o: %.cpp
$(CC) -c $(CCOPTS) -o $# $<

a couple of Makefile issues

I've got this Makefile:
CFLAGS = -c -Wall
CC = g++
EXEC = main
SOURCES = main.cpp listpath.cpp Parser.cpp
OBJECTS = $(SOURCES: .cpp=.o)
EXECUTABLE = tp
DIR_SRC = /src/
DIR_OBJ = /obj/
all: $(SOURCES) $(OBJECTS)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm $(OBJECTS) $(EXECUTABLE)
Note this:
I'm in the directory "." which contains the makefile
The folder "./src" EXISTS, and has all the .h and .cpp files
The folder "./obj" doesn't exist, I want makefile to create it and put all the .o there
The error I get is:
No rules to build "main.cpp", necessary for "all". Stopping.
Help!
All right, from the top:
CFLAGS = -c -Wall
CC = g++
# EXEC = main never used, not needed
SOURCES = main.cpp listpath.cpp Parser.cpp
So far, so good. Note that this SOURCES doesn't mention DIR_SRC, so we'll have to make that connection later (and $(DIR_SRC)$(SOURCES) won't work, because the path must be appended to each member of the list). But OBJECTS really needs paths (e.g. /obj/main.o):
OBJECTS = $(patsubst %.cpp, $(DIR_OBJ)%.o, $(SOURCES))
EXECUTABLE = tp
DIR_SRC = /src/
DIR_OBJ = /obj/
(Personally I don't like putting the trailing slash in the variable, but it's a matter of taste.) The first target is the default target, so it should build what you actually want built:
all: $(EXECUTABLE)
Don't worry about listing the sources as prerequisites; they will sort themselves out later.
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $# # <-- note the automatic variable $^
The .cpp.o convention doesn't really work here; we'll have to spell it out. And we must tell Make to search $(DIR_SRC) for .cpp files:
$(OBJECTS): $(DIR_OBJ)%.o: %.cpp $(DIR_OBJ)
$(CC) $(CFLAGS) $< -o $#
$(DIR_OBJ):
mkdir $#
vpath %.cpp $(DIR_SRC)
And tell Make that clean is not a real target, just to be safe:
.PHONY: clean
clean:
rm $(OBJECTS) $(EXECUTABLE)
EDIT:
I shouldn't have attempted so much in one step. Let's try something simpler:
$(DIR_OBJ)%.o: $(DIR_SRC)%.cpp $(DIR_OBJ)
$(CC) $(CFLAGS) $< -o $#
Edit the SOURCES to include the source directory (e.g. src/main.cpp etc.).
For the object files, consider something like this:
OBJECTS = $(subst src/,obj/,$(SOURCES:%.cpp=%.o))
# ...
all: $(SOURCES) build
.PHONY: build
build: pre_build $(EXECUTABLE)
.PHONY: pre_build
pre_build: obj
obj:
-mkdir obj
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $#