Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Create a Makefile from this mess

Create a Makefile from this mess

Scheduled Pinned Locked Moved C / C++ / MFC
linuxc++hostingcloudtools
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • pkfoxP Offline
    pkfoxP Offline
    pkfox
    wrote on last edited by
    #1

    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 -lcrypto

    the 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

    L K 2 Replies Last reply
    0
    • pkfoxP pkfox

      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 -lcrypto

      the 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

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      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 -lcrypto

      SOURCES = <-- 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.

      pkfoxP 1 Reply Last reply
      0
      • L Lost User

        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 -lcrypto

        SOURCES = <-- 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.

        pkfoxP Offline
        pkfoxP Offline
        pkfox
        wrote on last edited by
        #3

        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

        L 1 Reply Last reply
        0
        • pkfoxP pkfox

          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

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          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.

          pkfoxP 1 Reply Last reply
          0
          • L Lost User

            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.

            pkfoxP Offline
            pkfoxP Offline
            pkfox
            wrote on last edited by
            #5

            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 -lcrypto

            SOURCES = $(wildcard *.cpp */*.cpp)

            TARGET: callapi

            callapi: $(SOURCES)
            g++ $(SOURCES) -o $@ $(INCS) $(LIBS)

            clean:
            rm callapi

            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

            1 Reply Last reply
            0
            • pkfoxP pkfox

              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 -lcrypto

              the 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

              K Offline
              K Offline
              k5054
              wrote on last edited by
              #6

              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 -lcrypto

              SRCS = $(wildcard Source/*.cpp)
              OBJS = $(SRCS:.cpp=.o)

              ifdef DEBUG
              CXXFLAGS += -ggdb
              LDFLAGS += -ggdb
              else
              CXXFLAGS += -O2
              LDFLAGS += -O2
              endif

              callapi: $(OBJS)
              $(CXX) $(LDFLAGS) $^ -o $@

              clean:
              rm -f callapi $(OBJS)

              I've added clean and debug options to help maintain your code. To make a debug version you do

              make 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

              pkfoxP 1 Reply Last reply
              0
              • K k5054

                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 -lcrypto

                SRCS = $(wildcard Source/*.cpp)
                OBJS = $(SRCS:.cpp=.o)

                ifdef DEBUG
                CXXFLAGS += -ggdb
                LDFLAGS += -ggdb
                else
                CXXFLAGS += -O2
                LDFLAGS += -O2
                endif

                callapi: $(OBJS)
                $(CXX) $(LDFLAGS) $^ -o $@

                clean:
                rm -f callapi $(OBJS)

                I've added clean and debug options to help maintain your code. To make a debug version you do

                make 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

                pkfoxP Offline
                pkfoxP Offline
                pkfox
                wrote on last edited by
                #7

                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

                K 1 Reply Last reply
                0
                • pkfoxP pkfox

                  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

                  K Offline
                  K Offline
                  k5054
                  wrote on last edited by
                  #8

                  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 say

                  CXX=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

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups