1#!/usr/bin/env python3
2# pylint: disable=C0103,C0114,C0115,C0116,R0801,R0915
3######################################################################
4
5import argparse
6import multiprocessing
7import os
8import shutil
9import subprocess
10import sys
11
12######################################################################
13
14
15def test():
16    if not os.path.exists("nodist/install_test"):
17        sys.exit("%Error: Run from the top of the verilator kit")
18
19    cleanenv()
20    if os.path.exists("Makefile"):
21        run("make distclean")
22
23    # Try building from a scratch area
24    srcdir = os.getcwd()
25    blddir = srcdir + "/test_regress/obj_dir/install_test_bld"
26    prefix = srcdir + "/test_regress/obj_dir/install_test_prefix"
27    testdirp = srcdir + "/test_regress/obj_dir/install_test_testp"
28    testdirn = srcdir + "/test_regress/obj_dir/install_test_testn"
29
30    if Args.stage <= 0:
31        print("== stage 0")
32        run("/bin/rm -rf " + blddir)
33        run("/bin/mkdir -p " + blddir)
34        run("cd " + blddir + " && " + srcdir + "/configure --prefix " + prefix)
35        run("cd " + blddir + " && make -j " + str(calc_jobs()))
36
37    # Install it under the prefix
38    if Args.stage <= 1:
39        print("== stage 1")
40        run("/bin/rm -rf " + prefix)
41        run("/bin/mkdir -p " + prefix)
42        run("cd " + blddir + " && make install")
43        run("test -e " + prefix + "/share/man/man1/verilator.1")
44        run("test -e " + prefix +
45            "/share/verilator/examples/make_tracing_c/Makefile")
46        run("test -e " + prefix + "/share/verilator/include/verilated.h")
47        run("test -e " + prefix + "/bin/verilator")
48        run("test -e " + prefix + "/bin/verilator_bin")
49        run("test -e " + prefix + "/bin/verilator_bin_dbg")
50        run("test -e " + prefix + "/bin/verilator_gantt")
51        run("test -e " + prefix + "/bin/verilator_profcfunc")
52
53    # run a test using just the path
54    if Args.stage <= 2:
55        print("== stage 2")
56        odir = testdirp
57        run("/bin/rm -rf   " + odir)
58        run("/bin/mkdir -p " + odir)
59        path = prefix + "/bin" + ":" + prefix + "/share/bin"
60        write_verilog(odir)
61        run("cd " + odir + " && PATH=" + path +
62            ":$PATH verilator --cc top.v --exe sim_main.cpp")
63        run("cd " + odir + "/obj_dir && PATH=" + path +
64            ":$PATH make -f Vtop.mk")
65        run("cd " + odir + " && PATH=" + path + ":$PATH obj_dir/Vtop")
66
67    # run a test using exact path to binary
68    if Args.stage <= 3:
69        print("== stage 3")
70        odir = testdirn
71        run("/bin/rm -rf   " + odir)
72        run("/bin/mkdir -p " + odir)
73        write_verilog(odir)
74        bin1 = prefix + "/bin"
75        run("cd " + odir + " && " + bin1 +
76            "/verilator --cc top.v --exe sim_main.cpp")
77        run("cd " + odir + "/obj_dir && make -f Vtop.mk")
78        run("cd " + odir + "/obj_dir && ./Vtop")
79
80    if Args.stage <= 9:
81        print("*-* All Finished *-*")
82
83
84def write_verilog(odir):
85    shutil.copy2("examples/make_hello_c/top.v", odir + "/top.v")
86    shutil.copy2("examples/make_hello_c/sim_main.cpp", odir + "/sim_main.cpp")
87
88
89def cleanenv():
90    for var in os.environ:
91        if var in ('VERILATOR_ROOT', 'VERILATOR_INCLUDE',
92                   'VERILATOR_NO_OPT_BUILD'):
93            print("unset %s # Was '%s'" % (var, os.environ[var]))
94            del os.environ[var]
95
96
97def calc_jobs():
98    return multiprocessing.cpu_count() + 1
99
100
101def run(command):
102    # run a system command, check errors
103    print("\t%s" % command)
104    os.system(command)
105    status = subprocess.call(command, shell=True)
106    if status < 0:
107        raise Exception("%Error: Command failed " + command + ", stopped")
108
109
110#######################################################################
111#######################################################################
112
113parser = argparse.ArgumentParser(
114    allow_abbrev=False,
115    formatter_class=argparse.RawDescriptionHelpFormatter,
116    description=
117    """install_test performs several make-and-install iterations to verify the
118Verilator kit.  It isn't part of the normal "make test" due to the number
119of builds required.""",
120    epilog=
121    """Copyright 2009-2021 by Wilson Snyder. This program is free software; you
122can redistribute it and/or modify it under the terms of either the GNU
123Lesser General Public License Version 3 or the Perl Artistic License
124Version 2.0.
125
126SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
127parser.add_argument('--debug',
128                    action='store_const',
129                    const=9,
130                    help='enable debug')
131parser.add_argument('--stage',
132                    type=int,
133                    default=0,
134                    help='run a specific test stage (see the script)')
135
136Args = parser.parse_args()
137test()
138
139######################################################################
140# Local Variables:
141# compile-command: "cd .. ; nodist/install_test"
142# End:
143