How to change my makefile to build into a separate folder - c++

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 $# $<

Related

Library not loaded: #rpath/libMatlabEngine.dylib

I'm pretty much a novice when it comes to coding.
I'm trying to visualize a game in C++ using Matlab.
The makefile was partially given as part of the exercise.
I tried fixing the problem by using this: https://de.mathworks.com/help/matlab/matlab_external/custom-linking-to-required-api-libraries.html
The code works but when trying to implement the "GUI" this error comes up:
dyld[45987]: Library not loaded: #rpath/libMatlabEngine.dylib
Reason: tried: '/Applications/MATLAB_R2020a.app/bin/maci64/libMatlabEngine.dylib' (no such file), '/Applications/MATLAB_R2020a.app/sys/os/maci64/libMatlabEngine.dylib' (no such file), '/libMatlabEngine.dylib' (no such file), '/usr/local/lib/libMatlabEngine.dylib' (no such file), '/usr/lib/libMatlabEngine.dylib' (no such file)
MATLAB_ROOT=/Applications/MATLAB_R2020a.app
Gpp=g++
LD=g++
CPPFLAGS=-MMD -MP -std=c++11 -Wpedantic \
-I ${MATLAB_ROOT}/extern/include/ -pthread
LDFLAGS=-L ${MATLAB_ROOT}/extern/bin/maci64/ -pthread
LDLIBS=-lMatlabDataArray -lMatlabEngine
srcs = $(wildcard *.cpp)
objs = $(srcs:.cpp=.o)
deps = $(srcs:.cpp=.d)
targets = viergewinnt
default: viergewinnt
run: viergewinnt
LD_LIBRARY_PATH=\
${MATLAB_ROOT}extern/bin/maci64:${LD_LIBRARY_PATH} \
./viergewinnt
viergewinnt: viergewinnt.o cviergewinnt.o cviergewinntGUI.o
$(LD) $(LDFLAGS) -o $# $^ $(LDLIBS)
%.o: %.cpp
$(Gpp) $(CPPFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(RM) $(targets) $(objs) $(deps) *~
-include $(deps)

How to prevent my makefile to relink due to static library

I have a Makefile which works well when there is not static library to compile:
CC = g++ -std=c++11
RM = rm -f
NAME = hello
SRCS = Main.cpp \
srcs/Controller.cpp \
...
srcs/Parser.cpp
OBJS = $(SRCS:.cpp=.o)
CPPFLAGS += -W -Wall -Wextra -Werror
all : $(NAME)
$(NAME) : $(OBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(OBJS) -I./inc
clean :
$(RM) $(OBJS)
fclean : clean
$(RM) $(NAME)
re : fclean all
.PHONY : all clean fclean re
This makefile works and doesn't relink (when I type twice "make", it doesn't recompile and output "Nothing to be done for all")
But when I want to compile a static library, the "make" command recompile the library without outputing "Nothing to be done for all", here is the new Makefile containing the static lib:
CC = g++ -std=c++11
RM = rm -f
NAME = hello
LIBNAME = libhello.a
SRCS = srcs/Controller.cpp \
...
srcs/Parser.cpp
OBJS = $(SRCS:.cpp=.o)
CPPFLAGS += -W -Wall -Wextra -Werror
all : $(NAME)
$(NAME) : $(OBJS)
ar rc $(LIBNAME) $(OBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(LIBNAME) Main.cpp -I./inc
clean :
$(RM) $(OBJS)
$(RM) $(LIBNAME)
fclean : clean
$(RM) $(NAME)
re : fclean all
.PHONY : all clean fclean re
How could I fix that problem to prevent the makefile to recompile when the static library has already been compiled and doesn't need to be recompiled ?
Thank you very much
regarding this recipe:
$(NAME) : $(OBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(OBJS) -I./inc
it is expecting that the default compile statement will be used to generate the object files and make will generate those object files before executing the rule. and since it is not performing any compiles in this recipe, the parameter -I./inc is unneeded.
Without the header files being listed in the dependencies, changing a header file will fail to cause the associated source files to be recompiled.
Suggest:
HEADERS := ..
$(name): $(OBJS)
<tab> $(CC) -o $# $(OBJS) $(LFLAGS)
%.o:%.cpp $(HEADERS)
<tab> $(CC) $(CPPFLAGS) -c $< -o $# -I./inc
Note in the line:
CPPFLAGS += -W -Wall -Wextra -Werror
the -W turns off all the previously enabled warnings, probably not what you want, suggest removing that parameter.
Similar considerations need to be applied when creating the static library, similar to:
this line:
$(NAME) : $(OBJS)
ar rc $(LIBNAME) $(OBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(LIBNAME) Main.cpp -I./inc
becomes:
HEADER := ...
all: $(LIBNAME) $(NAME)
$(LIBNAME): $(OBJS)
<tab> ar rc -o $# $^
%.o:%.cpp
<tab> $(CC) $(CPPFLAGS) -c $< -o $# -I./inc
$(NAME): main.o $(LIBNAME)
<tab> $(CC) $< -o $# $(LFLAGS) -l$(LIBNAME)
The issue is that $NAME is a phony target due to this rule:
all : $(NAME)
I think the issue can be resolved by instead changing it to an actual target:
all : $(LIBNAME)
Also, you have this rule:
$(NAME) : $(OBJS)
ar rc $(LIBNAME) $(OBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(LIBNAME) Main.cpp -I./inc
It is a bit confusing: The library is built as $LIBNAME, but then it goes on to link an executable named $NAME. So everytime you make a change to Main.cpp, the library has to be rebuilt.
Your rule for $(NAME) doesn't actually make a file called $(NAME) (i.e. hello), so make will try and remake it every time. The recipe must match the rule (and this is why you should use automatic variables as in the last example below):
all: $(LIBNAME)
$(LIBNAME): $(OBJS)
ar rc $(LIBNAME) $(OBJS)
GNU make also has built-in archive functionality, although it doesn't play well with parallel make:
ARFLAGS := rc
all: $(LIBNAME)($(OBJS))
A more idiomatic, parallel-safe way would be something like
ARFLAGS := rc
.PHONY: all
all: $(LIBNAME)
$(LIBNAME): $(OBJS)
$(AR) $(ARFLAGS) $# $^

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.

Linker command fail with a bunch of undefined reference

I try to compile a project using clang and libc++. Here is my makefile :
EXEC = ModularMadness
SRCDIR = src/
INC =-I$(SRCDIR)
SOURCES := $(wildcard $(SRCDIR)*.cpp) $(wildcard $(SRCDIR)*/*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
CXX = clang++
CXX_FLAGS = -std=c++1y -stdlib=libc++ $(INC)
all: $(EXEC)
$(EXEC): $(OBJECTS)
$(CXX) $(OBJECTS) -o $(EXEC)
%.o: %.cpp
$(CXX) -c $(CXX_FLAGS) $< -o $#
.PHONY: all clean
clean:
#echo Cleaning...
#rm -f $(EXEC) $(OBJECTS)
#echo done
The .o files creation works fine, but I ran in multiple error like
In function 'std::__1::weak_ptr<module::Module>::lock() const': undefined reference to 'std::__1::__shared_weak_count::lock()' during linker command.
Could someone help me understanding what's the problem here ?
Note
This makefile run perfectly on OS X.
I missed the linker flag -lc++... Thank you perencia.
Here is the working makefile :
EXEC = ModularMadness
SRCDIR = src/
INC =-I$(SRCDIR)
SOURCES := $(wildcard $(SRCDIR)*.cpp) $(wildcard $(SRCDIR)*/*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
CXX = clang++
CXX_FLAGS = -std=c++1y -stdlib=libc++ $(INC)
all: $(EXEC)
$(EXEC): $(OBJECTS)
$(CXX) $(OBJECTS) -o $(EXEC) -lc++ # Here
%.o: %.cpp
$(CXX) -c $(CXX_FLAGS) $< -o $#
.PHONY: all clean
clean:
#echo Cleaning...
#rm -f $(EXEC) $(OBJECTS)
#echo done

Automating my Makefile

I am learning to create a makefile. My folder structure looks like this..
Project
bin //this is where the executable "e" is kept
e
obj //this is where the obj files generated are kept
Node.o
Node1.o
src //this is where .cpp files resides
Folder
Node.cpp
Folder2
Node1.cpp
include //this is where .hhp files resides
Folder
Node.hpp
Folder2
Node1.hpp
makefile
I am using Ubuntu 12.04 and trying to compile it using g++. The makefile resides in the project folder along with folders: src, include, obj and bin
My makefile looks like this
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
TARGET = bin/
OBJ = obj/
INCLUDE = include/
SRC = src/
SOURCES=$(wildcard $(SRC)**/*.cpp $(SRC)*.cpp)
HEADERS=$(wildcard include/**/*.hpp include/*.hpp)
OBJECTS=$(patsubst %.cpp,$(OBJ)%.o,$(notdir $(SOURCES)))
All : $(TARGET)e
$(TARGET)e : make_dir $(OBJECTS)
$(CC) $(LFLAGS) $(OBJECTS) -o $#
$(OBJ)Node.o : $(SRC)Folder/Node.cpp $(HEADERS)
$(CC) $(CFLAGS) -I$(INCLUDE) $< -o $#
$(OBJ)Node1.o : $(SRC)Folder2/Node1.cpp $(HEADERS)
$(CC) $(CFLAGS) -I$(INCLUDE) $< -o $#
make_dir:
mkdir -p obj bin
clean :
-rm -rf bin
-rm -rf obj
-rm -f e *.o *~
This piece of code runs just fine but what I would like to do is to replace the below code snippets
$(OBJ)Node.o : $(SRC)Folder/Node.cpp $(HEADERS)
$(CC) $(CFLAGS) -I$(INCLUDE) $< -o $#
$(OBJ)Node1.o : $(SRC)Folder2/Node1.cpp $(HEADERS)
$(CC) $(CFLAGS) -I$(INCLUDE) $< -o $#
with some thing more like
%.o : %.cpp $(HEADERS)
$(CC) $(CFLAGS) -I$(INCLUDE) $< -o $#
Something that generalizes the whole feeding and mapping. In other words, automate the makefile in a way I shouldn't worry or edit until the hierarchy is disturbed.
$(OBJ)/%.o : $(SRC)Folder/%.cpp $(HEADERS)
$(CC) $(CFLAGS) -I$(INCLUDE) $< -o $#