Building with -DNEMO_SPEECH_WITH_NORM=ON fails when the runtime is compiled with gcc-14:
.deps/itn/include/fst/fst.h:690:59: error: no match for 'operator=' (operand types are
'std::unique_ptr<fst::SymbolTable, std::default_delete<fst::SymbolTable> >' and 'fst::SymbolTable*')
.deps/itn/include/fst/fst.h:691:59: error: (same, next line)
FAILED: src/common/CMakeFiles/nemo_speech_text_normalization.dir/text_normalization/fst_normalizer.cpp.o
Cause
scripts/build_itn_deps.sh pins https://github.com/sarane22/openfst.git at fc23b4cf529429284b874a26f28b15c6cc94f404. In that tree, FstImpl::operator= (src/include/fst/fst.h:690-691) is:
isymbols_ = impl.isymbols_ ? impl.isymbols_->Copy() : nullptr;
osymbols_ = impl.osymbols_ ? impl.osymbols_->Copy() : nullptr;
isymbols_ and osymbols_ are std::unique_ptr<SymbolTable>, while SymbolTable::Copy() is declared virtual SymbolTable *Copy() const (symbol-table.h:411). So the conditional yields SymbolTable * and the statement is unique_ptr<SymbolTable> = SymbolTable *.
std::unique_ptr has exactly three assignment operators: from unique_ptr&&, from a convertible unique_ptr<U,E>&&, and from nullptr_t. None accepts a raw pointer, in any C++ standard, so these two lines are ill-formed everywhere. The same class spells the identical operation correctly 78 lines later in SetInputSymbols (fst.h:768), using .reset(...), which suggests a plain typo.
It has gone unnoticed because nothing instantiates FstImpl::operator=, and compilers before gcc-14 defer the check. gcc-14 resolves non-dependent operator expressions at template definition time, so it rejects the line in any translation unit that merely includes the header. The diagnostic header confirms this:
fst.h: In member function 'fst::internal::FstImpl<Arc>& fst::internal::FstImpl<Arc>::operator=(const fst::internal::FstImpl<Arc>&)':
That is In member function, not In instantiation of ... required from here, and there is no instantiation backtrace.
Compiler reading fst.h |
Result |
gcc-12 (what build_itn_deps.sh uses to build OpenFST) |
OK, check deferred |
| gcc-13 |
OK, check deferred |
| gcc-14 |
error at definition time |
fst_normalizer.cpp is the only translation unit here that includes OpenFST, so it is the only one that breaks. Note this is not a mismatch between gcc-12-built artifacts and a gcc-14 compile: build_itn_deps.sh installs the headers with cp -a, so they are verbatim source.
Fix
isymbols_.reset(impl.isymbols_ ? impl.isymbols_->Copy() : nullptr);
osymbols_.reset(impl.osymbols_ ? impl.osymbols_->Copy() : nullptr);
That matches the existing spelling in SetInputSymbols and compiles on every version tested. Since the affected function is never instantiated, libfst.so cannot contain it, so there is no ABI or ODR consequence.
The fix belongs in the pinned sarane22/openfst fork, or the pin could move to a revision that already has it.
Context
Found while packaging NeMo-Speech.cpp as a backend for LocalAI (pin 2e12e2def8a98ed06666f7ee3ca94e7193e04be4), where the build image defaults to gcc-14. Reproduced standalone from a file whose entire content is #include <fst/fst.h>, compiled with gcc 14.2: exactly 2 errors, matching CI. Downstream we patch the two lines in the installed prefix before configuring.
Happy to send a PR to whichever repo is the right home for it.
Building with
-DNEMO_SPEECH_WITH_NORM=ONfails when the runtime is compiled with gcc-14:Cause
scripts/build_itn_deps.shpinshttps://github.com/sarane22/openfst.gitatfc23b4cf529429284b874a26f28b15c6cc94f404. In that tree,FstImpl::operator=(src/include/fst/fst.h:690-691) is:isymbols_andosymbols_arestd::unique_ptr<SymbolTable>, whileSymbolTable::Copy()is declaredvirtual SymbolTable *Copy() const(symbol-table.h:411). So the conditional yieldsSymbolTable *and the statement isunique_ptr<SymbolTable> = SymbolTable *.std::unique_ptrhas exactly three assignment operators: fromunique_ptr&&, from a convertibleunique_ptr<U,E>&&, and fromnullptr_t. None accepts a raw pointer, in any C++ standard, so these two lines are ill-formed everywhere. The same class spells the identical operation correctly 78 lines later inSetInputSymbols(fst.h:768), using.reset(...), which suggests a plain typo.It has gone unnoticed because nothing instantiates
FstImpl::operator=, and compilers before gcc-14 defer the check. gcc-14 resolves non-dependent operator expressions at template definition time, so it rejects the line in any translation unit that merely includes the header. The diagnostic header confirms this:That is
In member function, notIn instantiation of ... required from here, and there is no instantiation backtrace.fst.hbuild_itn_deps.shuses to build OpenFST)fst_normalizer.cppis the only translation unit here that includes OpenFST, so it is the only one that breaks. Note this is not a mismatch between gcc-12-built artifacts and a gcc-14 compile:build_itn_deps.shinstalls the headers withcp -a, so they are verbatim source.Fix
That matches the existing spelling in
SetInputSymbolsand compiles on every version tested. Since the affected function is never instantiated,libfst.socannot contain it, so there is no ABI or ODR consequence.The fix belongs in the pinned
sarane22/openfstfork, or the pin could move to a revision that already has it.Context
Found while packaging NeMo-Speech.cpp as a backend for LocalAI (pin
2e12e2def8a98ed06666f7ee3ca94e7193e04be4), where the build image defaults to gcc-14. Reproduced standalone from a file whose entire content is#include <fst/fst.h>, compiled with gcc 14.2: exactly 2 errors, matching CI. Downstream we patch the two lines in the installed prefix before configuring.Happy to send a PR to whichever repo is the right home for it.