makemnit

28
The Makefile utility Courtesy: UCCS

Upload: devender

Post on 12-Nov-2015

212 views

Category:

Documents


0 download

DESCRIPTION

makefile

TRANSCRIPT

  • The Makefile utilityCourtesy: UCCS

  • MotivationSmall programs single file

    Not so small programs :

    Many lines of codeMultiple componentsMore than one programmer

  • Motivation continuedProblems:

    Long files are harder to manage (for both programmers and machines)Every change requires long compilationMany programmers can not modify the same file simultaneouslyDivision to components is desired

  • Motivation continuedSolution : divide project to multiple filesTargets:

    Good division to componentsMinimum compilation when something is changedEasy maintenance of project structure, dependencies and creation

  • Project maintenanceDone in Unix by the Makefile mechanismA makefile is a file (script) containing :Project structure (files, dependencies)Instructions for files creationThe make command reads a makefile, understands the project structure and makes up the executableNote that the Makefile mechanism is not limited to C programs

  • Project structureProject structure and dependencies can be represented as a DAG (= Directed Acyclic Graph) Example :Program contains 3 filesmain.c., sum.c, sum.hsum.h included in both .c filesExecutable should be the file sum

  • Make: Header DependenciesWhat if Sensor.cc changes? Sensor.h changes?Robot.h changes?Pattern rule ignores header dependencies!Requires unnecessary make clean; makeLet gcc figure out the header dependencies for us!The MM option produces make rules in a .d file which we can then include in the MakefileSensor.hSensor.ccRobot.hRobot.ccrobotest.cc

  • makefilesum: main.o sum.ogcc o sum main.o sum.o

    main.o: main.c sum.hgcc c main.c

    sum.o: sum.c sum.hgcc c sum.c

  • Rule syntax

    main.o: main.c sum.h gcc c main.c

    tab

    dependency actionRule

  • Equivalent makefiles.o depends (by default) on corresponding .c file. Therefore, equivalent makefile is:

    sum: main.o sum.ogcc o sum main.o sum.o

    main.o: sum.hgcc c main.c

    sum.o: sum.hgcc c sum.c

  • Equivalent makefiles - continuedWe can compress identical dependencies and use built-in macros to get another (shorter) equivalent makefile :sum: main.o sum.ogcc o $@ main.o sum.o

    main.o sum.o: sum.hgcc c $*.c

  • make operation Project dependencies tree is constructedTarget of first rule should be createdWe go down the tree to see if there is a target that should be recreated. This is the case when the target file is older than one of its dependenciesIn this case we recreate the target file according to the action specified, on our way up the tree. Consequently, more files may need to be recreatedIf something is changed, linking is usually necessary

  • make operation - continuedmake operation ensures minimum compilation, when the project structure is written properly

    Do not write something like: prog: main.c sum1.c sum2.cgcc o prog main.c sum1.c sum2.c

    which requires compilation of all project when something is changed

  • Make operation - exampleFile Last Modified

    sum 10:03 main.o09:56sum.o 09:35main.c 10:45sum.c 09:14sum.h 08:39

  • Make operation - exampleOperations performed:

    gcc c main.cgcc o sum main.o sum.o

    main.o should be recompiled (main.c is newer).Consequently, main.o is newer than sum and therefore sum should be recreated (by re-linking).

  • Another makefile example# Makefile to compare sorting routines BASE = /home/blufox/baseCC = gccCFLAGS = -O WallEFILE = $(BASE)/bin/compare_sortsINCLS = -I$(LOC)/includeLIBS = $(LOC)/lib/g_lib.a \ $(LOC)/lib/h_lib.aLOC = /usr/local

    OBJS = main.o another_qsort.o chk_order.o \ compare.o quicksort.o

    $(EFILE): $(OBJS)@echo linking @$(CC) $(CFLAGS) o $@ $(OBJS) $(LIBS)

    $(OBJS): compare_sorts.h$(CC) $(CFLAGS) $(INCLS) c $*.c

    # Clean intermediate filesclean:rm *~ $(OBJS)

  • Example - continuedWe can define multiple targets in a makefileTarget clean has an empty set of dependencies. Used to clean intermediate files.makeWill create the compare_sorts executablemake cleanWill remove intermediate files

  • Passing parameters to makefileWe can pass parameters to a makefile by specifying them along with their values in the command line. For example: make PAR1=1 PAR2=soft1will call the makefile with 2 parameters: PAR1 is assigned the value 1 and PAR2 is assigned the value soft1. The same names should be used within the makefile to access these variables (using the usual $(VAR_NAME) syntax)

  • Passing parameters - continuedNote that assigning a value to a variable within the makefile overrides any value passed from the command line.

    For example: command line : make PAR=1in the makefile:PAR = 2

    PAR value within the makefile will be 2, overriding the value sent from the command line

  • Conditional statementsSimple conditional statements can be included in a makefile.Usual syntax is:

    ifeq (value1, value2)body of ifelsebody of elseendif

  • Conditional statements - examplesum: main.o sum.ogcc o sum main.o sum.o

    main.o: main.c sum.hgcc c main.c

    #deciding which file to compile to create sum.oifeq ($(USE_SUM), 1)

    sum.o: sum1.c sum.hgcc c sum1.c o $@

    elsesum.o: sum2.c sum.hgcc c sum2.c o $@

    endif

  • Make: Advanced OptionsText manipulation functions$(patsubst pattern,replacement,text)$(patsubst %.o,%.cc,)Pattern rulesUses a pattern in the target with % as wildcardMatched % can be used in dependencies as wellSimple Example:%.o : %.cc command Pattern rules with automatic variables$@ full target name$< first dependency$* string which matched % wildcardAdvance Example:%.o : %.cc $(CC) $(CCFLAGS) c $< $(INCPATHS)

  • Make: A Simple ExampleCC=g++ # Compiler to useFLAGS=-g # Compile flagsMASLAB_ROOT=maslab-software # Maslab software root directoryLIB_DIR=$(MASLAB_ROOT)/liborc # orc-related library directoryINC_DIR=$(MASLAB_ROOT)/liborc # orc-related include directoryLIBS=-lm lpthread -lorc # Library files

    all : helloworld

    helloworld.o : helloworld.cc$(CC) $(FLAGS) c $*.cc o $@

    helloworld: helloworld.o $(CC) -o helloworld helloworld.o $(LIBS)

    clean: rm -f *.o helloworld

  • Make: Example MakefileMASLABROOT = /mnt/maslab/software/maslab-software-current

    #This is the list of places to look for include filesINCPATHS = -I$(MASLABROOT)/libs/liborc \ -I$(MASLABROOT)/libs/libim \ -I$(MASLABROOT)/libs/libbotserver \ -I/opt/intel/ipp/include

    #This is the list of places to look for librariesLIBPATHS = -L$(MASLABROOT)/libs/liborc \ -L$(MASLABROOT)/libs/libim \ -L$(MASLABROOT)/libs/libbotserver \ -L/opt/intel/ipp/sharedlib

    #This is the names of the librariesLIBS = -lippipx -lippcvpx -lim -lorc -lbotserver -lm -lpthread -ljpeg -lpng

    #This is the compiler to useCC = g++

    # This is your c++ file extension (usually cc or cpp)CCEXT = cc

  • Make: Example Makefile (cont)

    CCFLAGS = -g -Wall

    # This rule builds everything. You should put the names of all your# programs in this list.all : robotest

    # This rule says how to turn any .cpp file into a .o file.%.o : %.$(CCEXT)$(CC) $(CCFLAGS) -c $< $(INCPATHS)

    #----------------------------------------------------------------------# robotest

    PROGRAM_NAME = robotestPROGRAM_OBJS = robotest.o BumpSensor.o Robot.o

    GLOBAL_OBJS += $(PROGRAM_OBJS)JUNK += $(PROGRAM_NAME)

    $(PROGRAM_NAME): $(PROGRAM_OBJS)$(CC) $(PROGRAM_OBJS) -o $(PROGRAM_NAME) $(LIBS) $(LIBPATHS)chmod a+x $(PROGRAM_NAME)

  • Extending Example Makefile

    #----------------------------------------------------------------------# Sensor Incremental Test

    PROGRAM_NAME = sensor-testPROGRAM_OBJS = sensor.t.o BumpSensor.o

    GLOBAL_OBJS += $(PROGRAM_OBJS)JUNK += $(PROGRAM_NAME)

    $(PROGRAM_NAME): $(PROGRAM_OBJS)$(CC) $(PROGRAM_OBJS) -o $(PROGRAM_NAME) $(LIBS) $(LIBPATHS)chmod a+x $(PROGRAM_NAME)

    So to add a new executable program, simply cut and paste the robotest section and enter your own PROGRAM_NAME and PROGRAM_OBJS

  • Extending example Makefile

    DEPENDS += $(patsubst %.o, %.d, $(GLOBAL_OBJS))JUNK += $(DEPENDS)include $(DEPENDS)depend : $(DEPENDS)

    depend.$(CCEXT) = set -e; $(CC) $(CCFLAGS) -MM $(DEFS) $(INCPATHS) depend.filt = sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; [ -s $@ ] || rm -f $@

    %.d: %.$(CCEXT)$(depend.cc) $< | $(depend.filt)

    #======================================================================# Miscellaneous Rules#----------------------------------------------------------------------

    # This rule cleans your directory. You could also add commands here# to remove program files and any other files that should be cleanedclean:rm -f $(JUNK) *~ *.o core.[0-9]* core

  • CMAKE: a cross platform Make

  • Build-System GeneratorProvides single-sourcing for build systemsKnowledge of many platforms and toolsUsers configure builds through a GUI

  • Source and Build TreesThe Source Tree contains:CMake input files (CMakeLists.txt)Program source files (hello.cxx)The Binary Tree (build tree) contains:Native build system files (hello.dsp)Program libraries and executables (hello.exe)Source and Binary trees may be:In the same directory (in-source build)In different directories (out-of-source build)

  • The CMake CacheRepresents build configurationPopulated by CMake codeStored in CMakeCache.txt at top of buildEntries have a type to help the GUIHolds global information for CMake codeUpdated by CMake configuration phase

  • Command Line UsageCan be used from scriptsSet current-working-directory to binary treePass path to source tree as first argumentUse -G to select build system generatorUse -D to set cache variables$ cd Foo-msvc-6$ cmake ../Foo GVisual Studio 6 DBAR:BOOL=1

  • GUI UsageEdit cache entries to configure the buildUse configure button after a changeUse OK (generate) button when finished

  • Source Tree StructureEvery directory has a CMakeLists.txt fileSubdirectories specified by SUBDIRSDirectories depend only on parentsA subset of commands are inherited

  • Writing CMakeLists.txt FilesCMake language evolved while in useScripting language with simple syntaxComments CommandsListsVariablesControl structuresProcessed during CMake configure phase# Comment ends at a newlineCOMMAND(arg1 arg2 ...)A;B;C # Semicolon-separatedIF(CONDITION)${VAR}

  • CommandsSimple syntax: Each command must start on its own lineVariable references are replaced by valuesLists in unquoted arguments are expandedArgument meanings defined by commandBoth positional and keyword arguments usedCOMMAND(ARG ARG WITH SPACES ${A_LIST} ${A_STRING})TARGET_LINK_LIBRARIES(myTarget lib1 lib2)FIND_LIBRARY(MY_LIB NAMES my1 my2 PATHS /foo /bar)

  • VariablesNamed by C-style identifierValue is always a stringNo associated typeInitialized by CMake cache entriesAssigned through commands like SETReferenced by ${VAR} (only one level)SET(A_LIST ${A_LIST} foo)SET(A_STRING ${A_STRING} bar)

  • Control StructuresIF

    FOREACH

    MACROIF(CONDITION) MESSAGE(Yes)ELSE(CONDITION) MESSAGE(No)ENDIF(CONDITION)

    FOREACH(c A B C) MESSAGE(${c}: ${${c}})ENDFOREACH(c)MACRO(MY_MACRO arg1 arg2) SET(${arg1} ${${arg2}})ENDMACRO(MY_MACRO)MY_MACRO(A B)

  • A Typical Project

  • Developer DocumentationCommand-line documentation:Run cmake --help for summaryRun cmake --help COMMAND for detailed help with a specific listfile commandTry cmake --help IFOnline documentation:http://www.cmake.org/HTML/Documentation.htmlMastering CMakePublished by Kitware, Inc.ISBN 1-930934-09-2

  • Editing CMake CodeEMACS mode for CMakecmake-mode.el located in CMake/Docs directoryProvides highlighting and indentationUse this code in your .emacs file:

    VIM mode is also available(setq load-path (cons /path/to/cmake-mode load-path))(require 'cmake-mode)(setq auto-mode-alist (append '(("CMakeLists.txt" . cmake-mode) ("\\.cmake$" . cmake-mode)) auto-mode-alist))