From 849487da23c7fc99a11e79fcf2da58634a355f9c Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Thu, 30 Apr 2020 12:54:50 +0100 Subject: [PATCH] Modify --build to be a standalone option (#2294) - Issue an error when --build is used together with --make - When given --build, always use GNU Make to perform the build - Update documentation (examples were good as they were) - Remove the broken t_flag_build_cmake test Fixes #2280 --- bin/verilator | 45 +++++++++++------- src/V3Options.cpp | 4 ++ src/Verilator.cpp | 45 +++++++----------- .../{t_flag_build_make.pl => t_flag_build.pl} | 4 +- test_regress/t/t_flag_build_bad.out | 2 + test_regress/t/t_flag_build_bad.pl | 26 ++++++++++ test_regress/t/t_flag_build_cmake.pl | 47 ------------------- test_regress/t/t_flag_verilate.pl | 4 +- 8 files changed, 79 insertions(+), 98 deletions(-) rename test_regress/t/{t_flag_build_make.pl => t_flag_build.pl} (87%) create mode 100644 test_regress/t/t_flag_build_bad.out create mode 100755 test_regress/t/t_flag_build_bad.pl delete mode 100755 test_regress/t/t_flag_build_cmake.pl diff --git a/bin/verilator b/bin/verilator index 1b448da73..2d3c6c538 100755 --- a/bin/verilator +++ b/bin/verilator @@ -274,12 +274,12 @@ detailed descriptions in L for more information. --bbox-sys Blackbox unknown $system calls --bbox-unsup Blackbox unsupported language features --bin Override Verilator binary - --build Call make system to build executable after Verilation + --build Build model executable/library after Verilation -CFLAGS C++ Compiler flags for makefile --cc Create C++ output --cdc Clock domain crossing analysis --clk Mark specified signal as clock - --make Generate scripts for specified make system + --make Generate scripts for specified build tool --compiler Tune for specified C++ compiler --converge-limit Tune convergence settle time --coverage Enable all coverage @@ -325,7 +325,7 @@ detailed descriptions in L for more information. --language Default language standard to parse +libext++[ext]... Extensions for finding modules --lint-only Lint, but do not make output - -MAKEFLAGS Options to make/cmake during --build + -MAKEFLAGS Options to make during --build --max-num-width Maximum number width (default: 64K) --MMD Create .d dependency files --MP Create phony dependency targets @@ -545,8 +545,10 @@ output files. =item --build -After generating the SystemC/C++ code, Verilator will use the make system -to build a library or executable. See also C<--make> and C<--exe>. +After generating the SystemC/C++ code, Verilator will invoke the toolchain to +build the model library (and executable when C<--exe> is also used). Verilator +manages the build itself, and for this --build requires GNU Make to be +available on the platform. =item -CFLAGS I @@ -593,15 +595,17 @@ If clock signals are assigned to vectors and then later used individually, Verilator will attempt to decompose the vector and connect the single-bit clock signals directly. This should be transparent to the user. -=item --make I +=item --make I -Generates a script for the specified make system. +Generates a script for the specified build tool. -Supported make systems are gmake and cmake. Both can be specified. -If no make system is specified, gmake is assumed. -The executable of gmake can be configured via environment variable "MAKE". +Supported values are C for GNU Make and C for CMake. Both can be +specified together. If no build tool is specified, gmake is assumed. The +executable of gmake can be configured via environment variable "MAKE". -See also --build. +When using --build Verilator takes over the responsibility of building the +model library/executable. For this reason --make cannot be specified when +using --build. =item --compiler I @@ -951,9 +955,11 @@ for very small modules; they will always be inlined, if allowed. =item -j -Specify the parallelism for make system. This option is used when --build -options is specified. must be a positive integer or can be omitted. -Build system exploits maximum parallelism when is omitted. +Specify the level of parallelism for --build. must be a positive +integer specifying the maximum number of parallel build jobs, or can be +omitted. When is omitted, the build will not try to limit the number of +parallel build jobs but attempt to execute all independent build steps in +parallel. =item -LDFLAGS I @@ -1002,10 +1008,11 @@ If the design is not to be completely Verilated see also the --bbox-sys and =item -MAKEFLAGS -When using --build, add the specified flag to the make/cmake command line. +When using --build, add the specified flag to the invoked make command line. For multiple flags either pass them as a single argument with space separators quoted in the shell (e.g. C<-MAKEFLAGS "-a -b">), or use multiple -MAKEFLAGS -arguments (e.g. C<-MAKEFLAGS -l -MAKEFLAGS -k>). +arguments (e.g. C<-MAKEFLAGS -l -MAKEFLAGS -k>). Use of this option should not +be required for simple builds using the host toolchain. =item --max-num-width I @@ -1576,7 +1583,9 @@ Note -v is fairly standard across Verilog tools. =item --no-verilate -When using --build, disable generation of C++/SC code, and only run make/cmake. +When using --build, disable generation of C++/SC code, and execute only the +build. This can be useful for rebuilding verilated code produced by a previous +invocation of Verilator. =item +verilog1995ext+I @@ -2193,7 +2202,7 @@ needed at simulation runtime. =item MAKE -Executable of the make command used in --build option. +Names the executable of the make command invoked when using the --build option. Some operating systems may require "gmake" to this variable to launch GNU make. If this variable is not specified, "make" is used. diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 29b058b72..733cea183 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -593,6 +593,10 @@ void V3Options::notify() { "--xml-only or --E option"); } + if (m_build && (m_gmake || m_cmake)) { + cmdfl->v3error("--make cannot be used together with --build. Suggest see manual"); + } + // Make sure at least one make system is enabled if (!m_gmake && !m_cmake) m_gmake = true; diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 2f174600e..33f3c9388 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -567,41 +567,28 @@ static void verilate(const string& argString) { static void execBuildJob() { UASSERT(v3Global.opt.build(), "--build is not specified."); + UASSERT(v3Global.opt.gmake(), "--build requires GNU Make."); + UASSERT(!v3Global.opt.cmake(), "--build cannot use CMake."); UINFO(1, "Start Build\n"); - std::stringstream cmd; const V3StringList& makeFlags = v3Global.opt.makeFlags(); const int jobs = v3Global.opt.buildJobs(); UASSERT(jobs >= 0, "-j option parser in V3Options.cpp filters out negative value"); - if (v3Global.opt.gmake()) { // If both gmake and cmake are chosen, use gmake to build. - cmd << v3Global.opt.getenvMAKE(); - cmd << " -C " << v3Global.opt.makeDir(); - cmd << " -f " << v3Global.opt.prefix() << ".mk"; - if (jobs == 0) { - cmd << " -j"; - } else if (jobs > 1) { - cmd << " -j " << jobs; - } - for (V3StringList::const_iterator it = makeFlags.begin(); it != makeFlags.end(); ++it) { - cmd << ' ' << *it; - } - } else { - UASSERT(v3Global.opt.cmake(), "cmake or gmake must be chosen in V3Options.cpp"); - cmd << "cd " << v3Global.opt.makeDir() << " && "; - cmd << "cmake"; - for (V3StringList::const_iterator it = makeFlags.begin(); it != makeFlags.end(); ++it) { - cmd << ' ' << *it; - } - cmd << ' ' << V3Os::getcwd() << " && "; - cmd << "cmake --build . "; - if (jobs == 0) { - cmd << " -j"; - } else if (jobs > 1) { - cmd << " -j " << jobs; - } - } - const std::string cmdStr = cmd.str(); + std::stringstream cmd; + cmd << v3Global.opt.getenvMAKE(); + cmd << " -C " << v3Global.opt.makeDir(); + cmd << " -f " << v3Global.opt.prefix() << ".mk"; + if (jobs == 0) { + cmd << " -j"; + } else if (jobs > 1) { + cmd << " -j " << jobs; + } + for (V3StringList::const_iterator it = makeFlags.begin(); it != makeFlags.end(); ++it) { + cmd << ' ' << *it; + } + + const std::string cmdStr = cmd.str(); const int exit_code = V3Os::system(cmdStr); if (exit_code != 0) { v3error(cmdStr << " exitted with " << exit_code << std::endl); diff --git a/test_regress/t/t_flag_build_make.pl b/test_regress/t/t_flag_build.pl similarity index 87% rename from test_regress/t/t_flag_build_make.pl rename to test_regress/t/t_flag_build.pl index 0084a0b55..d5278d93f 100755 --- a/test_regress/t/t_flag_build_make.pl +++ b/test_regress/t/t_flag_build.pl @@ -15,7 +15,7 @@ top_filename("t/t_flag_make_cmake.v"); compile( # Don't call cmake nor gmake from driver.pl verilator_make_cmake => 0, verilator_make_gmake => 0, - verilator_flags2 => ['--exe --cc --build -j 2 --make gmake', + verilator_flags2 => ['--exe --cc --build -j 2', '../' . $Self->{main_filename}, '-MAKEFLAGS -p --trace'], ); @@ -26,7 +26,7 @@ execute( # If '-MAKEFLAGS --trace' is not properly processed, # the log will not contain 'CMAKE_BUILD_TYPE:STRING=Debug'. -file_grep($Self->{obj_dir} . '/vlt_compile.log', /^Vt_flag_build_make.mk:\d+: update target \'(\w+)\' due to:/, 'Vt_flag_build_make'); +file_grep($Self->{obj_dir} . '/vlt_compile.log', /^Vt_flag_build_make.mk:\d+: update target \'(\w+)\' due to:/, 'Vt_flag_build'); ok(1); 1; diff --git a/test_regress/t/t_flag_build_bad.out b/test_regress/t/t_flag_build_bad.out new file mode 100644 index 000000000..63a4df79c --- /dev/null +++ b/test_regress/t/t_flag_build_bad.out @@ -0,0 +1,2 @@ +%Error: --make cannot be used together with --build. Suggest see manual +%Error: Exiting due to diff --git a/test_regress/t/t_flag_build_bad.pl b/test_regress/t/t_flag_build_bad.pl new file mode 100755 index 000000000..8b792ff9c --- /dev/null +++ b/test_regress/t/t_flag_build_bad.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +compile( + verilator_flags2 => ["--build --make gmake"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +compile( + verilator_flags2 => ["--build --make cmake"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_build_cmake.pl b/test_regress/t/t_flag_build_cmake.pl deleted file mode 100755 index 1c189d3c3..000000000 --- a/test_regress/t/t_flag_build_cmake.pl +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/perl -if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } -# DESCRIPTION: Verilator: Verilog Test driver/expect definition -# -# Copyright 2008 by Wilson Snyder. This program is free software; you -# can redistribute it and/or modify it under the terms of either the GNU -# Lesser General Public License Version 3 or the Perl Artistic License -# Version 2.0. -# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - - -scenarios(simulator => 1); -top_filename("t/t_flag_make_cmake.v"); - -# This test seems broken as the CMake build invoked by Verilator itself -# invokes Verilator.. (See #2280). Strangely though it passes when built -# from clean, so nuke it: -clean_objs(); - -compile( # Don't call cmake nor gmake from driver.pl - verilator_make_cmake => 0, - verilator_make_gmake => 0, - verilator_flags2 => ['--exe --cc --build --make cmake', - '../' . $Self->{main_filename}, - ' -MAKEFLAGS "-DTEST_NAME=' . $Self->{name} . '"', - ' -MAKEFLAGS "-DTEST_CSOURCES=' . $Self->{main_filename} . '"', - ' -MAKEFLAGS "-DTEST_OPT_FAST=-Os"', - ' -MAKEFLAGS "-DTEST_VERILATOR_ROOT=' . $ENV{VERILATOR_ROOT} . '"', - ' -MAKEFLAGS "-DTEST_VERILATOR_ARGS=\"--prefix ' . $Self->{VM_PREFIX} . ' --cc \""', - ' -MAKEFLAGS "-DTEST_VERILATOR_SOURCES=./t/t_flag_make_cmake.v"', - ' -MAKEFLAGS "-DTEST_SYSTEMC=0"', - ' -MAKEFLAGS "-DTEST_VERBOSE=0"', - ' -MAKEFLAGS "-DTEST_VERILATION=1"', - ' -MAKEFLAGS -DCMAKE_BUILD_TYPE=Debug', - ' -MAKEFLAGS -L'], - ); - -execute( - check_finished => 1, - ); - -# If '-MAKEFLAGS -DCMAKE_BUILD_TYPE=Debug' and '-MAKEFLAGS -L' are not properly processed, -# the log will not contain 'CMAKE_BUILD_TYPE:STRING=Debug'. -file_grep($Self->{obj_dir} . '/vlt_compile.log', /^CMAKE_BUILD_TYPE:STRING=(\w+)$/, 'Debug'); - -ok(1); -1; diff --git a/test_regress/t/t_flag_verilate.pl b/test_regress/t/t_flag_verilate.pl index b523b77e3..f4b0081eb 100755 --- a/test_regress/t/t_flag_verilate.pl +++ b/test_regress/t/t_flag_verilate.pl @@ -33,7 +33,7 @@ if ( -e $Self->{obj_dir} . '/Vt_flag_verilate.mk' ) { compile( # Don't call cmake nor gmake from driver.pl. Just verilate here. verilator_make_cmake => 0, verilator_make_gmake => 0, - verilator_flags2 => ['--exe --cc --make gmake --verilate', + verilator_flags2 => ['--exe --cc --verilate', '../' . $Self->{main_filename}] ); @@ -46,7 +46,7 @@ if ( ! -e $Self->{obj_dir} . '/Vt_flag_verilate.mk' ) { compile( # Don't call cmake nor gmake from driver.pl. Just build here verilator_make_cmake => 0, verilator_make_gmake => 0, - verilator_flags2 => ['--exe --cc --build --make gmake --no-verilate', + verilator_flags2 => ['--exe --cc --build --no-verilate', '../' . $Self->{main_filename}, '--debugi 1 --dump-tree'], );