pathsubst with wildcard appearing 2 times - makefile

I want to replace a string like this
OntVeip -> ManagedObjects/OntVeip/OntVeipConfigDef.xml
so logically to me this is like :
% -> ManagedObjects/%/%ConfigDef.xml
If I try to do this with pathsubst, the % is only replaced once
ie
ManagedObjects := OntVeip OntMoca
XMLSOURCES := $(patsubst %,ManagedObjects/%/%ConfigDef.xml,$(ManagedObjects))
does not work as I was hoping for.
How can I achieve the result I am after ?

Liberally stolen adapted from here
XMLSOURCES := $(foreach obj,$(ManagedObjects),ManagedObjects/$(obj)/$(obj)ConfigDef.xml)

Related

makefile variable automatically assignment with index

I have a question about variable assignments in makefile.
given 2 lists of the same size as below :
(there are no any characters or string match between 2 lists)
index := 1 2 3 4 5
objects := one_obj two_obj three_obj four_obj five_obj
and I need some index to be active, for example, 1 and 3
act_idx := 1 3
all :
#echo act_obj = $(act_obj)
how should I assign $(act_obj) to get the output as "act_obj = one_obj three_obj" after I type "make all" in shell ?
Something like this should do the trick:
act_obj := $(foreach I,$(act_idx),$(filter $I_%,$(objects)))
Based on the adjusted question you can do something like this:
act_obj := $(foreach I,$(act_idx),$(word $I,$(objects)))
You can probably work this out yourself from the set of functions described in the GNU make manual.
The GNUmake library at https://github.com/markpiffer/gmtt was originally written with this exact use case in mind (it grew into a everything-but-the-kitchen-sink, but oh well).
The formulation for the selection process which you are basically needing here is done with the relational table idiom. You produce a table as GNUmake string list and execute a select statement which mimicks a simple SQL select.
include gmtt/gmtt.mk
# define a table with 2 columns (no empty cells allowed!)
define object_tbl :=
2
key1 one_obj
key2 two_obj
key3 three_obj
key4 four_obj
key5 five_obj
endef
act_keys := key1 key3
# SELECT column 2 FROM object_tbl WHERE column 1 is found in act_keys
objects := $(call select,2,$(object_tbl),$$(filter $$1,$(act_keys)))
$(info $(objects))
Output:
one_obj three_obj
make: *** No targets. Stop.
More complex clauses (using arithmetic e.g.) are also possible.

When do we use := and when do we use = in GNU makefile?

What are the scenarios , where = is preferred over := ?
What are the scenarios, where := is preferred over = ?
I read from gnu site, that usage of = makes make run slower. I just wonder, when do we use = in makefile?
To answer your question, = is used when you want to delay expansion of the right side until the variable is used.
This allows you to define variables in any order. It also allows you to create variables with values that refer to automatic variables (remember automatic variables have no value until the rule is being run). So for example:
my_FLAGS = -a
your_FLAGS = -b
FLAGS = $($#_FLAGS)
my your : ; #echo $(FLAGS)
this cannot work if you use := because when the FLAGS variable is defined, $# has no value.
They are also useful when defining user-defined functions that can later be invoked with $(call ...); you don't want those to be expanded until they are called.
With simply defined variables you can do things like recursively use the variable:
ITEMS := one two three
ITEMS := $(addsuffix $(ITEMS))
This is because the simple assignment (:=) happens in the order you read them
Non simple assignment (=) is recursively expanded so if you assign it to other variables they are in turn expanded until you end up with the final result that contains all the expanded parts. Note that the makefile first parses the file so that the order you do the assignment is not so important, examples to follow:
i.e. this is not allowed:
ITEMS = one two three
ITEMS = $(addsuffix $(ITEMS))
So this affects when you want to use each type. With non simple you can do:
ITEMS1 = a b c
ITEMS_all = $(ITEMS1) $(ITEMS2)
ITEMS2 = d e f
And now ITEMS_ALL will contain a b c d e f - even though they are not defined in order, this can be very useful. So if you just want to assign a simply value - stick with := if you want to keep adding things to a variable you might want to use =...

Deferred assignment in makefile with one round of expansion

This may be a very esoteric question, but it's a larger problem that boils down to this. There is a global variable keeping track of state (in this case it's NUM), that is changing. The problem is I need to do a deferred assignment (to LIST) but I need the current value of NUM to be expanded.
NUM := ONE
LIST = three four $(VAR_$(NUM))
NUM := TWO
VAR_ONE := SUCCESS
VAR_TWO := FAILURE
$(info LIST => $(LIST))
$(info LIST VALUE => $(value LIST) )
This results in:
LIST => three four FAILURE
LIST VALUE => three four $(VAR_$(NUM))
What I would like to see:
LIST => three four SUCCESS
LIST VALUE => three four $(VAR_ONE)
I have a very cumbersome solution, which I'll post below, but if there is a simpler solution I would be glad to hear it.
Thank you.
My (pretty ugly) solution is to use a macro to construct the assignment, to force one round of expansion:
define append_deferred
$(1) += $(2)
endef
NUM := ONE
LIST = three four
$(eval $(call append_deferred,LIST,$$(VAR_$(NUM))))
NUM := TWO
VAR_ONE := SUCCESS
VAR_TWO := FAILURE
$(info LIST == $(LIST))
$(info LIST VALUE == $(value LIST) )
This prints the desired result:
LIST => three four SUCCESS
LIST VALUE => three four $(VAR_ONE)
But I'm wondering if there is a better way.

