how to use a "-define" parameter of makefile in systemverilog testbench? - makefile

Using the "make" command a define is done which looks like this:
make something -define "file=$(name)"
How can I use this define in my System verilog testbench?

You will need to convert this to a +define switch when you invoke your compiler. For example, with modelsim/questa
vlog +define+file=\"$(file)\" .....
You may have to play around with how the quotes get through depending on the shell you are using.

Related

Accessing gnu make options

I'd like to make part of a makefile's execution conditional on whether -B was used when calling make (ie, full recompilation).
Is there a way to access this argument from within MAKE?
Thanks!
Use the MAKEFLAGS variable. The following code fragment runs if -B was passed as an argument.
ifeq (B,$(MAKEFLAGS))
#echo Do something
endif

In makefile, how to store multi-line shell output in variable

I have a shell command where it outputs multiple lines. I want to store it in a variable in makefile for later processing in the target.
A simplified example:
I have this file called zfile1
#zfile1
some text
$echo 123
more text
$$$#&^$
more text
The makefile:
a:
#$(eval v1 = $(shell cat zfile1))
# need to process the variable here, example:
#echo "$(v1)"
# I want to prevent expansion of values in the file and print in multi-line
If you have GNU make 4.2 or above you can use the $(file <zfile1) function. See https://www.gnu.org/software/make/manual/html_node/File-Function.html
If you don't have a new-enough version of GNU make, you can't do it. Of course in your example there's no real need to put the contents of the file into a make variable at all: you can just have your recipe use the file itself. But maybe your real use-case isn't so simple.
ETA
You should never use either the make function eval or the make function shell in a recipe [1].
You can just write:
v1 := $(file <zfile1)
.ONESHELL:
a:
#echo "$(v1)"
You must have the .ONESHELL because otherwise each line of the recipe (after it expands into multiple lines) is considered a separate recipe line. Note that .ONESHELL is in effect for the entire make process so could cause other recipes to break if they rely on each line being invoked in a different shell.
Another option is to export the result into the environment, and use a shell variable like this:
export v1 := $(file <zfile1)
a:
#echo "$$v1"
There are probably better ways to do it but since you've only given us this example and not what you really want to do, that's about all we can say.
[1] There are times where it can be useful but if you have a sufficiently sophisticated requirement to need this you'll probably know how to use it.
I think you're making things too complicated.
Start by writing your recipes as proper self-contained shell scripts.
You can then either store the whole script in a file and run it from make, or you can include it directly in your makefile as a single logical line, as in the following:
a:
#v1=$$(< zfile1); \
echo $$v1
Note the need to "escape" the dollar sign by repeating it.
You could also use global make variables, depending on the actual logic of your real-world use.

Variables in makefiles (How to use arrays)

I have compiler flag in a makefile which looks like:
MYVARIABLE1=HELLO 4.5.6
MYVARIABLE2"="{0x95,0x04,0x05,0x06,' ','A','A'}"
CFLAGS+=-DMYVARIABLE2=${MYVARIABLE2}
which works fine. But if I want to use already known info in VARIABLE1 to create VARIABLE2:
MYVARIABLE1=HELLO 4.5.6
MYVARIABLE2"="{0x95,$(MYVARIABLE1[7]},$(MYVARIABLE1[9]},$(MYVARIABLE1[11]},' ','A','A'}"
CFLAGS+=-DMYVARIABLE2=${MYVARIABLE2}
But when I run my makefile with the second option, It stops compile at the c-file using the CFLAG with the error message:
error: expected expression before ',' token
in the C-code:
uint8 OTHERVARIABLE[] = MYVARIABLE2;
Question: Is the really $(MYVARIABLE1[x ]}the correct way of using parts of a variable defined in the makefile?
There is no such thing as an "array" or list variable in make syntax.
There are some GNU make functions which will operate on every word of a string, one at a time, where a word is a space-separated value. This can be thought of as an array, kind of. This is why make has an almost impossible time dealing with paths containing whitespace.
If you're not using GNU make, then none of this will work.
To do what you want you'll have to split the MYVARIABLE1 value into separate words, then you can access individual words using functions. Something like this will work:
MYVARIABLE1 = HELLO 4.5.6
__var1 = $(subst ., ,$(MYVARIABLE1))
MYVARIABLE2 = "{0x95,$(word 2,$(__var1)),$(word 3,$(__var1)),$(word 4,$(__var1)),' ','A','A'}"
The subst function replaces the . with spaces, giving a result of HELLO 4 5 6 so that you can reference the parts of the version individually using the word function.
You can find out more about GNU make functions in the documentation.
Is the really $(MYVARIABLE1[x]} the correct way of using parts of a variable defined in the makefile?
It is valid bash syntax, but not valid GNU make syntax.

GCC linker : passing multiple --wrap=<function>

I am adding quite a few mocks, using cmocka, which require me to alias them using the GC Clinker opetion --wrap=
I am passing a linker option of the format
-Wl,--wrap=foo,--wrap=bar,--wrap=baz,--wrap= ...
Is there any way to shorten it?
-Wl,--wrap=foo,bar,baz,... did not work. Any suggestions?
Is there any way to shorten it?
No.
Why would you want to? If you care about the length of the resulting command line, note that GCC supports response files:
echo "-Wl,--wrap=foo,--wrap=bar,--wrap=baz,--wrap=..." > cmd
gcc #cmd ...

Using Condition statements with Makefile targets

Hello i'm trying to use condition statements in my makefile to have it execute different make targets, but it skips over the condition and goes right to the else.
He's a general example of what i'm trying to do
ifdef ($(RUN_TEST))
all: install run uninstall
else
all: install uninstall
endif
You did not indicate on what system you are running the Makefile, as there are slightly differing make programs available. Make can be run on linux and windows and comes in different variants.
However, I have worked with most variants, and there is a common way you can resolve your problem. You have to realise that the makefile is not a program executed in the conventional sequential manner. It is a series of declarations or definitions of actions to be performed at some future time. You cannot read through it in a sequential manner like a program. In particular the definitions of dependencies are not executed and cannot be embedded within statements, even pre-processed statements.
The best way to achieve what you want it to put the dependencies in a variable and set that variable conditionally, like this:
if ($(RUN_TEST))
ALL=install run uninstall
else
ALL=install uninstall
endif
all : $(ALL)
This should work on most implementations.
The GNU make ifdef operation takes the name of a variable to test; you are providing it the expansion of a variable. You want to write it like this:
ifdef RUN_TEST
ALL = install run uninstall
else
ALL = install uninstall
endif
By using $(RUN_TEST) you're actually testing a variable named by the expansion of RUN_TEST. So for example if RUN_TEST is set to true, then ifdef $(RUN_TEST) actually tests to see if the variable true is defined or not.

Resources