Makefiles, what are you doing with them? 34

Posted by Brett Schuchert Wed, 27 Jan 2010 15:02:00 GMT

Half a year ago, I took some exercises written in Java and ported them to C++. At that time I punted on writing makefiles and decided to reply on an IDE (Visual Studio). That worked fine but recently we almost had a customer that was going to take this class and, bless their heart, use the command line.

Turns out they are going to use visual studio, so I can shelve this, but I figured I’d get feedback on what I have created for a makefile. Since I have not written a makefile for 12ish years, I figured things have changed. They have, but I suspect they have even more.

What follows are my environment assumptions and the makefile. I’d appreciate any suggestions.

FWIW, I wrote this makefile because it turns out fully building all files takes longer than just building what has changed. I know this seems obvious, but it is not always the case with small projects like this. There is some point where the project becomes big enough to warrant dependency-based building. The exercise meets that criteria. Sometimes the time taken to evaluate build changes is enough overhead that it can be safely removed in lieu of a full build. This is a consideration when creating custom build files for legacy-based refactoring efforts.

Environment
  • Generic Unix
  • zsh – though any shell will do really
  • g++
  • gnu make
  • This source base will still be used in Visual Studio but not this makefile
  • CppUTest used for unit testing tool
  • Provide default location for CppUTest, which can be overridden by environment variable
  • Boost library installed in /usr/local/include and /usr/local/lib (reasonable assumption or should I go ahead and allow this to be configured easily in the makefile – what’s your opinion?)
  • Project is small enough that all headers and source files are in the same directory (should I build the .o’s and put them in another directory to hide them?)
Current Makefile
ifdef CPP_U_TEST
    CppUTest_base = $(CPP_U_TEST)
else
    CppUTest_base = $(wildcard ~/src/cpputest)
endif

LIB_DIRS = -L$(CppUTest_base)/lib
INC_DIRS = -I$(CppUTest_base)/include
LIBS = -lCppUTest -lboost_date_time -lboost_regex -lboost_thread
CFLAGS = -g $(INC_DIRS) 
LDFLAGS = $(LIB_DIRS) $(LIBS)
CC = g++
SRCS := $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
OUT = run_all_tests
DEP_DIR = dependencies

all: $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUT) $(OBJS)

clean:
    @rm -rf $(DEP_DIR) $(OBJS) $(OUT)

-include $(SRCS:.cpp=$(dep_dir)/.d)

.cpp.o:
    @if [ ! -d $(DEP_DIR) ] ; then mkdir $(DEP_DIR) ; fi
    $(CC) -c $(CFLAGS) -o $@ $< 
    @$(CC) -MM $(CFLAGS) $*.cpp > $(DEP_DIR)/$*.d
Comments

