Create a Makefile from this mess
-
Hi all, I have the following in a bash script on my debian box, it works perfectly but I would like to configure a Makefile I run this script from my project folder
g++ Source/*.cpp -o callapi \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/cpr \
-I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/ \
-L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptothe backslashes are line continuation markers
Anyone know how to put this in a Makefile ?Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
-
Hi all, I have the following in a bash script on my debian box, it works perfectly but I would like to configure a Makefile I run this script from my project folder
g++ Source/*.cpp -o callapi \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/cpr \
-I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/ \
-L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptothe backslashes are line continuation markers
Anyone know how to put this in a Makefile ?Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
You can use backslashes in the Makefile just the same. If you set all the includes into a macro it simplifies things a bit. Something like:
g++ Source/*.cpp -o callapi \
INCS = -I /home/pjk/vcpkg/packages/cpr_x64-linux/include/cpr \
-I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/LIBS = -L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptoSOURCES = <-- add the source names here - callapi.cpp etc.
TARGET: callapi
callapi: $(SOURCES)
g++ Source/*.cpp -o $@ $(INCS) $(LIBS)You may need to add the Source directory name in front of all the dependency names in the SOURCES macro, in which case the last line could be changed to
g++ $(SOURCES) -o $@ $(INCS) $(LIBS)
This is untested but broadly follows a Makefile I use in Ubuntu.
-
You can use backslashes in the Makefile just the same. If you set all the includes into a macro it simplifies things a bit. Something like:
g++ Source/*.cpp -o callapi \
INCS = -I /home/pjk/vcpkg/packages/cpr_x64-linux/include/cpr \
-I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/LIBS = -L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptoSOURCES = <-- add the source names here - callapi.cpp etc.
TARGET: callapi
callapi: $(SOURCES)
g++ Source/*.cpp -o $@ $(INCS) $(LIBS)You may need to add the Source directory name in front of all the dependency names in the SOURCES macro, in which case the last line could be changed to
g++ $(SOURCES) -o $@ $(INCS) $(LIBS)
This is untested but broadly follows a Makefile I use in Ubuntu.
Thanks Richard that will certainly get me started, what does -o $@ set the output file to ?
Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
-
Thanks Richard that will certainly get me started, what does -o $@ set the output file to ?
Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
The
$@
is one of the predefined make macros and refers to the target of the build; which should be the output file callapi. I looked at the man page for make on Ubuntu but it seems incomplete. There is (certainly used to be) a section somewhere that gives all the details on Makefile structures. -
The
$@
is one of the predefined make macros and refers to the target of the build; which should be the output file callapi. I looked at the man page for make on Ubuntu but it seems incomplete. There is (certainly used to be) a section somewhere that gives all the details on Makefile structures.With your help I've cobbled this together ( and it works :-D ) thanks again
INCS = -I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/LIBS = -L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptoSOURCES = $(wildcard *.cpp */*.cpp)
TARGET: callapi
callapi: $(SOURCES)
g++ $(SOURCES) -o $@ $(INCS) $(LIBS)clean:
rm callapiLife should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
-
Hi all, I have the following in a bash script on my debian box, it works perfectly but I would like to configure a Makefile I run this script from my project folder
g++ Source/*.cpp -o callapi \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/cpr \
-I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/ \
-L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptothe backslashes are line continuation markers
Anyone know how to put this in a Makefile ?Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
If you are interested in using the power of make to only compile modified sources that are newer than the target you should be able to do something like this
CPPFLAGS = -I /home/pjk/vcpkg/packages/cpr_x64-linux/include/cpr \
-I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/LDFLAGS = -L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptoSRCS = $(wildcard Source/*.cpp)
OBJS = $(SRCS:.cpp=.o)ifdef DEBUG
CXXFLAGS += -ggdb
LDFLAGS += -ggdb
else
CXXFLAGS += -O2
LDFLAGS += -O2
endifcallapi: $(OBJS)
$(CXX) $(LDFLAGS) $^ -o $@clean:
rm -f callapi $(OBJS)I've added
clean
anddebug
options to help maintain your code. To make a debug version you domake DEBUG=1
Note that
$CPPFLAGS
and$CXXFLAGS
are standard make variables and will be expanded when trying to compile the individual object files, without us having to explicitly tell make to do so. If you don't want the object files mixed in the source directory, look into using$(patsubst)
[Text Functions (GNU make)](https://www.gnu.org/software/make/manual/html\_node/Text-Functions.html#Text-Functions) and/or other make functions to manipulate targets. With some fancy footwork you could also get debug and production objects built at the same time, but I'll leave that as an exercise for the reader!Keep Calm and Carry On
-
If you are interested in using the power of make to only compile modified sources that are newer than the target you should be able to do something like this
CPPFLAGS = -I /home/pjk/vcpkg/packages/cpr_x64-linux/include/cpr \
-I /home/pjk/C++/CallCommandsAPI/Headers/ \
-I /home/pjk/vcpkg/packages/rapidjson_x64-linux/include/ \
-I /home/pjk/vcpkg/packages/cpr_x64-linux/include/LDFLAGS = -L /home/pjk/vcpkg/packages/cpr_x64-linux/lib/ \
-lcpr -lcurl -lpthread -lssl -lcryptoSRCS = $(wildcard Source/*.cpp)
OBJS = $(SRCS:.cpp=.o)ifdef DEBUG
CXXFLAGS += -ggdb
LDFLAGS += -ggdb
else
CXXFLAGS += -O2
LDFLAGS += -O2
endifcallapi: $(OBJS)
$(CXX) $(LDFLAGS) $^ -o $@clean:
rm -f callapi $(OBJS)I've added
clean
anddebug
options to help maintain your code. To make a debug version you domake DEBUG=1
Note that
$CPPFLAGS
and$CXXFLAGS
are standard make variables and will be expanded when trying to compile the individual object files, without us having to explicitly tell make to do so. If you don't want the object files mixed in the source directory, look into using$(patsubst)
[Text Functions (GNU make)](https://www.gnu.org/software/make/manual/html\_node/Text-Functions.html#Text-Functions) and/or other make functions to manipulate targets. With some fancy footwork you could also get debug and production objects built at the same time, but I'll leave that as an exercise for the reader!Keep Calm and Carry On
Thanks for this, one question, where is CXX defined ?
Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
-
Thanks for this, one question, where is CXX defined ?
Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
CXX is defined in the bowels of
make
somewhere. It is the default variable for the C++ compiler, and is used in the rules for constructing default recipes. So for example, suppose you had an otherwise empty directory with only one file, hello.cpp, in it. Without needing to create a Makefile, you can build the hello executable just by saying "make hello". There's default rules for all kinds of things, C, Fortran, ranlib (.a) libraries, yacc, tex, and on and on. You can get a list of available recipes by saying "make -p", which for my version of make produces 1357 lines of output. The CXX variable can be overridden by specifiying a shell variable of the same name at run time, so if for example you wanted to see what error messages clang++ spits out instead of g++ you can sayCXX=clang++ make target
Similarly you have CXXFLAGS and CPPFLAGS which pass arguments to the C++ compiler and the CPreProcessor, respectively. So you could say
CXX=clang++ CPPFLAGS="-I /path/to/includs" CXXFLAGS="-O2 -Wall -Wextra" LDFLAGS="-L /path/to/lib" LDLIBS="-lmylib1 -lmylib2" make hello
and
make
will apply the variables to the generated command line as expected, and produce:clang++ -O2 -Wall -Wextra -I /path/to/includs -L /path/to/lib hello.cc -lmylib1 -lmylib2 -o hello
gnu make hack: You can rebuild everything from scratch, even if already compiled, without having to "make clean" by using the -B flag It should also be noted that the Makefile I provided earlier uses GNU makeisms e.g.
$(wildcard),$(patsubst)
. If you find yourself on a BSD or other unix like system that does not have GNU tools installed, the given make file will fail. But the variable substitutions mentioned here will still work.Keep Calm and Carry On