I have written a Makefile to run tests in questasim. I am using the following commands.
vsim -l transcript -voptargs=+acc test -do $(WAVEDIR)/$(WAVE_FILE)
This helps to open the questa window and simulate the test case. With thin the questa console,I need to run "run -a" so that the complete test execution.
Is there any command which I can add inside my Makefile which will execute the testcase without using the questa console command.
Thanks in advance
Regards
S
Simply add a second -do option:
vsim -l transcript -voptargs=+acc test -do $(WAVEDIR)/$(WAVE_FILE) -do 'run -all'
Side note: be careful when using make with Modelsim or Questa. These tools are not parallel safe. If you try to run several compilations in parallel you will probably corrupt your target libraries and get strange errors.
So, if you use make to also compile, create the libraries, etc. you must guarantee that make will not try to launch in parallel several jobs modifying the same library or the same configuration file (e.g. modelsim.ini). With GNU make always add the .NOTPARALLEL: special target to your Makefiles (there are smarter and more efficient ways to handle this parallel problem with locks but this is out of scope).
Here I am posting the Makefile example below.
TEST = test_top_0006
WAVE_FILE = wave_test0006.do
PREFIX = europractice questa 10.6c
RTLDIR = ..
WAVEDIR = waves
TRANSCRIPT_FILE = transcript
GITBRANCH = feature
VSIM = $(PREFIX) vsim
VLOG = $(PREFIX) vlog
VCOM = $(PREFIX) vcom
VLIB = $(PREFIX) vlib
VLOG_OPTS = -suppress vlog-2583 +acc
compile: rtl tb
# compile all spu sources
spu = $(RTLDIR)/rtl/opcodeDefs_pkg.sv \
$(RTLDIR)/rtl/au/fp_pkg.sv \
$(RTLDIR)/rtl/spu.sv \
$(RTLDIR)/rtl/spu_top.sv
rtl:
if [ ! -d work ]; then $(VLIB) work; fi
${VLOG} -lint -work ${VLOG_OPTS} ${spu}
# compile verification environment
tb:
if [ ! -d work ]; then $(VLIB) work; fi
$(VLOG) $(VLOG_OPTS) $(RTLDIR)/rtl/typedefs_pkg.sv
$(VLOG) $(VLOG_OPTS) $(RTLDIR)/rtl/harness.sv
if [ ! -e "${TEST}.sv" ]; then false; fi
${VLOG} $(VLOG_OPTS) ${TEST}.sv
# run simulator in GUI mode
run:
${VSIM} -l $(TRANSCRIPT_FILE) test -do $(WAVEDIR)/$(WAVE_FILE) -do 'run -all'
runc: tb
${VSIM} -c -l $(TRANSCRIPT_FILE) -voptargs=+acc test -do $(WAVEDIR)/nogui.do
# GIT commands
push:
git push origin $(GITBRANCH)
pull:
git pull
commit:
git commit -a
stat:
git status
clean:
rm -rf work
rm -rf vsim.wlf
rm -f $(TRANSCRIPT_FILE)
Related
Thanks for all your time and response -
Currently, we are using the nested build, multiple Makefiles, and individual subdirectories having their own Makefile, all are connected with a top-level Makefile. We are running
make xxxxx_yyyy_defconfig
make
this builds and creates an output file which is xxxxx.elf file. --- Till here everything works fine.
Now we are having multiple def-configs(around 50), I want to build all configurations using one "make all" command. is that possible?
This is not a simple case where we can put all "all: prog01 prog02 prog03" as every program needs to have a different configuration. Configuration can be achieved by using "make xxxxx_yyyy_defconfig". The output of "make config" is the .config file, which is used during the "make" command.
Based on .config file many variables are exported which is used at the subdirectory level.
So How can I build multiple configurations using a single "make all" command?
Environment - Ubuntu, Cross compile for ARM, output file xxxx.elf.
With the use of script and make file I am able to solve, But I have to solve only using Makefile.
in Makefile add one PHONY target
all:
./build_all.sh #shell script calling.
Created one shell script like this
#! /usr/bin/bash
echo "Make All"
for entry in `ls conf`; do
make $entry
wait
make
if [ $? -eq 0 ] ; then
for xxxfile in `ls xxx*_*` ; do
xxxdir=$(echo $xxxfile | cut -b yy-zz)
mkdir -p $xxxdir
mv $xxxfile $xxxdir/
done
else
break
fi
done
If you want to build several configurations you must do this out of tree in separate build directories (make O=/tmp/builds/foo foo_defconfig; make -C /tmp/builds/foo) to avoid conflicts. A shell script could do this as well as a Makefile but if you insist on using a Makefile you could try the following that assumes your source tree is in /src/kernel and you want to build configuration foo in /tmp/builds/foo; adapt to your needs:
$ pwd
/tmp/builds
$ cat Makefile
CONFIGS := uuuu_vvvv xxxx_yyyy ...
BUILD := /tmp/build
KERNEL := /src/kernel
.PHONY: $(CONFIGS) all
all: $(CONFIGS)
$(CONFIGS):
rm -rf $#
mkdir -p $(BUILD)/$#
$(MAKE) -C $(KERNEL) O=$(BUILD)/$# $#_defconfig
$(MAKE) -C $(BUILD)/$#
$ make
I'm writing some Makefile. There is a file auto that can be processed in automatic way (build by make). There is recipe for it. So, this file needs to be edited manually and saved as manual. This manual is used for further automatic processing. How can I achieve the next:
If auto is not exists --- build it --- done by the recipe for it.
If manual is older than auto --- print a message and exit make.
If manual is newer --- build further --- done by the recipe for it.
How can the second step be done in some native way?
EDIT
The process description was not clear enough because I had no understanding how it should be. That was my mistake. Here is the process I assume.
There is source.
The auto can be built automatically from source.
The manual can be made manually from auto.
The result can be built automatically from manual.
Going 1->2 and 3->4 is what is make for.
The manual depends on source. But make itself can't build manual but only auto to help the user. So, if the manual is up-to-date (newer than source), then just build result from it.
But if manual is have to be rebuilt (it is older than source), rebuild auto (if needed), print a message and stop.
So, I think that Makefile should looks like:
SOURCE = source
result : manual ; cp manual result
manual : auto $(SOURCE) ; #echo "CREATE $#"
auto : $(SOURCE) ; cp source auto
But making result I have to stop after manual and let user to create it and run make again. The manual will be newer than source and auto and will not have to be rebuilt. But how can I do this?
The easiest is probably to describe your dependencies as they really are, even if you cannot really build manual with a make recipe. Then, for manual, instead of writing a building recipe, just print your message and exit with a non-zero status. If manualdoes not exist or is out of date, make will print the message and stop before trying to (re)build result:
# Makefile
result: manual
cp -f "$<" "$#"
manual: auto
#echo "CREATE $#"
#exit 1
auto: source
cp -f "$<" "$#"
Demo:
$ rm -f auto manual result source
$ touch source
$ make
cp -f "source" "auto"
CREATE manual
make: *** [Makefile:6: manual] Error 1
$ touch manual
$ make
cp -f "manual" "result"
$ make
make: 'result' is up to date.
$ touch source
$ make
cp -f "source" "auto"
CREATE manual
make: *** [Makefile:6: manual] Error 1
If you don't like the error situation you can defer the stop to the result recipe:
# Makefile
result: manual
[ -f "$#" ] && cp -f "$<" "$#" || true
manual: auto
#echo "CREATE $#"
auto: source
cp -f "$<" "$#"
Demo:
$ rm -f auto manual result source
$ touch source
$ make
cp -f "source" "auto"
CREATE manual
[ -f "manual" ] && cp -f "manual" "result" || true
$ touch manual
$ make
[ -f "manual" ] && cp -f "manual" "result" || true
$ make
make: 'result' is up to date.
$ touch source
$ make
cp -f "source" "auto"
CREATE manual
$ make
CREATE manual
$ touch manual
$ make
[ -f "manual" ] && cp -f "manual" "result" || true
I'm using GNU Make to build a dynamic web site but I need to build two versions. As a net result currently I run my makefile using two command line incantations. This is inefficient and can result in errors (I don't always remember to run both versions or make a typing error and they fail) thus I want to make it one build.
The Command Line incantations are:
sudo make release build=test
sudo make release build=release
The two incantations activate ifeq blocks that set the path and modify some files.
Part of the much simplified (to help readability) top level makefile:
subs = today tomorrow
files = index.php foot.php
ifeq ($(build),test)
export path = /var/www/html/cgi-test
$(shell cp -f head-test.php head.php)
$(shell sed -i '/"DB"/c\ define("DB", "db_test");' subs.php)
else ifeq ($(build),release)
export path = /var/www/html/cgi-new
$(shell cp -f head-release.php head.php)
$(shell sed -i '/"DB"/c\ define("DB", "db_new");' subs.php)
endif
.PHONY: all go
all:
$(MAKE) go
#for ALL in $(subs);\
do $(MAKE) -C $$ALL all || exit $$?;\
done;
go:
cp $(files) $(path)/.
The sub-makefiles have a very similar structure but don't need the ifeq blocks because the files and paths have already been setup.
I think I can simply move the shell commands into the .PHONY rules but I can't do that with the exports because I get errors "export: : bad variable name".
I could do it with a batch file and call the makefile twice but that sidesteps the problem rather than cures it and I wish to learn from the process.
So can anybody show me the way to do this in a makefile?
Thanks to Tripleee here is the answer that finally worked back ported to match my starting post. The one major change is that I have gone back to 'all' as the rule I expect to start the build habits die hard! - Thanks
.PHONY: all both rel-test rel-release
cgi-test := cgi-test
db-test := db_test
cgi-release := cgi-new
db-release := db_new
subs = today tomorrow
files = index.php foot.php
all: both
both: rel-test rel-release
rel-test rel-release: rel-%:
cp -f head-$*.php head.php
sed -i '/"DB"/c\ define("DB", "$(db-$*)");' subs.php
$(MAKE) go path=/var/www/html/strutts/$(cgi-$*)
#for ALL in $(subs);\
do $(MAKE) build=$* path=/var/www/html/strutts/$(cgi-$*) -C $$ALL all || exit $$?;\
done;
Something like this?
.PHONY: both rel-test rel-release
both: rel-test rel-release
cgi-test := cgi-test
db-test := db_test
cgi-release := cgi-new
db-release := db_new
rel-%:
cp -f head-$*.php head.php
sed -i '/"DB"/c\ define("DB", "$(db-$*)")' subs.php
$(MAKE) release build=$* path=/var/www/html/$(cgi-$*)
The reason the export can't be moved into a recipe is that you are using the export command of make itself, not the shell's command with the same name.
You absolutely should not use sudo unless you specifically require the output files to be owned and only writable by root. Even then, running as much as possible as a regular user would be proper hygiene; maybe add a sudo command inside the Makefile to copy the files to their final location.
Criteria: Makefile is a GNU Make Makefile - I'm not interested in makepp, qmake, cmake, etc. They're all nice (especially cmake), but this is for work and at work we use GNU Make. The optimal solution is a pure Makefile solution rather than a shell script that parses make for you.
I also don't want to do a 'continue on failure' solution - if it's broken, it's broken and needs to be fixed.
The situation is this, I've got a makefile that builds several directories in parallel - if one of them fails, of course the whole build fails, but not until all the running makes run to completion (or failure). This means that the reason why make actually failed is buried somewhere arbitrarily far from the end of make's output.
Here's an example of what I've got:
all: $(SUBDIRS)
SUBDIRS = \
apple \
orange \
banana \
pineapple \
lemon \
watermelon \
grapefruit
$(SUBDIRS):
cd $# && $(MAKE) $(MFLAGS) 2>&1 | sed -e "s/^/$(notdir $(#)): /g"
If I run 'make -j 5' and 'orange' happens to fail - I'd like to see a table like this at the end
of the make process
apple - passed
orange - FAILED
banana - passed
pineapple - passed
lemon - passed
I've considered having an && echo "passed" >.result || echo "FAILED" >.result, but make still needs some sort of TRAP or __onexit() cleanup command to print at them on exit.
Any Makefile ninjas out there have a pure-makefile solution for this?
un-edit - my solution wasn't actually working the way I had hoped.. STYMIED!
When you want make to abort at the first failure, end immediately and kill all in-flight jobs instead of waiting for them to finish, you need to patch GNU Make like this
http://lists.gnu.org/archive/html/bug-make/2009-01/msg00035.html
Then you need to set a trap for every shell that make invokes (as well as set -o pipefail if you use a pipe), as described in this post http://lists.gnu.org/archive/html/help-make/2009-02/msg00011.html
In a nutshell:
target1:
trap 'kill $$(jobs -p)'; command && something || something-else
target2:
trap 'kill $$(jobs -p)'; set -o pipefail; command | sed '...'
The only way I see is self-execution with a sub-make:
all : subdirs
subdirs :
$(MAKE) -f $(lastword $(MAKEFILE_LIST)) subdirs-recursive || cat log
subdirs-recursive: $(SUBDIRS)
What do the make and shell option mean in g77? For example, if I have the following script in my Makefile:
FC = g77
FFLAGS = -O2 -mno-cygwin
LDFLAGS =
CD = cd
LN = ln
LNFLAGS = -s
MAKE = /bin/make
RM = rm
RMFLAGS = -f
SHELL = /bin/sh
Does this mean that make operation needs to make use of /bin/make.exe?
On a side note: when I run the compilation, using the above command line, I got an error:
/bin/sh: line 4: Making: command not
found
Not sure whether the two are related.
Edit: This is my Makfile:
arpacklib:
#( \
for f in $(DIRS); \
do \
$(CD) $$f; \
$(ECHO) Making lib in $$f; \
$(MAKE) $(PRECISIONS); \
$(CD) ..; \
done );
$(RANLIB) $(ARPACKLIB)
These are just variables holding the location of programs on your computer. There will probably be rules like $(SHELL) a_shell_script.sh using these variables. The FC, CD, LN and RM are similar, they just don't have the path explicitly listed. Having programs as variables makes it simple to change them, for example if you want to use a different version.
Your error looks like the shell is trying to run the command Making. A possible cause is there is an undefined variable in front of this, eg a rule
all:
$(ECHO) Making something
which would expand to Making something when run instead of echo Making something. Without seeing the relevant line that's the best I can think of.