mozilla
Your Search Results

    Makefiles - Best practices and suggestions

    • Laundry list
      • makefiles should remove all content that it will generate.
      • prefer library rules whenever possible or create library rules that are missing.
      • dependency builds - A second invocation of make within a sandbox should always be a NOP.
      • hardcoded values - avoid them like the plague.  Use variable assignments, autogen paths and dynamic file gathering.
      • platform specific - avoid this logic whenever possible.
        • Code as little platform specific logic within a makefile as possible, a conditional and compiler flags at most should be needed.  For ex use defines within sources to shift platform logic into your source code.
        • If a unit test is platform specific write your makefile so it can be used on all platforms but only do work on the specific hardware or class of hardware.
        • For classes of hardware (unix/windows) place your makefile in a subdirectory, unix/Makefile.in
    • Always include dependencies when creating a target
      • Initial make call should always be the workhorse: build, generate, deploy, install, etc.
      • All subsequent make calls must become a NOP unless sources or dependencies change or have been removed.
      • Incorrect dependencies will contribute to wasted cycles and can contribute to circular dependencies.
    • Directory dependencies
      • Do not use directories as a dependency for generated targets, ever.  Any activity within a directory will alter inodes forcing targets to always be stale.
        • For ex, individual unit tests would invalidate all prior test activity whenever a test touched a timestamp file in the directory to signal success.
      • Parallel make: add an explicit timestamp dependency (.done) that make can synchronize threaded calls on to avoid a race condition.
    # Transient directory for storing timestamps
    TS=.ts
    
    #####################################################
    ## Extra dep needed to synchronize parallel execution
    #####################################################
    $(TS): $(TS)/.done
    $(TS)/.done:
      $(MKDIR) -p $(dir $@)
      touch $@ 
    
    #  "clean" target
    GARBAGE_DIRS += $(TS)
    
    • Maintain clean targets - makefiles should be able to remove all content that is generated so "make clean" will return the sandbox/directory back to a clean state.
    targets = foo bar tans
    timestampDIR = .ts
    
    all: $(timestampDIR) $(targets)
    
    %: %.c
        $(CC) -o $@ $<
    
    $(timestampDIR):
        $(MKDIR) $@
    
    # "clean" target
    GARBAGE += $(targets)
    GARBAGE_DIRS += $(timestampDIR)
    
    • Wrapper check/unit tests with a ENABLE_TESTS conditional so tests can be disabled on demand.
    ifdef ENABLE_TESTS 
        ifeq ($(NULL),$(filter WINNT OS2,$(OS_ARCH)))
            DIRS += test 
        endif # WIN
    endif # ENABLE_TESTS
    

    Document Tags and Contributors

    Contributors to this page: lahabana, Joey Armstrong
    Last updated by: lahabana,