help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ifeq and ifneq and/or help


From: Paul D. Smith
Subject: Re: ifeq and ifneq and/or help
Date: Wed, 29 Mar 2006 09:56:23 -0500

%% "PATTON, BILLY \(SBCSI\)" <address@hidden> writes:

  pb> I need to make some decision on how to load some files.
  pb> I have 6 flows: build, refresh, linktree, clean, depend and product
  pb> I have 6 files: make.<flow> that contain foreach loop that use evals to
  pb> create targets on the fly.

  pb> Loading the 6 files takes just a little more than 10 minutes.  They
  pb> create 72k + targets.  Not all these targets are necessary.
  pb> Examples of make and what they need

  pb> make           < needs build linktree and product
  pb> make build     < needs build
  pb> make refresh   < needs build and refresh
  pb> make clean     < needs clean
  pb> make depend    < needs build linktree depend
  pb> make linktree  < needs build linktree
  pb> make anything that doesn't begin with the named 6 needs build refresh
  pb> and product
  pb> it is possible to do a 
  pb> make build+ldb+bb+topic  < needs build
  pb> make ldb < needs build refresh and product

  pb> Since I have been unable to get the gmsl or to function as the examples
  pb> are I need to do the and/or in another method.  This is where I need
  pb> help.  I don't want to load the file multiple times.

First, you should use $(filter ...) rather than $(findstring ...) to
match rules, since filter matches entire words whereas findstring
matches substrings.


There are two ways to go.  One, you can use the old "multiple inclusion
guard" trick from the C preprocessor; define a variable in each makefile
and test for it to avoid multiple inclusion.  This would be something
like:

  # "make"
  ifeq (,$(MAKECMDGOALS))
    ifndef __make.build
      include make.build
    endif
    ifndef __make.linktree
      include make.linktree
    endif
    ifndef __make.product
      include make.product
    endif
  endif

  # "make build"
  ifeq (build,$(filter build,$(MAKECMDGOALS)))
    ifndef __make.build
      include make.build
    endif
  endif

  # "make refresh"
  ifeq (build,$(filter refresh,$(MAKECMDGOALS)))
    ifndef __make.build
      include make.build
    endif
    ifndef __make.refresh
      include make.refresh
    endif
  endif

  # "make clean"
  ifeq (clean,$(MAKECMDGOALS))
    include make.clean
  endif

etc.  Then inside each make.xxx you'd add:

  __make.xxx = 1

or whatever.  Now each file is included only once but all the files you
need for any target on the command line will be included.  You can also
put the ifdef inside the makefile itself which looks cleaner at the top
level, at the expense of reading the included makefile (but nothing will
be evaluated inside the ifndef):

  # "make"
  ifeq (,$(MAKECMDGOALS))
    include make.build
    include make.linktree
    include make.product
  endif

Then inside each one:

  ifndef __make.build
  __make.build = 1

    ...

  endif


The alternative is to use $(filter ...) as a poor-man's OR, but it's not
quite flexible enough for everything; you'll have to handle the empty
list and the non-standard list separately.

Something like:

  # "make.build" is needed for all targets other than clean
  ifneq (clean,$(MAKECMDGOALS))
    include make.build
  endif

  ifeq (,$(MAKECMDGOALS))
    # Just "make" needs "build" "linktree" "product"
    # "build" is done above
    include make.linktree
    include make.product
  else
    # Some other target needs "build" "refresh" "product"
    # "build" is done above
    ifeq (,$(filter build refresh clean depend linktree,$(MAKECMDGOALS))
      include make.refresh
      include make.product
  endif

  # "make.refresh" is needed for refresh
  ifneq (,$(filter refresh,$(MAKECMDGOALS)))
    include make.refresh
  endif

  # "make.clean" is needed for clean
  ifneq (,$(filter clean,$(MAKECMDGOALS)))
    include make.clean
  endif

  # "make.linktree" is needed for "depend" "linktree"
  ifneq (,$(filter depend linktree,$(MAKECMDGOALS)))
    include make.linktree
  endif

  # "make.depend" is needed for "depend"
  ifneq (,$(filter depend,$(MAKECMDGOALS)))
    include make.depend
  endif



One thing you might do is step back for a minute and ask yourself if you
can make use of pattern rules.  A single pattern can replace a lot of
explicit rules, and save a ton of time during the parsing of makefiles
and a ton of memory storing all those explicit rules, if the targets and
prerequisites can be expressed that way.

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.paulandlesley.org
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist




reply via email to

[Prev in Thread] Current Thread [Next in Thread]