Leave a response

  1. Avatar
    Ben about 2 hours later:

    We’ve moved to CMake, rather than maintaining Makefiles and vcproj files simultaneously.

  2. Avatar
    kbob about 2 hours later:

    I did a little exploratory project on makefiles a year ago. The goal was to build a makefile that (a) avoids recursive make (see Recursive Make Considered Harmful, http://miller.emu.id.au/pmiller/books/rmch/ ), and (b) minimizes the per-source and per-target noise.

    Check it out here. There’s a sample project included. git://gitorious.org/better-makefiles/mainline.git

    Try “make help” in the sample project directory.

  3. Avatar
    James about 3 hours later:

    I’m no expert, but I like the makefiles we put together for CppUTest. The idea is to setup the inputs and include a helper that has the common parts for all similar makefiles.

    #Set this to @ to keep the makefile quiet
    SILENCE = @
    
    #---- Outputs ----#
    COMPONENT_NAME = Demo
    TARGET_LIB = \
        lib/lib$(COMPONENT_NAME).a
    
    TEST_TARGET = \
        $(COMPONENT_NAME)_tests
    
    #--- Inputs ----#
    PROJECT_HOME_DIR = .
    ifeq "$(CPPUTEST_HOME)" "" 
        CPPUTEST_HOME = ../CppUTest
    endif
    
    #CFLAGS are set to override malloc and free to get memory leak detection in C programs
    CFLAGS = -Dmalloc=cpputest_malloc -Dfree=cpputest_free
    CPPFLAGS = -Wall
    #GCOVFLAGS = -fprofile-arcs -ftest-coverage
    
    #includes for all compiles
    #a list of -I's are created from these directories
    
    INCLUDE_DIRS =\
      .\
      include\
      include/*\
      $(CPPUTEST_HOME)/include/
    
    #SRC_DIRS is a list of source directories that make up the target library
    SRC_DIRS = \
        src\
        src/*
    
    #TEST_SRC_DIRS is a list of directories including 
    # - A test main (AllTests.cpp by convention)
    # - OBJ files in these directories are included in the TEST_TARGET
    TEST_SRC_DIRS = \
        tests \
        tests/*
    
    # - OBJ files in these directories are included in the TEST_TARGET
    MOCKS_SRC_DIRS = \
        mocks
    
    #Flags to pass to ld
    LDFLAGS +=
    LD_LIBRARIES += -lstdc++
    
    include $(CPPUTEST_HOME)/build/ComponentMakefile
    
  4. Avatar
    Markus Gaertner about 3 hours later:

    I see three problems in the Makefile as it is: 1. $(wildcard ~/src/cpputest) does not include a wildcard at all. So something like $(HOME)/src/cpputest makes more sense to me, leaving out the wildcard function completely. 2. In the -include statement the $(dep_dir) is in lower case, while it is defined in upper case. I think this causes you the problem with the dependencies. 3. There does not seem to be a .PHONY rule to prevent make to try to build all or clean all the time. .PHONY rules depict names of rules which don’t have a physical file or directory on the hard-drive later. Make checks changedates to determine whether to rebuild or not on non-PHONY targets. 4. There last rule ”.cpp.o” does not make sense to me. %.cpp.o would, but as it is, I don’t think it would work.

    You may want to take a look into makedepend. The source dependencies are here tracked manually in a separate directory. makedepend puts these behind the Makefile. Both approaches have pros and cons. If the dependencies do not change often, then makedepend makes sense, otherwise maybe not.

    The larger problem I have with the structure as it is, is that it seems to be complicated for me. There are some tidyings I would want to apply, like introducing a depend target to trace down the dependencies. The last target looks very dubious to me. In order to build dependencies incrementally one would need to track dependencies in a depend directory, and have objects rebuilt based on the particular changes in the source files.

  5. Avatar
    Fabian Ritzmann about 4 hours later:

    I would also recommend CMake. After 20+ years of make, it is time to evolve.

    Another tool I like for small Makefiles and even general purpose scripting is Rake. IMHO, it is the better Ruby for any script that operates on files. For a bigger system and possibly heterogeneous software, I would prefer CMake however.

  6. Avatar
    Angry Poodle about 5 hours later:

    One possibility is Boost Jam (BJam) with distcc.

  7. Avatar
    James Martin about 5 hours later:

    For small stuff I use a slightly modified version of the cpputest makefile, that James pasted above.

    For big dependency riddled stuff I like http://www.scons.org/

  8. Avatar
    Jason Y 1 day later:

    This brings back memories of my college days, before I knew to go to Google for everything I don’t know first. It seems the general recommendation of the instructors was to use the lowest-tech, most arcane tools available.

  9. Avatar
    Amal Pillai 1 day later:

    The experience with CMake (www.cmake.org) on Windows and Linux (using Boost and CppTest) was good enough to go for a complete switch.

  10. Avatar
    Patrick 2 days later:

    One tip: use ”:=” instead of ”= unless you have a really good reason to prefer deferred evaluation, or you need to support ancient versions of make. If you use” as your default, then “make -np” suddenly becomes a useful makefile debugging tool.

  11. Avatar
    Patrick 2 days later:

    One tip: use ”:=” for variable assignment unless you have a really good reason to prefer deferred evaluation, or you need to support ancient versions of make. If you use ”:=” as your default, then “make -np” suddenly becomes a useful makefile debugging tool.

    (Sorry about the formatting bug in my previous version of this post…)

  12. Avatar
    Mark 3 days later:

    I would highly recommend autotools, even for small projects (more than 3 source files). Its less arcane than writing your own makefile, with the most arcane parts being more or less boilerplate. It ends up being quite easy to maintain as the project grows and needs change, and certainly much easier than maintaining a makefile.

  13. Avatar
    Donnie 4 days later:

    I was positively amused after reading this text . After all, if you need to gain knowledge about C++ or obtain a perfect essay associated with it, visit online essay writers and make a request.

  14. Avatar
    sun@gmail.com 2 months later:

    If you are being confused by the problem that how to convert pdf file to png, PDF to PNG Converter will tell you the answer to this question with professional skills.PDF to PNG Converter is very helpful software which owns personalize design and good reputation. Of course, it is most important for the customers that PDF to PNG Convert can Convert PDF to PNG with best quality! Here, PDF to PNG Converter will make promise for you that it will bring fire-new experience to you.[url=”http://www.pdftopngconverter.com]pdf to png converter[/url]Moreover, whether you are professor or novice, PDF to PNG will let you mast it with the easiest way. You can realize “PDF to PNG” more particularly by browsing the following content. You will find that PDF to PNG Converter is really useful!

  15. Avatar
    ruthyang2@gmail.com 2 months later:

    I have read the article,it is really good !and also i like to say FLV extractor is speclially designed for windows

    users, we also developed FLV Extractor Mac version for all Mac lovers,you can have a try

  16. Avatar
    parça TL kontör 2 months later:

    I like This site! Thank you for your information…

  17. Avatar
    Blu-ray ripper mac 3 months later:
  18. Avatar
    toronto escorts 5 months later:

    That piece of code helped me a lot in a application I’m developing!

  19. Avatar
    Tax Reclaims 5 months later:

    Thanks for share this code.It will help me as well as other developer also.

  20. Avatar
    Electricians 6 months later:

    This article gives the light in which we can observe the reality.Electricians This is very nice one and gives in depth information. Thanks for this nice article Good post…..Valuable information for all.I will recommend my friends to read this for sure.

  21. Avatar
    Conversion Kits 6 months later:

    Its great to be here and i salute to the post owner to post on such this intelligent topic.

  22. Avatar
    CNC Milling 6 months later:

    i want to go with james.

  23. Avatar
    Perspex Cut To Size 6 months later:

    This code is just make me frizzed because i wanted it and i get it from here.

  24. Avatar
    Cufflinks 6 months later:

    I think the code provider is just genius and also this post owner. I will surely implement it.

  25. Avatar
    Travel Clothing 6 months later:

    If i will not reach this post then i will loss the biggest things.

  26. Avatar
    Termite Inspection 6 months later:

    I think the IT people will surely follow this post.

  27. Avatar
    Biomedical Waste Management 6 months later:

    Very technical blog.Sure it will helpful to person who is aware with this code.

  28. Thank you very much for sharing all those set of lovely and top I am newly learning the use of in and this I think would really help me in my assignments.

  29. Avatar
    buy cd’s 7 months later:

    Your post will be rather good, and I’m sure some will find it interesting because it’s about a topic that’s as widely discussed as others. Some may even find it useful.Thanks so much for your post.

  30. Avatar
    cheap vps 7 months later:

    he larger problem I have with the structure as it is, is that it seems to be complicated for me. There are some tidyings I would want to apply, like introducing a depend target to trace down the dependencies. The last target looks very dubious to me. In order to build dependencies incrementally one would need to track dependencies in a depend directory, and have objects rebuilt based on the particular changes in the source files.cheap VPS

  31. Avatar
    Free Hosting With Sitebuilder 7 months later:

    This is a very intriguing post, I was looking for this knowledge. Just so you know I found your web site when I was searching for blogs like mine, so please check out my site sometime and leave me a comment to let me know what you think.
    Free Hosting With Sitebuilder

  32. Avatar
    Free Hosting With Sitebuilder 7 months later:

    This is a very intriguing post, I was looking for this knowledge. Just so you know I found your web site when I was searching for blogs like mine, so please check out my site sometime and leave me a comment to let me know what you think.
    Free Hosting With Sitebuilder

  33. Avatar
    Dive Watch 7 months later:

    Interesting topic at interesting post.Thanks to share this knowledge at here.

  34. Avatar
    supplynflshop 7 months later:

    so good post i like it china nfl jerseys

Comments