syntax error - makefile is missing separator -


alright stuck on , have no idea doing wrong. going great working on more complicated makefile of sudden got "missing separator" error. able isolate down simple scenario:

test.mk

define push_dir $(info ${1}) endef  define pop_dir $(info ${1}) endef  define include_submake $(call push_dir,${1}) $(call pop_dir,${1}) endef 

simple

include test.mk  initial_submake:= includeme.mk $(call include_submake,${initial_submake})  process:     @echo processed... 

and output:

c:\project>make -f simple process includeme.mk includeme.mk simple:4: *** missing separator.  stop. 

includeme.mk not exist. have no idea going wrong here have tried multitude of things. if surround call include_submake in info so:

$(info $(call include_submake,${initial_submake})) 

the missing separator error goes away. if in include_submake define call 1 of functions works fine. additionally if directly call functions instead of calling them include_submake works well:

include test.mk  initial_submake:= includeme.mk $(call push_dir,${initial_submake}) $(call pop_dir,${initial_submake})  process:     @echo processed...   c:\project>make -f simple process includeme.mk includeme.mk processed... 

i feel i'm overlooking fundamental here. help.

the missing separator error happens because of non-empty return value of include_submake, single line feed character in case. make permits whitespace characters (that is, space or tab) occur in expression not assumed part of rule or directive.

rewrite functions using plain-old make variable assignment , error should go away:

push_dir = \     $(info $1)  pop_dir = \     $(info $1)  include_submake = \     $(call push_dir,$1) \     $(call pop_dir,$1) 

upd.: define vs plain old variable assignment

answering question first comment. prefer using define directive in several cases.

using eval function

as gnu make manual suggests, define directive useful in conjunction eval function. example manual (emphasis mine):

 programs    = server client  server_objs = server.o server_priv.o server_access.o server_libs = priv protocol  client_objs = client.o client_api.o client_mem.o client_libs = protocol  # after generic  .phony: all: $(programs)  define program_template   $(1): $$($(1)_objs) $$($(1)_libs:%=-l%)   all_objs   += $$($(1)_objs) endef  $(foreach prog,$(programs),$(eval $(call program_template,$(prog))))  $(programs):     $(link.o) $^ $(ldlibs) -o $@  clean:     rm -f $(all_objs) $(programs) 

generator templates

verbatim variables fit cases when want generate file gnu make. example, consider generating header file based on information makefile.

 # args: #   1. header identifier. define header_template /* file generated gnu make $(make_version). */  #ifndef $(inclusion_guard) #define $(inclusion_guard)  $(foreach inc,$($1.includes), #include <$(inc).h>)  /* else... */  #endif /* $(inclusion_guard) */  endef  # 1. unique header identifier. inclusion_guard = \     __gen_$1_h  # shell escape. sh_quote = \     '$(subst ','"'"',$1)'  foo.includes := bar baz  headers := foo.h  $(headers) : %.h :     @printf "%s" $(call sh_quote,$(call header_template,$(*f)))> $@ 

extended make syntax

in our project use our own build system called mybuild, , implemented entirely on top of gnu make. 1 of low-level hacks used improve poor syntax of builtin language of make, have developed special script allows 1 use extended syntax function definitions. script written in make too, sort of meta-programming in make.

in particular, 1 can use such features as:

  • defining multiline functions without need use backslash
  • using comments inside functions (in plain-old make comments can occur outside variable assignment directives)
  • defining custom macros $(assert ...) or $(lambda ...)
  • inlining simple functions $(eq s1,s2) (string equality check)

this example of how function can written using extended syntax. note becomes valid make function , can called usual after call $(def_all).

 # reverses specified list. #   1. list # return: #   list elements in reverse order. define reverse     # start empty list.     $(fold ,$1,          # prepend each new element ($2)         # result of previous computations.         $(lambda $2 $1)) endef $(def_all) 

using these new features able implement cool things (well, @ least make :-) ) including:

  • object-oriented layer dynamic object allocation, class inheritance, method invocations , on
  • lalr parser runtime engine parsers generated gold parser builder
  • modelling library runtime support models generated emf

feel free use part of the code in own projects!


Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -