Bzlmodified.
This commit is contained in:
parent
29c76e9a62
commit
3a43d85ae3
|
|
@ -0,0 +1,734 @@
|
|||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Description:
|
||||
# Icarus Verilog is a Verilog simulation and synthesis tool.
|
||||
# Use :iverilog and :vvp targets in your genrules.
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_binary")
|
||||
|
||||
load("//bazel:yacclex_helpers.bzl", "genyacc", "genlex")
|
||||
load("//bazel:build_plugins.bzl", "vpi_binary")
|
||||
load("//bazel:pseudo_configure.bzl", "pseudo_configure")
|
||||
load("//bazel:system.bzl", "cc_system_headers")
|
||||
|
||||
# The only two exported labels are iverilog and vvp. They are enough
|
||||
# to run simple simulations.
|
||||
package(
|
||||
default_visibility = ["//visibility:private"],
|
||||
features = [
|
||||
"-layering_check", # vpi/fastlz.c including itself
|
||||
"-parse_headers", # missing: `size_t` definition in stab.h, `using string` in parse_api.h
|
||||
],
|
||||
)
|
||||
|
||||
licenses(["restricted"]) # GPLv2
|
||||
|
||||
exports_files([
|
||||
"LICENSE",
|
||||
"build-plugins",
|
||||
])
|
||||
|
||||
filegroup(
|
||||
name = "system_vpis",
|
||||
srcs = [
|
||||
":system_vpi",
|
||||
":v2005_math_vpi",
|
||||
":v2009_vpi",
|
||||
":va_math_vpi",
|
||||
":vhdl_sys_vpi",
|
||||
":vhdl_textio_vpi",
|
||||
":vpi_debug_vpi",
|
||||
],
|
||||
)
|
||||
|
||||
# This wrapper around iverilog compiler is to be used by
|
||||
# simulations. A typical genrule will look similar to gen_hello.vvp
|
||||
# below.
|
||||
sh_binary(
|
||||
name = "iverilog",
|
||||
srcs = ["iverilog.sh"],
|
||||
data = [
|
||||
"vvp.conf",
|
||||
":iverilog-bin",
|
||||
":ivl",
|
||||
":ivlpp",
|
||||
":vvp_tgt",
|
||||
],
|
||||
deps = ["@bazel_tools//tools/bash/runfiles"],
|
||||
output_licenses = ["unencumbered"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "vvp_conf",
|
||||
srcs = ["tgt-vvp/vvp.conf.in"],
|
||||
outs = ["vvp.conf"],
|
||||
cmd = "echo 'flag:VVP_EXECUTABLE=/unused' | cat $(location :tgt-vvp/vvp.conf.in) - > $@",
|
||||
)
|
||||
|
||||
# This wrapper around vvp simulator is to be used by simulations. A
|
||||
# typical genrule will look similar to run_hello below.
|
||||
sh_binary(
|
||||
name = "vvp",
|
||||
srcs = ["vvp.sh"],
|
||||
data = [
|
||||
":vvp-bin",
|
||||
":system_vpis",
|
||||
],
|
||||
output_licenses = ["unencumbered"],
|
||||
deps = ["@bazel_tools//tools/bash/runfiles"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_system_headers(
|
||||
name = "tgt_vvp_config_header",
|
||||
hdrs = [
|
||||
"tgt-vvp/vvp_config.h",
|
||||
],
|
||||
)
|
||||
|
||||
cc_system_headers(
|
||||
name = "vpi_user_header",
|
||||
hdrs = [
|
||||
"vpi_user.h",
|
||||
"_pli_types.h",
|
||||
],
|
||||
)
|
||||
|
||||
cc_system_headers(
|
||||
name = "config_header",
|
||||
hdrs = [
|
||||
"config.h",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "ivl-misc",
|
||||
srcs = [
|
||||
"libmisc/LineInfo.cc",
|
||||
"libmisc/StringHeap.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"libmisc/LineInfo.h",
|
||||
"libmisc/StringHeap.h",
|
||||
],
|
||||
copts = ["-Wno-unused-variable"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "ivl",
|
||||
srcs = glob(
|
||||
[
|
||||
"*.cc",
|
||||
"*.h",
|
||||
],
|
||||
exclude = ["elab_anet.cc"],
|
||||
) + [
|
||||
":config_h",
|
||||
"vvp/ivl_dlfcn.h",
|
||||
"_pli_types.h",
|
||||
":lexor",
|
||||
":lexor_keyword_cc",
|
||||
":parse_y",
|
||||
":syn-rules_y",
|
||||
":version_tag_h",
|
||||
],
|
||||
# Really poor code hygiene. Produces mounds of warnings.
|
||||
copts = ["-w"],
|
||||
includes = [
|
||||
"libmisc",
|
||||
],
|
||||
linkopts = [
|
||||
"-ldl",
|
||||
"-Wl,--export-dynamic",
|
||||
"-Wl,-no-pie",
|
||||
],
|
||||
deps = [
|
||||
":ivl-misc",
|
||||
],
|
||||
)
|
||||
|
||||
genlex(
|
||||
name = "lexor",
|
||||
src = "lexor.lex",
|
||||
out = "lexor.cc",
|
||||
)
|
||||
|
||||
genyacc(
|
||||
name = "parse_y",
|
||||
src = "parse.y",
|
||||
header_out = "parse.h",
|
||||
prefix = "VL",
|
||||
source_out = "parse.cc",
|
||||
)
|
||||
|
||||
genyacc(
|
||||
name = "syn-rules_y",
|
||||
src = "syn-rules.y",
|
||||
header_out = "syn-rules.h",
|
||||
prefix = "syn_",
|
||||
source_out = "syn-rules.cc",
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "iverilog-bin",
|
||||
srcs = glob([
|
||||
"driver/*.c",
|
||||
"driver/*.h",
|
||||
]) + [
|
||||
":config_h",
|
||||
"ivl_alloc.h",
|
||||
"version_base.h",
|
||||
":version_tag_h",
|
||||
":cflexor",
|
||||
":cfparse_y",
|
||||
],
|
||||
copts = [
|
||||
"-D_GNU_SOURCE",
|
||||
"-std=c11",
|
||||
"-fcommon",
|
||||
"-DIVL_LIB='\"\"'",
|
||||
"-DIVL_SUFFIX='\"\"'",
|
||||
"-DIVL_INCLUDE_INSTALL_DIR='\"\"'",
|
||||
],
|
||||
includes = [
|
||||
"driver",
|
||||
"libmisc",
|
||||
],
|
||||
)
|
||||
|
||||
genlex(
|
||||
name = "cflexor",
|
||||
src = "driver/cflexor.lex",
|
||||
out = "driver/cflexor.c",
|
||||
)
|
||||
|
||||
genyacc(
|
||||
name = "cfparse_y",
|
||||
src = "driver/cfparse.y",
|
||||
header_out = "driver/cfparse.h",
|
||||
prefix = "cf",
|
||||
source_out = "driver/cfparse.c",
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "vvp-bin",
|
||||
srcs = glob([
|
||||
"vvp/*.cc",
|
||||
"vvp/*.h",
|
||||
]) + [
|
||||
"ivl_alloc.h",
|
||||
"sv_vpi_user.h",
|
||||
"version_base.h",
|
||||
":version_tag_h",
|
||||
":gen_tables",
|
||||
":vvp_flexor",
|
||||
":vvp_parse_y",
|
||||
":vvp_gen__vvp_config_h",
|
||||
],
|
||||
copts = [
|
||||
"-O2", # Optimized binary regardless of configuration.
|
||||
"-Wno-implicit-fallthrough",
|
||||
],
|
||||
# Do not sort: dot last.
|
||||
includes = [
|
||||
"vvp_gen",
|
||||
"vvp",
|
||||
],
|
||||
linkopts = [
|
||||
"-ldl",
|
||||
"-Wl,--export-dynamic",
|
||||
],
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
"@readline//:readline",
|
||||
],
|
||||
)
|
||||
|
||||
genyacc(
|
||||
name = "vvp_parse_y",
|
||||
src = "vvp/parse.y",
|
||||
header_out = "vvp_gen/parse.h",
|
||||
source_out = "vvp_gen/parse.cc",
|
||||
)
|
||||
|
||||
genlex(
|
||||
name = "vvp_flexor",
|
||||
src = "vvp/lexor.lex",
|
||||
out = "vvp_gen/lexor.cc",
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "draw_tt",
|
||||
srcs = ["vvp/draw_tt.c"],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "gen_tables",
|
||||
outs = ["vvp_gen/tables.cc"],
|
||||
cmd = "$(location :draw_tt) > $@",
|
||||
tools = [":draw_tt"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "ivlpp",
|
||||
srcs = glob([
|
||||
"ivlpp/*.c",
|
||||
"ivlpp/*.h",
|
||||
]) + [
|
||||
":config_h",
|
||||
"ivl_alloc.h",
|
||||
"version_base.h",
|
||||
":version_tag_h",
|
||||
":ivlpp_lexor",
|
||||
],
|
||||
copts = ["-Wno-unused-variable"],
|
||||
# Do not sort: dot last.
|
||||
includes = [
|
||||
"ivlpp",
|
||||
],
|
||||
)
|
||||
|
||||
genlex(
|
||||
name = "ivlpp_lexor",
|
||||
src = "ivlpp/lexor.lex",
|
||||
out = "ivlpp_gen/lexor.c",
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "system_vpi",
|
||||
srcs = [
|
||||
":config_h",
|
||||
"ivl_alloc.h",
|
||||
"sv_vpi_user.h",
|
||||
"version_base.h",
|
||||
"vpi/fastlz.c",
|
||||
"vpi/fastlz.h",
|
||||
"vpi/fstapi.c",
|
||||
"vpi/fstapi.h",
|
||||
"vpi/lxt_write.c",
|
||||
"vpi/lxt_write.h",
|
||||
"vpi/lxt2_write.c",
|
||||
"vpi/lxt2_write.h",
|
||||
"vpi/lz4.c",
|
||||
"vpi/lz4.h",
|
||||
"vpi/mt19937int.c",
|
||||
"vpi/sdf_parse_priv.h",
|
||||
"vpi/sdf_priv.h",
|
||||
"vpi/stringheap.c",
|
||||
"vpi/stringheap.h",
|
||||
"vpi/sys_convert.c",
|
||||
"vpi/sys_countdrivers.c",
|
||||
"vpi/sys_darray.c",
|
||||
"vpi/sys_deposit.c",
|
||||
"vpi/sys_display.c",
|
||||
"vpi/sys_fileio.c",
|
||||
"vpi/sys_finish.c",
|
||||
"vpi/sys_fst.c",
|
||||
"vpi/sys_icarus.c",
|
||||
"vpi/sys_lxt.c",
|
||||
"vpi/sys_lxt2.c",
|
||||
"vpi/sys_plusargs.c",
|
||||
"vpi/sys_priv.c",
|
||||
"vpi/sys_priv.h",
|
||||
"vpi/sys_queue.c",
|
||||
"vpi/sys_random.c",
|
||||
"vpi/sys_random.h",
|
||||
"vpi/sys_random_mti.c",
|
||||
"vpi/sys_readmem.c",
|
||||
"vpi/sys_readmem_lex.h",
|
||||
"vpi/sys_scanf.c",
|
||||
"vpi/sys_sdf.c",
|
||||
"vpi/sys_table.c",
|
||||
"vpi/sys_time.c",
|
||||
"vpi/sys_vcd.c",
|
||||
"vpi/sys_vcdoff.c",
|
||||
"vpi/table_mod.c",
|
||||
"vpi/table_mod.h",
|
||||
"vpi/vams_simparam.c",
|
||||
"vpi/vcd_priv.c",
|
||||
"vpi/vcd_priv.h",
|
||||
"vpi/vcd_priv2.cc",
|
||||
"vpi/vpi_config.h",
|
||||
"vpi/wavealloca.h",
|
||||
":table_mod_lexor_lex",
|
||||
":table_mod_parse_y",
|
||||
":vpi_sdf_lexor",
|
||||
":vpi_sdfparse_y",
|
||||
":vpi_sys_readmem_lex",
|
||||
],
|
||||
out = "system.vpi",
|
||||
# Optimized binary regardless of configuration.
|
||||
copts = [
|
||||
"$(STACK_FRAME_UNLIMITED)",
|
||||
"-O2",
|
||||
# "-std=c11",
|
||||
# was for for-loop-indices, removed to allow vcd_priv2.cc to compile
|
||||
],
|
||||
includes = [
|
||||
"vpi",
|
||||
],
|
||||
# The code has atrocious const hygiene. Produces mounds of warnings.
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
":config_header",
|
||||
"@bzip2//:bz2",
|
||||
"@zlib//:zlib",
|
||||
],
|
||||
)
|
||||
|
||||
genyacc(
|
||||
name = "table_mod_parse_y",
|
||||
src = "vpi/table_mod_parse.y",
|
||||
header_out = "vpi/table_mod_parse.h",
|
||||
prefix = "tblmod",
|
||||
source_out = "vpi/table_mod_parse.c",
|
||||
)
|
||||
|
||||
genlex(
|
||||
name = "table_mod_lexor_lex",
|
||||
src = "vpi/table_mod_lexor.lex",
|
||||
out = "vpi/table_mod_lexor.c",
|
||||
)
|
||||
|
||||
genyacc(
|
||||
name = "vpi_sdfparse_y",
|
||||
src = "vpi/sdf_parse.y",
|
||||
header_out = "vpi/sdf_parse.h",
|
||||
prefix = "sdf",
|
||||
source_out = "vpi/sdf_parse.c",
|
||||
)
|
||||
|
||||
genlex(
|
||||
name = "vpi_sdf_lexor",
|
||||
src = "vpi/sdf_lexor.lex",
|
||||
out = "vpi/sdf_lexor.c",
|
||||
)
|
||||
|
||||
genlex(
|
||||
name = "vpi_sys_readmem_lex",
|
||||
src = "vpi/sys_readmem_lex.lex",
|
||||
out = "vpi/sys_readmem_lex.c",
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "vhdl_sys_vpi",
|
||||
srcs = [
|
||||
"ivl_alloc.h",
|
||||
"sv_vpi_user.h",
|
||||
"vpi/sys_priv.c",
|
||||
"vpi/sys_priv.h",
|
||||
"vpi/vhdl_table.c",
|
||||
"vpi/vpi_config.h",
|
||||
],
|
||||
out = "vhdl_sys.vpi",
|
||||
copts = ["-O2"],
|
||||
includes = [
|
||||
"vpi",
|
||||
],
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
],
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "vhdl_textio_vpi",
|
||||
srcs = [
|
||||
"ivl_alloc.h",
|
||||
"sv_vpi_user.h",
|
||||
"vpi/sys_priv.c",
|
||||
"vpi/sys_priv.h",
|
||||
"vpi/vhdl_textio.c",
|
||||
"vpi/vpi_config.h",
|
||||
],
|
||||
out = "vhdl_textio.vpi",
|
||||
copts = ["-O2"],
|
||||
includes = [
|
||||
"vpi",
|
||||
],
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
],
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "va_math_vpi",
|
||||
srcs = [
|
||||
"ivl_alloc.h",
|
||||
"vpi/va_math.c",
|
||||
"vpi/vpi_config.h",
|
||||
],
|
||||
out = "va_math.vpi",
|
||||
copts = ["-O2"], # Optimized binary regardless of configuration.
|
||||
includes = [
|
||||
"vpi",
|
||||
],
|
||||
# The code has atrocious const hygiene. Produces mounds of warnings.
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
],
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "v2005_math_vpi",
|
||||
srcs = [
|
||||
"ivl_alloc.h",
|
||||
"sv_vpi_user.h",
|
||||
"vpi/sys_clog2.c",
|
||||
"vpi/v2005_math.c",
|
||||
"vpi/vpi_config.h",
|
||||
],
|
||||
out = "v2005_math.vpi",
|
||||
copts = ["-O2"], # Optimized binary regardless of configuration.
|
||||
includes = [
|
||||
"vpi",
|
||||
],
|
||||
# The code has atrocious const hygiene. Produces mounds of warnings.
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
],
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "vpi_debug_vpi",
|
||||
srcs = ["vpi/vpi_debug.c"],
|
||||
out = "vpi_debug.vpi",
|
||||
copts = ["-O2"],
|
||||
includes = [
|
||||
"vpi",
|
||||
],
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
],
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "v2009_vpi",
|
||||
srcs = [
|
||||
"ivl_alloc.h",
|
||||
"sv_vpi_user.h",
|
||||
"vpi/sys_priv.c",
|
||||
"vpi/sys_priv.h",
|
||||
"vpi/v2009_array.c",
|
||||
"vpi/v2009_bitvec.c",
|
||||
"vpi/v2009_enum.c",
|
||||
"vpi/v2009_string.c",
|
||||
"vpi/v2009_table.c",
|
||||
"vpi/vpi_config.h",
|
||||
],
|
||||
out = "v2009.vpi",
|
||||
copts = [
|
||||
"-O2", # Optimized binary regardless of configuration.
|
||||
],
|
||||
includes = [
|
||||
"vpi",
|
||||
],
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
],
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "vvp_tgt",
|
||||
srcs = glob([
|
||||
"tgt-vvp/*.c",
|
||||
"tgt-vvp/*.h",
|
||||
]) + [
|
||||
"ivl_alloc.h",
|
||||
"ivl_target.h",
|
||||
"version_base.h",
|
||||
":version_tag_h",
|
||||
":tgt_vvp__vvp_config_h",
|
||||
],
|
||||
out = "vvp.tgt",
|
||||
copts = [
|
||||
"-std=c11",
|
||||
"-Wno-implicit-function-declaration",
|
||||
"-Wno-int-conversion",
|
||||
],
|
||||
includes = [
|
||||
"tgt-vvp",
|
||||
],
|
||||
# The code has atrocious const hygiene. Produces mounds of warnings.
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "_pli_types_h",
|
||||
srcs = ["_pli_types.h.in"],
|
||||
outs = ["_pli_types.h"],
|
||||
cmd = "cat $(location :_pli_types.h.in) | sed 's/# undef HAVE_INTTYPES_H/# define HAVE_INTTYPES_H 1/' > $@",
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "lexor_keyword_cc",
|
||||
srcs = ["lexor_keyword.gperf"],
|
||||
tools = ["@gperf//:gperf"],
|
||||
outs = ["lexor_keyword.cc"],
|
||||
cmd = "$(location @gperf//:gperf) -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(location :lexor_keyword.gperf) > $@",
|
||||
message = "Generating perfect hash function from $(SRCS)",
|
||||
)
|
||||
|
||||
# In the following genrules we do an extremely crude approximation of a
|
||||
# configuration step -- workable now given the limited set of
|
||||
# platforms/environments we intend to target.
|
||||
|
||||
HAVE_CONFIG_SUFFIXES = "TIMES|IOSFWD|GETOPT_H|INTTYPES_H|DLFCN_H|LIBREADLINE|LIBZ|LIBBZ2|LROUND|SYS_WAIT_H|ALLOCA_H|FSEEKO|LIBPTHREAD|REALPATH"
|
||||
HAVE_CONFIG_RE = "HAVE_(%s)" % HAVE_CONFIG_SUFFIXES
|
||||
|
||||
DEFS = [
|
||||
"HAVE_IOSFWD",
|
||||
"HAVE_DLFCN_H",
|
||||
"HAVE_GETOPT_H",
|
||||
"HAVE_LIBREADLINE",
|
||||
"HAVE_READLINE_READLINE_H",
|
||||
"HAVE_LIBHISTORY",
|
||||
"HAVE_READLINE_HISTORY_H",
|
||||
"HAVE_INTTYPES_H",
|
||||
"HAVE_LROUND",
|
||||
"HAVE_LLROUND",
|
||||
"HAVE_NAN",
|
||||
"UINT64_T_AND_ULONG_SAME",
|
||||
"HAVE_SYS_RESOURCE_H",
|
||||
"LINUX"
|
||||
]
|
||||
|
||||
pseudo_configure(
|
||||
name = "tgt_vvp__vvp_config_h",
|
||||
src = "tgt-vvp/vvp_config.h.in",
|
||||
out = "tgt-vvp/vvp_config.h",
|
||||
defs = [
|
||||
"HAVE_STDINT_H",
|
||||
"HAVE_INTTYPES_H",
|
||||
"_LARGEFILE_SOURCE"
|
||||
],
|
||||
mappings = {},
|
||||
)
|
||||
|
||||
pseudo_configure(
|
||||
name = "config_h",
|
||||
src = "config.h.in",
|
||||
out = "config.h",
|
||||
defs = [
|
||||
"HAVE_TIMES",
|
||||
"HAVE_IOSFWD",
|
||||
"HAVE_GETOPT_H",
|
||||
"HAVE_INTTYPES_H",
|
||||
"HAVE_DLFCN_H",
|
||||
"HAVE_LIBREADLINE",
|
||||
"HAVE_LIBZ",
|
||||
"HAVE_LIBBZ2",
|
||||
"HAVE_LROUND",
|
||||
"HAVE_SYS_WAIT_H",
|
||||
"HAVE_ALLOCA_H",
|
||||
"HAVE_FSEEKO",
|
||||
"HAVE_LIBPTHREAD",
|
||||
"HAVE_REALPATH"
|
||||
],
|
||||
mappings = {},
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "vpi__vpi_config_h",
|
||||
srcs = ["vpi/vpi_config.h.in"],
|
||||
outs = ["vpi/vpi_config.h"],
|
||||
cmd = "perl -p -e 's/# undef (\\w+)/#define $$1 1/' $< > $@",
|
||||
message = "Configuring vpi/vpi_config.h.in",
|
||||
)
|
||||
|
||||
pseudo_configure(
|
||||
name = "vvp_gen__vvp_config_h",
|
||||
src = "vvp/config.h.in",
|
||||
out = "vvp_gen/config.h",
|
||||
defs = DEFS,
|
||||
mappings = {
|
||||
"SIZEOF_UNSIGNED_LONG_LONG": "8",
|
||||
"SIZEOF_UNSIGNED_LONG": "8",
|
||||
"SIZEOF_UNSIGNED": "4",
|
||||
"SIZEOF_VOID_P": "8",
|
||||
"USE_READLINE": "",
|
||||
"USE_HISTORY": "",
|
||||
"MODULE_DIR": '"."',
|
||||
"__STDC_FORMAT_MACROS": "",
|
||||
"TIME_FMT_O": '"lo"',
|
||||
"TIME_FMT_U": '"lu"',
|
||||
"TIME_FMT_X": '"lx"',
|
||||
"UL_AND_TIME64_SAME": "",
|
||||
"i64round": "lround",
|
||||
"nan(x)": "(NAN)",
|
||||
"INFINITY": "HUGE_VAL",
|
||||
"LU": '""',
|
||||
"TU": '""'
|
||||
},
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "version_tag_h",
|
||||
outs = ["version_tag.h"],
|
||||
cmd = "\n".join([
|
||||
"cat <<'EOF' >$@",
|
||||
'#ifndef __VERSION_TAG_H_',
|
||||
'#define __VERSION_TAG_H_',
|
||||
'#define VERSION_TAG "v12_0"',
|
||||
'#endif // __VERSION_TAG_H_',
|
||||
"EOF",
|
||||
]),
|
||||
)
|
||||
|
||||
# Trivial integration tests to confirm iverilog is minimally functional.
|
||||
|
||||
genrule(
|
||||
name = "hello_vvp",
|
||||
srcs = ["hello.v"],
|
||||
outs = ["hello.vvp"],
|
||||
cmd = (
|
||||
"$(location :iverilog) " +
|
||||
"-o $@ " +
|
||||
"$<"
|
||||
),
|
||||
tools = [
|
||||
":iverilog",
|
||||
":vvp", # to resolve module include
|
||||
],
|
||||
)
|
||||
|
||||
vpi_binary(
|
||||
name = "hello_vpi",
|
||||
srcs = ["hello_vpi.c"],
|
||||
out = "hello.vpi",
|
||||
deps = [
|
||||
":vpi_user_header",
|
||||
],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "run_hello",
|
||||
srcs = ["hello.vvp"],
|
||||
outs = ["hello.out"],
|
||||
cmd = (
|
||||
"$(location :vvp) " +
|
||||
"-M$$(dirname $(location :hello_vpi)) " +
|
||||
"-mhello $< > $@ "
|
||||
),
|
||||
tools = [
|
||||
":hello_vpi",
|
||||
":vvp",
|
||||
],
|
||||
)
|
||||
|
||||
sh_test(
|
||||
name = "hello_verilog_test",
|
||||
srcs = [":hello_verilog_test.sh"],
|
||||
args = ["$(location :run_hello)"],
|
||||
data = [":run_hello"],
|
||||
)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
module(
|
||||
name = "iverilog",
|
||||
version = "12.0.0",
|
||||
)
|
||||
|
||||
bazel_dep(name = "gperf", version = "3.1")
|
||||
bazel_dep(name = "bzip2", version = "1.0.8.bcr.2")
|
||||
bazel_dep(name = "rules_flex", version = "0.4")
|
||||
bazel_dep(name = "rules_bison", version = "0.4")
|
||||
bazel_dep(name = "sed", version = "4.9.bcr.1")
|
||||
bazel_dep(name = "rules_m4", version = "0.3")
|
||||
bazel_dep(name = "readline", version = "8.2.bcr.1")
|
||||
bazel_dep(name = "zlib", version = "1.3.1.bcr.5")
|
||||
bazel_dep(name = "rules_cc", version = "0.1.1")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""BUILD helpers for using iverilog.
|
||||
"""
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary")
|
||||
|
||||
def vpi_binary(name, out, srcs, **kwargs):
|
||||
"""Creates a .vpi file with the given name from the given sources.
|
||||
|
||||
All the extra arguments are passed directly to cc_binary.
|
||||
"""
|
||||
cc_target = name + "_shared"
|
||||
cc_binary(
|
||||
name = cc_target,
|
||||
srcs = srcs,
|
||||
linkshared = 1,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
native.genrule(
|
||||
name = name,
|
||||
srcs = [":" + cc_target],
|
||||
outs = [out],
|
||||
cmd = "cp $< $@",
|
||||
output_to_bindir = 1,
|
||||
executable = 1,
|
||||
)
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Fake configuration step for hacky substitutions in ".in" files."""
|
||||
|
||||
_UNIX_TEMPLATE = """\
|
||||
#!/usr/bin/env bash
|
||||
# Generated by `@iverilog//bazel:pseudo_configure.bzl`
|
||||
set -euo pipefail
|
||||
{}
|
||||
"""
|
||||
|
||||
def _pseudo_configure_impl(ctx):
|
||||
additional = ctx.attr.additional
|
||||
mappings = ctx.attr.mappings
|
||||
defs = ctx.attr.defs
|
||||
out = ctx.outputs.out
|
||||
src = ctx.file.src if ctx.attr.src else None
|
||||
sed = ctx.executable._sed
|
||||
|
||||
cmd = []
|
||||
|
||||
if src == None:
|
||||
cmd.append("echo '#pragma once' >> %s" % (out.path))
|
||||
|
||||
for k, v in additional.items():
|
||||
cmd.append("echo '#define %s %s' >> %s" % (k, v, out.path))
|
||||
|
||||
if src != None:
|
||||
cmd.append("cat %s \\" % (src.path))
|
||||
else:
|
||||
cmd.append("echo '' \\")
|
||||
all_defs = ""
|
||||
for def_ in defs:
|
||||
cmd.append(r"| " + sed.path + r" 's/#\s*undef \b\(" + def_ + r"\)\b/#define \1 1/'" + "\\")
|
||||
all_defs += ("#define " + def_ + " 1\\n")
|
||||
for key, value in mappings.items():
|
||||
cmd.append(r"| " + sed.path + r" 's/#\s*undef \b" + key + r"\b/#define " + str(key) + " " + str(value) + "/' \\")
|
||||
cmd.append(r"| " + sed.path + r" 's/#\s*define \b\(" + key + r"\)\b 0/#define \1 " + str(value) + "/' \\")
|
||||
all_defs += "#define " + key + " " + value + "\\n"
|
||||
cmd.append(r"| " + sed.path + r" 's/\@DEFS\@/" + all_defs + "/' \\")
|
||||
cmd.append(" >> " + out.path)
|
||||
|
||||
executable = ctx.actions.declare_file("{}.sh".format(ctx.label.name))
|
||||
ctx.actions.write(
|
||||
output = executable,
|
||||
content = _UNIX_TEMPLATE.format(
|
||||
"\n".join(cmd),
|
||||
),
|
||||
is_executable = True,
|
||||
)
|
||||
|
||||
ctx.actions.run(
|
||||
mnemonic = "NCursesPseudoConfigure",
|
||||
inputs = [src] if src != None else [],
|
||||
outputs = [out],
|
||||
executable = executable,
|
||||
tools = [sed],
|
||||
use_default_shell_env = True,
|
||||
)
|
||||
|
||||
return [DefaultInfo(
|
||||
files = depset([out]),
|
||||
)]
|
||||
|
||||
pseudo_configure = rule(
|
||||
doc = "Perform a fake 'configure' step on a file.",
|
||||
implementation = _pseudo_configure_impl,
|
||||
attrs = {
|
||||
"additional": attr.string_dict(
|
||||
doc = "Optional mapping of definitions to prepend to the file.",
|
||||
default = {},
|
||||
),
|
||||
"defs": attr.string_list(
|
||||
doc = "List of definitions to #define as `1`.",
|
||||
default = [],
|
||||
),
|
||||
"mappings": attr.string_dict(
|
||||
doc = "Mapping of definitions with non-trivial values.",
|
||||
default = {},
|
||||
),
|
||||
"out": attr.output(
|
||||
doc = "Path to place the output file contents.",
|
||||
mandatory = True,
|
||||
),
|
||||
"src": attr.label(
|
||||
doc = "`.in` file to transform.",
|
||||
allow_single_file = True,
|
||||
),
|
||||
"_sed": attr.label(
|
||||
cfg = "exec",
|
||||
executable = True,
|
||||
default = Label("@sed"),
|
||||
),
|
||||
},
|
||||
)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
|
||||
|
||||
SYSTEM_HEADERS_BASE = "_system"
|
||||
|
||||
def cc_system_headers(name, hdrs, strip_include_prefix='', **kwargs):
|
||||
"""Copy headers in a folder and create a cc_library with system includes.
|
||||
|
||||
This rule relies on strip_include_prefix behavior that adds a folder with virtual_includes
|
||||
and includes both iquote and isystem compiler options.
|
||||
|
||||
The SYSTEM_HEADERS_BASE is just used to hide in the gendir the files.
|
||||
"""
|
||||
outs = [
|
||||
'{}/{}'.format(SYSTEM_HEADERS_BASE, hdr)
|
||||
for hdr in hdrs
|
||||
]
|
||||
[copy_file(
|
||||
name = "{}_{}".format(SYSTEM_HEADERS_BASE, hdr).replace('/', '_').replace('.', '_').replace('-', '_'),
|
||||
src = hdr,
|
||||
out = out,
|
||||
) for hdr, out in zip(hdrs, outs)]
|
||||
includes = kwargs.pop('includes', default=[])
|
||||
includes = [
|
||||
'{}/{}'.format(SYSTEM_HEADERS_BASE, k)
|
||||
for k in includes
|
||||
]
|
||||
native.cc_library(
|
||||
name = name,
|
||||
hdrs = outs,
|
||||
includes = includes,
|
||||
strip_include_prefix = '{}/{}'.format(SYSTEM_HEADERS_BASE, strip_include_prefix),
|
||||
**kwargs
|
||||
)
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
"""Port of the original rules to bzlmod bison and lex."""
|
||||
|
||||
def genlex(name, src, out, prefix = "yy"):
|
||||
native.genrule(
|
||||
name = name,
|
||||
srcs = [src],
|
||||
outs = [out],
|
||||
cmd = "M4=$(M4) $(FLEX) -P {} --outfile=$@ $<".format(prefix),
|
||||
toolchains = [
|
||||
"@rules_flex//flex:current_flex_toolchain",
|
||||
"@rules_m4//m4:current_m4_toolchain",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def genyacc(name, src, header_out, source_out, prefix = "yy", extra_outs = []):
|
||||
native.genrule(
|
||||
name = name,
|
||||
srcs = [src],
|
||||
outs = [
|
||||
header_out,
|
||||
source_out,
|
||||
] + extra_outs,
|
||||
cmd = """
|
||||
M4=$(M4) $(BISON) \
|
||||
--defines=$(@D)/{} \
|
||||
--output-file=$(@D)/{} \
|
||||
--name-prefix={} $<
|
||||
""".format(header_out, source_out, prefix),
|
||||
toolchains = [
|
||||
"@rules_bison//bison:current_bison_toolchain",
|
||||
"@rules_m4//m4:current_m4_toolchain",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1743583204,
|
||||
"narHash": "sha256-F7n4+KOIfWrwoQjXrL2wD9RhFYLs2/GGe/MQY1sSdlE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2c8d3f48d33929642c1c12cd243df4cc7d2ce434",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2c8d3f48d33929642c1c12cd243df4cc7d2ce434",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
// Verilog test helper file.
|
||||
|
||||
module hello;
|
||||
|
||||
integer val;
|
||||
|
||||
initial begin
|
||||
val = 41;
|
||||
$increment(val);
|
||||
$display("$increment returns val=%d", val);
|
||||
$finish();
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright 2020 The XLS Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -eu
|
||||
|
||||
exec grep 42 $1
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Based on http://en.wikipedia.org/wiki/Verilog_Procedural_Interface.
|
||||
//
|
||||
// Simple VPI plug-in to test the toolchain.
|
||||
|
||||
#include "vpi_user.h"
|
||||
|
||||
// Implements the increment system task
|
||||
static PLI_INT32 increment(PLI_BYTE8 *userdata) {
|
||||
// Obtains a handle to the argument list
|
||||
vpiHandle systfref = vpi_handle(vpiSysTfCall, NULL);
|
||||
vpiHandle args_iter = vpi_iterate(vpiArgument, systfref);
|
||||
|
||||
// Grabs the value of the first argument
|
||||
vpiHandle argh = vpi_scan(args_iter);
|
||||
struct t_vpi_value argval;
|
||||
argval.format = vpiIntVal;
|
||||
vpi_get_value(argh, &argval);
|
||||
|
||||
int value = argval.value.integer;
|
||||
vpi_printf("Input %d\n", value);
|
||||
|
||||
// Increments the value and puts it back as first argument
|
||||
argval.value.integer = value + 1;
|
||||
vpi_put_value(argh, &argval, NULL, vpiNoDelay);
|
||||
|
||||
// Cleans up and returns.
|
||||
vpi_free_object(args_iter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Registers the $increment task with the system.
|
||||
static void registerIncrementTask() {
|
||||
s_vpi_systf_data task;
|
||||
task.type = vpiSysTask;
|
||||
task.tfname = "$increment";
|
||||
task.calltf = increment;
|
||||
task.compiletf = 0;
|
||||
|
||||
vpi_register_systf(&task);
|
||||
}
|
||||
|
||||
// Registers the new system task here.
|
||||
void (*vlog_startup_routines[]) () = {
|
||||
registerIncrementTask,
|
||||
0
|
||||
};
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Wrapper around iverilog binary. Adds the path to the dependencies to
|
||||
# the command line of iverilog.
|
||||
set -eu
|
||||
|
||||
# Copy-pasted from the Bazel Bash runfiles library v3.
|
||||
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
|
||||
# shellcheck disable=SC1090
|
||||
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
|
||||
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
|
||||
source "$0.runfiles/$f" 2>/dev/null || \
|
||||
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
|
||||
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
|
||||
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
|
||||
|
||||
repo_name=$(runfiles_current_repository)
|
||||
repo_name=${repo_name:-_main}
|
||||
dir="$0.runfiles/$repo_name"
|
||||
vvp_dir="${0/%iverilog/vvp}.runfiles/$repo_name"
|
||||
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
dir=$(dirname $0) # use current directory it not launched directly from the :iverilog target.
|
||||
fi
|
||||
if [[ ! -d "$vvp_dir" ]]; then
|
||||
vvp_dir=$(dirname $0) # use current directory it not launched directly from the :iverilog target.
|
||||
fi
|
||||
|
||||
exec "$dir/iverilog-bin" -B"$dir" -BM"$vvp_dir" -DIVERILOG "$@"
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Wrapper around vvp binary. Adds the path to the dependencies to
|
||||
# the command line of vvp.
|
||||
|
||||
set -eu
|
||||
# Copy-pasted from the Bazel Bash runfiles library v3.
|
||||
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
|
||||
# shellcheck disable=SC1090
|
||||
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
|
||||
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
|
||||
source "$0.runfiles/$f" 2>/dev/null || \
|
||||
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
|
||||
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
|
||||
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
|
||||
|
||||
repo_name=$(runfiles_current_repository)
|
||||
repo_name=${repo_name:-_main}
|
||||
dir="$0.runfiles/$repo_name"
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
dir=$(dirname $0) # use current directory it not launched directly from the :vvp target.
|
||||
fi
|
||||
|
||||
exec "$dir/vvp-bin" -M"$dir" "$@"
|
||||
Loading…
Reference in New Issue