Today, I got a project with a makefile to compile it, but unfortunately I can't run a makefile on Windows. So I started converting it to CMake but as I don't have much knowledge on makefiles to correctly understand what the following code tries to do and "emulate" the behavior in CMake.
So the code where I have problems is the following one:
# -- src and obj List ----------
SRC = $(addprefix ${SRC_PATH}/, $(FILE))
OBJ = $(addprefix ${OBJ_PATH}/, $(addsuffix .o, $(basename $(FILE))))
# -- Base rules ----------
$(OBJ_PATH)/%.o : $(SRC_PATH)/%.c
$(CC) $(CFLAGS) -c $< -o $#
#-----Main rule ----------
$(EXE_PATH)/$(PRODUCT): $(OBJ)
$(CC) -o $# $^ $(LDFLAGS) $(OPTFLAGS) $(CFG) $(INC) $(LIB) -lm
# -- Other stuff ----------
depend:
makedepend $(CFLAGS) -Y $(SRC)
Could some one give me some insights in how to convert this one?, especially, in what $#, $< and $^do?
Thanks.
$#, $< and $^ are automatic variables, relevant documentation can be found here
Related
I have a recipe in my makefile that relies on several object files. I would like it to simply link the them, but they are always recompiling.
I've googled around and found information I did not know(marked with #) and changed it a bit, but the problem persisted.
I am led to believe make expects the name of the recipe be the name of the file, and I am failing to accomplish that. The problem is I do not what else to try and fix this. I would appreciate any help
CC = g++
#.PHONY: sfml-app
LIBS = -lsfml-graphics -lsfml-window -lsfml-system
APPLICATION = sfml-app
INCLUDE_DIR = -I include/
SOURCE_DIR = source
OUTPUT_DIR = bin
SOURCES = $(wildcard $(SOURCE_DIR)/*.cpp)
OBJECTS = $(notdir $(patsubst %.cpp, %.o, $(SOURCES)))
#$(OUTPUT_DIR)/$(APPLICATION): $(OBJECTS)
#bin/sfml-app: $(OBJECTS)
#sfml-app: $(OBJECTS)
#$(APPLICATION): $(OBJECTS)
$(CC) $(OUTPUT_DIR)/*.o $(LIBS) -o $(OUTPUT_DIR)/$(APPLICATION)
%.o: $(SOURCE_DIR)/%.cpp
$(CC) -c $< $(INCLUDE_DIR) -o $(OUTPUT_DIR)/$#
clean:
rm $(OUTPUT_DIR)/*
print-% : ; #echo $* = $($*)
This rule doesn't create the file it promises to:
%.o: $(SOURCE_DIR)/%.cpp
$(CC) -c $< $(INCLUDE_DIR) -o $(OUTPUT_DIR)/$#
See that -o $(OUTPUT_DIR)/$#? That's instructing the compiler to create a file in $(OUTPUT_DIR) instead of in the working directory.
If you really want your object files to go in $(OUTPUT_DIR), you need to make sure that your rule indicates that:
$(OUTPUT_DIR)/%.o: $(SOURCE_DIR)/%.cpp
$(CC) -c $< $(INCLUDE_DIR) -o $#
Or better, to act like the standard %.o: %.c rule (which will include CFLAGS etc):
$(OUTPUT_DIR)/%.o: $(SOURCE_DIR)/%.cpp
$(COMPILE.c) $(OUTPUT_OPTION) $<
I note your input files are named *.cpp - usually, that convention is for C++ files (i.e. to be compiled with $(COMPILE.cc), which will invoke $(CXX) rather than $(CC)). Check that you've not mixed up your C and C++ sources!
I have the following Makefile:
VERSION = 0.1.1
CC = g++
CFLAGS = -Wall -g -DVERSION=\"$(VERSION)\"
LDFLAGS = -lm
DEPFILE = .dep
SOURCES := ${wildcard *.cpp}
HEADERS := ${wildcard *.h}
OBJECTS := ${SOURCES:.cpp=.o}
BINARY = main.exe
.PHONY: all dep clean
all: $(BINARY)
$(BINARY): $(DEPFILE) $(OBJECTS)
$(CC) $(CFLAGS) -o $(BINARY) $(OBJECTS) $(LDFLAGS)
%.o: %.cpp
$(CC) $(CFLAGS) -c $<
dep: $(DEPFILE)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $(DEPFILE)
-include $(DEPFILE)
clean:
rm -vf $(BINARY) $(OBJECTS) $(DEPFILE)
When I run make dep I get
g++ -MM Monomial.cpp main.cpp Variable.cpp > .dep
make: Nothing to be done for 'dep'.
It seems as if dep is called twice. Why is that?
I am using GNU Make 4.2.1 under Cygwin.
Also it would be great if you could give me some best practises for this Makefile if you spot some bad design patterns (other than the double call of dep).
Your makefile contains an include directive:
-include $(DEPFILE)
So when Make starts, before it even considers the target(s) you've asked it to build, it tries to rebuild the file that is to be included in the makefile. Once it's done rebuilding .dep, it gets to work on the file you asked for... which is .dep.
You probably don't have to explicitly make dep, ever.
And you can simplify a couple of your rules in light of this fact, and the useful nature of automatic variables:
$(BINARY): $(OBJECTS)
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $#
I have the following makefile snippet to compile my C++ project.
obj/%.o: src/%.cpp
$(CXX) $(CFLAGS) -c $< -o $#
Now I want to link the .o files. But I want to be able to just call the rule name of the link, like make build/main, in order to compile AND link.
Neither this:
build/main: $(wildcard obj/*.o)
$(CXX) $^ -o $#
works, as it only links and does not compile, as I would expect by this answer;
nor this:
build/main: obj/%.o
$(CXX) $^ -o $#
with the error:
No rule to make target 'obj/%.o', needed by 'build/main'. Stop.
even though it is needed.
SOURCES := $(wildcard src/*.cpp)
OBJECTS := $(patsubst src/%.cpp, obj/%.o, $(SOURCES))
build/main: $(OBJECTS)
$(CXX) $^ -o $#
I've this folder structure
project
|_src
| |_test
| |_main.cpp
|_Makefile
This is my makefile (trying to adapt from this link):
CC = g++
RM = rm
WFLAGS = -c -Wall -W
LDFLAGS =
SRCTESTD = src/test
EXECUTABLE = test
OBJD = .obj
DEPD = .dep
SRCSTEST = $(SRCTESTD)/main.cpp
OBJECTSTEST = $(patsubst %.cpp, $(OBJD)/test/%.o, $(notdir $(SRCSTEST)))
DEPDSTEST = $(patsubst %.cpp, $(DEPD)/test/%.d, $(notdir $(SRCSTEST)))
all: $(SRCSTEST) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTSTEST)
$(CC) $(LDFLAGS) $(OBJECTSTEST) -o $#
.cpp.o:
$(CC) $(WFLAGS) $< -o $#
It does not work, and I've this error
make: *** No rule to make target `.obj/test/main.o', needed by `test'. Stop.
What I'm doing wrong? Sorry for trivial question, but I'm a make newbie.
The link shows outdated methods, such as suffix rules. Making dependencies can also be done during compilation by gcc/g++.
As for the rest, here is it :
EXE := test
SRCDIR := src
OBJDIR := .obj
SRC := $(shell find $(SRCDIR) -name "*.cpp")
OBJ := $(SRC:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
DEP := $(OBJ:.o=.d)
LDLIBS := # -l flags
LDFLAGS := # -L flags
CPPFLAGS := -MMD -MP # -I flags also
CXXFLAGS := -W -Wall # no -c flag here
.PHONY: all clean fclean re
all: $(EXE)
clean:
$(RM) -r $(OBJDIR)
fclean: clean
$(RM) $(EXE)
re: fclean all
-include $(DEP)
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
#mkdir -p $(#D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
No redefinition of internally defined variables, no suffix rules, correct linking step and dependencies generation.
Update: To avoid calling mkdir for every source file, one should use order-only prerequisites and the special target .SECONDEXPANSION.
Change this block:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
#mkdir -p $(#D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
To this:
.SECONDEXPANSION:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $$(#D)/
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
%/:
mkdir $*
The error means make can't find a correct rule to build your object files. Your tree structure lacks some informations: only one file ? Where are the others ? Anyway, here are some hints:
In the last two lines, you are using an obsolete feature of make: suffix rules. I suggest you switch to a pattern rule, which is functionaly equivalent.
Say something like:
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
Another thing (that shouldn't be a problem here): you are using the variable CC which is internally defined as the default C compiler. It's okay because you redefine it, but as your sources seem to be C++ files, why not use the variable CXX, that is internally defined as the C++ compiler ?
Lastly, to make sure your set of files are correctly defined, you can print them with a dummy show target, see here.
show:
#echo "OBJECTSTEST=$(OBJECTSTEST)"
...
I know there are ways to remove duplicates $(CC) $(CFLAGS) $# $^ in Makefile. Can you tell me how to make the Makefile below more concise?
CC=gcc
CFLAGS=-pthread -g -o
all: p1 p2
p1: p1.c
$(CC) $(CFLAGS) $# $^
p2: p2.c
$(CC) $(CFLAGS) $# $^
To make your Makefile more concise, you can write it as follows.
CC=gcc
CFLAGS=-pthread -g -o
all: p1 p2
%: %.c
$(CC) $(CFLAGS) $# $^
Then you can add as many p's as you want on the all: line. As long as you provide pN.c, make will compile them into the corresponding pN.
Yes, you can combine commands "by prerequisite". For example:
CC=gcc
CFLAGS=-O3
INCLS=-I$(BASEDIR)/include
LIBS=$(BASEDIR)/lib/thread.a
OBJS = dotprod_mutex.o dotprod_serial.o
EXEC = dotprod
$(EXEC): $(OBJS)
$(CC) -o $(EXEC) $(OBJS) $(LIBS)
$(OBJS): dotprod.h
$(CC) $(CFLAGS) $(INCLS) -c $*.c
or somesuch -- you'll need to go through the details and make sure those libraries and so on actually make sense.
Note that the phrase $(OBJS): dotprod.h means that $(OBJS): depends on the presence of dotprod.h.
You will want to read the manual to get all the gory details, in particular:
Letting Make deduce commands
Combine by prerequisite
As for tools to automate this stuff, you want automake and autoconf: http://sourceware.org/autobook/