From 157948c552f63f413aefc3ef3acd28d53dfd1b20 Mon Sep 17 00:00:00 2001 From: Yutetsu TAKATSUKASA Date: Sun, 20 Sep 2020 07:48:05 +0900 Subject: [PATCH] Fix cmake build with --hierarchical option (#2560) * hier_block with cmake test doesn't assume prefix now. * Add space between files * don't set -Mdir on cmake build as it will be set by DIRECTORY option * Use top target name instead of prefix --- Makefile.in | 2 + src/V3EmitCMake.cpp | 21 ++++---- src/V3HierBlock.cpp | 2 +- test_regress/t/t_hier_block_cmake.pl | 50 ++++++++----------- .../t/t_hier_block_cmake/CMakeLists.txt | 27 ++++++++++ test_regress/t/t_hier_block_cmake/main.cpp | 27 ++++++++++ 6 files changed, 88 insertions(+), 41 deletions(-) create mode 100644 test_regress/t/t_hier_block_cmake/CMakeLists.txt create mode 100644 test_regress/t/t_hier_block_cmake/main.cpp diff --git a/Makefile.in b/Makefile.in index 8870f6cc0..93d3ef247 100644 --- a/Makefile.in +++ b/Makefile.in @@ -170,6 +170,8 @@ DISTFILES_INC = $(INFOS) .gitignore \ test_regress/t/t*/*.v* \ test_regress/t/t*/*/*.sv* \ test_regress/t/t*/*/*.v* \ + test_regress/t/t*/*.cpp \ + test_regress/t/t*/CMakeLists.txt \ test_regress/t/*.cpp \ test_regress/t/*.h \ test_regress/t/*.dat \ diff --git a/src/V3EmitCMake.cpp b/src/V3EmitCMake.cpp index d244469d1..2b14984fc 100644 --- a/src/V3EmitCMake.cpp +++ b/src/V3EmitCMake.cpp @@ -204,15 +204,14 @@ class CMakeEmitter { *of << "# Verilate hierarchical blocks\n"; // Sorted hierarchical blocks in order of leaf-first. const V3HierBlockPlan::HierVector& hierBlocks = planp->hierBlocksSorted(); - const string topTarget = v3Global.opt.protectLib().empty() ? v3Global.opt.prefix() - : v3Global.opt.protectLib(); + *of << "get_target_property(TOP_TARGET_NAME \"${TARGET}\" NAME)\n"; for (V3HierBlockPlan::HierVector::const_iterator it = hierBlocks.begin(); it != hierBlocks.end(); ++it) { const V3HierBlock* hblockp = *it; const V3HierBlock::HierBlockSet& children = hblockp->children(); const string prefix = hblockp->hierPrefix(); *of << "add_library(" << prefix << " STATIC)\n"; - *of << "target_link_libraries(" << topTarget << " PRIVATE " << prefix << ")\n"; + *of << "target_link_libraries(${TOP_TARGET_NAME} PRIVATE " << prefix << ")\n"; if (!children.empty()) { *of << "target_link_libraries(" << prefix << " INTERFACE"; for (V3HierBlock::HierBlockSet::const_iterator child = children.begin(); @@ -223,16 +222,17 @@ class CMakeEmitter { } *of << "verilate(" << prefix << " PREFIX " << prefix << " TOP_MODULE " << hblockp->modp()->name() << " DIRECTORY " - << deslash("${CMAKE_CURRENT_BINARY_DIR}/" + prefix) << " SOURCES "; + << deslash(v3Global.opt.makeDir() + "/" + prefix) << " SOURCES "; for (V3HierBlock::HierBlockSet::const_iterator child = children.begin(); child != children.end(); ++child) { - *of << deslash(" ${CMAKE_CURRENT_BINARY_DIR}/" + (*child)->hierWrapper(true)); + *of << " " + << deslash(v3Global.opt.makeDir() + "/" + (*child)->hierWrapper(true)); } *of << " "; const string vFile = hblockp->vFileIfNecessary(); if (!vFile.empty()) *of << vFile << " "; const V3StringList& vFiles = v3Global.opt.vFiles(); - for (const string& i : vFiles) *of << V3Os::filenameRealPath(i); + for (const string& i : vFiles) *of << V3Os::filenameRealPath(i) << " "; *of << " VERILATOR_ARGS "; *of << "-f " << deslash(hblockp->commandArgsFileName(true)) << " -CFLAGS -fPIC" // hierarchical block will be static, but may be linked @@ -240,11 +240,12 @@ class CMakeEmitter { << ")\n"; } *of << "\n# Verilate the top module that refers protect-lib wrappers of above\n"; - *of << "verilate(" << topTarget << " PREFIX " << v3Global.opt.prefix() - << " TOP_MODULE " << v3Global.rootp()->topModulep()->name() << " DIRECTORY " - << deslash("${CMAKE_CURRENT_BINARY_DIR}/" + topTarget + ".dir") << " SOURCES "; + *of << "verilate(${TOP_TARGET_NAME} PREFIX " << v3Global.opt.prefix() << " TOP_MODULE " + << v3Global.rootp()->topModulep()->name() << " DIRECTORY " + << deslash(v3Global.opt.makeDir()) << " SOURCES "; for (V3HierBlockPlan::const_iterator it = planp->begin(); it != planp->end(); ++it) { - *of << deslash(" ${CMAKE_CURRENT_BINARY_DIR}/" + it->second->hierWrapper(true)); + *of << " " + << deslash(v3Global.opt.makeDir() + "/" + it->second->hierWrapper(true)); } *of << " " << deslash(cmake_list(v3Global.opt.vFiles())); *of << " VERILATOR_ARGS "; diff --git a/src/V3HierBlock.cpp b/src/V3HierBlock.cpp index ae1bb1f86..fd0606ab0 100644 --- a/src/V3HierBlock.cpp +++ b/src/V3HierBlock.cpp @@ -218,8 +218,8 @@ void V3HierBlock::writeCommandArgsFile(bool forCMake) const { child != m_children.end(); ++child) { *of << v3Global.opt.makeDir() << "/" << (*child)->hierWrapper(true) << "\n"; } + *of << "-Mdir " << v3Global.opt.makeDir() << "/" << hierPrefix() << " \n"; } - *of << "-Mdir " << v3Global.opt.makeDir() << "/" << hierPrefix() << " \n"; V3HierWriteCommonInputs(this, of.get(), forCMake); const V3StringList& commandOpts = commandArgs(false); for (const string& opt : commandOpts) *of << opt << "\n"; diff --git a/test_regress/t/t_hier_block_cmake.pl b/test_regress/t/t_hier_block_cmake.pl index 24760fe3c..7f7c28cba 100755 --- a/test_regress/t/t_hier_block_cmake.pl +++ b/test_regress/t/t_hier_block_cmake.pl @@ -13,38 +13,28 @@ clean_objs(); scenarios(simulator => 1); top_filename("t/t_hier_block.v"); -# Travis environment offers 2 VCPUs, 2 thread setting causes the following warning. -# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads. -# So use 6 threads here though it's not optimal in performace wise, but ok. -compile( - verilator_make_gmake => 0, - verilator_make_cmake => 1, - v_flags2 => ['t/t_hier_block.cpp'], - verilator_flags2 => ['--stats', - '--hierarchical', - '--CFLAGS', "'-pipe -DCPP_MACRO=cplusplus '", - '--make cmake', - ($Self->{vltmt} ? ' --threads 6' : '')], +if (!$Self->have_cmake) { + $Self->skip("Test requires CMake; ignore error since not available or version too old\n"); +} else { + run(logfile => "$Self->{obj_dir}/cmake.log", + cmd => ['cd "' . $Self->{obj_dir} . '" && cmake ' . $Self->{t_dir} . '/t_hier_block_cmake', + "-DCMAKE_PREFIX_PATH=$ENV{VERILATOR_ROOT}", + ($Self->{vltmt} ? '-DTEST_THREADS=6' : '') + ]); + + run(logfile => "$Self->{obj_dir}/build.log", + cmd => ['cd "' . $Self->{obj_dir} . '" && cmake --build', '.'] ); -if (!$Self->have_cmake) { - skip("cmake is not installed"); -} else { - my $cmakecache = $Self->{obj_dir}."/CMakeCache.txt"; - if (! -e $cmakecache) { - error("$cmakecache does not exist.") - } - - execute( - check_finished => 1, - ); - -file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", /^module\s+(\S+)\s+/, "sub0"); -file_grep($Self->{obj_dir} . "/Vsub1/sub1.sv", /^module\s+(\S+)\s+/, "sub1"); -file_grep($Self->{obj_dir} . "/Vsub2/sub2.sv", /^module\s+(\S+)\s+/, "sub2"); -file_grep($Self->{obj_dir} . '/Vt_hier_block_cmake__stats.txt', qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10); -file_grep($Self->{run_log_filename}, qr/MACRO:(\S+) is defined/i, "cplusplus"); - + run(logfile => "$Self->{obj_dir}/run.log", + cmd => ['cd "' . $Self->{obj_dir} . '" && ./t_hier_block_cmake', '.'] + ); + my $target_dir = $Self->{obj_dir} .'/CMakeFiles/t_hier_block_cmake.dir/Vt_hier_block.dir/'; + file_grep($target_dir . 'Vsub0/sub0.sv', /^module\s+(\S+)\s+/, "sub0"); + file_grep($target_dir . 'Vsub1/sub1.sv', /^module\s+(\S+)\s+/, "sub1"); + file_grep($target_dir . 'Vsub2/sub2.sv', /^module\s+(\S+)\s+/, "sub2"); + file_grep($target_dir . 'Vt_hier_block__stats.txt', qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10); + file_grep($Self->{obj_dir} . '/run.log', qr/MACRO:(\S+) is defined/i, "cplusplus"); } ok(1); diff --git a/test_regress/t/t_hier_block_cmake/CMakeLists.txt b/test_regress/t/t_hier_block_cmake/CMakeLists.txt new file mode 100644 index 000000000..6e7c91bbe --- /dev/null +++ b/test_regress/t/t_hier_block_cmake/CMakeLists.txt @@ -0,0 +1,27 @@ +###################################################################### +# +# DESCRIPTION: CMake script for t_hier_block_cmake +# +# Copyright 2003-2020 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 +# +###################################################################### + +cmake_minimum_required (VERSION 3.8) +project (t_hier_block_cmake) + +find_package(verilator REQUIRED) + +add_executable(t_hier_block_cmake main.cpp ../t_hier_block.cpp) + +if(TEST_THREADS) + set(VERILATOR_OPTIONS "${VERILATOR_OPTIONS}" --threads ${TEST_THREADS}) +endif() +set(VERILATOR_OPTIONS "${VERILATOR_OPTIONS}" --hierarchical --stats --CFLAGS "-pipe -DCPP_MACRO=cplusplus") + +verilate(t_hier_block_cmake VERILATOR_ARGS ${VERILATOR_OPTIONS} SOURCES + ../t_hier_block.v ) + diff --git a/test_regress/t/t_hier_block_cmake/main.cpp b/test_regress/t/t_hier_block_cmake/main.cpp new file mode 100644 index 000000000..b26551f4d --- /dev/null +++ b/test_regress/t/t_hier_block_cmake/main.cpp @@ -0,0 +1,27 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2020 by Yutetsu TAKATSUKASA. 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 +// +//************************************************************************* + +#include +#include "Vt_hier_block.h" + +int main(int argc, char *argv[]) { + std::unique_ptr top{new Vt_hier_block("top")}; + Verilated::commandArgs(argc, argv); + for (int i = 0; i < 100 && !Verilated::gotFinish(); ++i) { + top->eval(); + top->clk ^= 1; + } + if (!Verilated::gotFinish()) { + vl_fatal(__FILE__, __LINE__, "main", "%Error: Timeout; never got a $finish"); + } + top->final(); + return 0; +}