Format TeXForm at several levels

In Mathematica, Format can be used to alter the output formats like TeXForm, OutputForm or TraditionalForm.
This is an example of how one can redefine the TeXForm of a function T.
In[1]:= Format[T[a_], TeXForm] := "\[Del]" a
The result is
In[2]:= TeXForm[T[x]]
Out[1]= x \nabla
This is what I expected. Now apply the same format on T[T[x]]
In[3]:= TeXForm[T[T[x]]]
Out[2]= \nabla T(x)
However, the output I would like is
Out[2]= \nabla \nabla x
Why does Mathematica not give this output? And what can I change to get this as output?
I tried to find more information about formatting in the Mathematica Help and on Stack Overflow, but I could not find many clues.
It will work if you don't restrict to TeXForm.
In[100] := Format[T[a_]] := \[Del] a
In[101] := TeXForm[T[T[x]]]
Out[101]//TexForm =
\nabla \nabla x
Why use T when you could use Del?
In[7] := Del[a]
Out[7] = ∇a
In[8] := TeXForm[Del[Del[a]]]
Out[8]//TeXForm =
\nabla \nabla a
You may want to do the formatting manually.
myTeX = TeXForm[# /. T -> (Row[{"\[Del]", #}] &)]&;
T[T[a]] //myTeX
\n abla \n abla a
The reason this fails is that the Format[arg, TeXForm] pattern doesn't recursively distribute Format over the arguments. This isn't unusual. Consider:
Clear[f];
f[T[a_]] := "\[Del]" a;
yields f[T[T[a]]] = "\[Del]" T[a], but
Clear[f];
f[T[a_]] := "\[Del]" f[a];
yields f[T[T[a]]] = ("\[Del]")^2 f[a], which is closer to what you want.
So define
Format[T[a_], TeXForm] := f[T[a]]
using the second choice of f[T[a_]] above, and you'll be off to a good start.
Type the following:
Needs["Notation`"]
ESCAPE notation ESCAPE
(or choose "Notation" from the palette that opens when you load the package)
In the first placeholder, insert
ESCAPE del ESCAPE a_
In the second placeholder, enter
T[a_]
Before the closing bracket of the Notation line, insert the option
, WorkingForm -> TraditionalForm
Now you can try your example:
T[T[a]]//TeXForm
and it should give you what you want, except with parentheses (which is advisable in order to maintain your sanity in most cases, anyway):
\nabla (\nabla a)
You may be able to go further by looking at the Help documents under "Notation/tutorial/OptionsAndAuxiliaryFunctions"

Is it possible to rename and block built-in functions temporarily?

I wish to temporarily rename a built-in symbol and use it with different name while block the main name of this symbol. For example, I wish the following code to print only "2" but not "1" and "3":
Block[{print = Print, Print}, Print[1]; print[2]; Print[3];]
In really the above code prints nothing.
Is it possible to make print working inside such code while completely block symbol Print?
Solutions like
With[{Print = f, print = Print}, Print[1]; print[2]; Print[3];]
are not suitable since Print is not really blocked inside such code.
The question appeared while thinking on a way to disable tracing of Message internals.
This is not very clean, but I believe it is serviceable.
Internal`InheritedBlock[{Print},
Unprotect[Print];
Print[x__] := Null /; ! TrueQ[$prn];
print[x__] := Block[{$prn = True}, Print[x]];
Print[1]; print[2]; Print[3];
]
If it is not acceptable to have the function replaced with Null in the return, you may need to use something like:
func[x__] := Hold[func[x]] /; ! TrueQ[$prn];
Followed by a ReleaseHold after the Block.
Or:
func[x__] := zz[x] /; ! TrueQ[$prn];
and then follow the Block with: /. zz -> func

Resources