Tablegen: undefined reference to build.. while linking

Hi,
I try to translate a declare Operation like
int a=b in AST
I add 2 custom builders in MIRStatements.td

def VariableDeclOp : MIROp<"vardecl", []> {
  let summary = "A variable declaration";

  let arguments = (ins StrAttr:$name, I32Attr:$init);
  let results = (outs MooreLValueType:$result);
  let assemblyFormat = [{
    $name `=` $init attr-dict `:` custom<LValueType>(type($result))
  }];
  let builders = [
    OpBuilder<(ins "::mlir::Type":$result,"::mlir::StringAttr":$name,"::mlir::StringAttr":$init)>,
    OpBuilder<(ins "::mlir::Type":$result,"::mlir::StringAttr":$name,"std::string_view":$init)>,
  ];
}

Then I try to call build like this:

    case ExpressionKind::NamedValue:{
      rootBuilder.create<moore::VariableDeclOp>(convertLocation(varAst.location),
                        moore::LValueType::get(loweredType),
                        rootBuilder.getStringAttr(varAst.name),
                        rootBuilder.getStringAttr(expr.getSymbolReference()->name));
    }break;

Then I try to build circt and linker complained as follow

in function `circt::moore::VariableDeclOp mlir::OpBuilder::create<circt::moore::VariableDeclOp, circt::moore::LValueType, mlir::StringAttr, mlir::StringAttr>(mlir::Location, circt::moore::LValueType&&, mlir::StringAttr&&, mlir::StringAttr&&)':
Expr.cpp:(.text._ZN4mlir9OpBuilder6createIN5circt5moore14VariableDeclOpEJNS3_10LValueTypeENS_10StringAttrES6_EEET_NS_8LocationEDpOT0_[_ZN4mlir9OpBuilder6createIN5circt5moore14VariableDeclOpEJNS3_10LValueTypeENS_10StringAttrES6_EEET_NS_8LocationEDpOT0_]+0xd1): undefined reference to `circt::moore::VariableDeclOp::build(mlir::OpBuilder&, mlir::OperationState&, mlir::Type, mlir::StringAttr, mlir::StringAttr)'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

what should I do to call the build function which generated by tablegen correctly?

the build function in Moore.h.inc that generated by tablegen as follow:

  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type result, ::mlir::StringAttr name, ::mlir::StringAttr init);
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type result, ::mlir::StringAttr name, std::string_view init);
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type result, ::mlir::StringAttr name, ::mlir::IntegerAttr init);
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::StringAttr name, ::mlir::IntegerAttr init);
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type result, ::llvm::StringRef name, uint32_t init);
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::llvm::StringRef name, uint32_t init);
  static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {});

You don’t provide a body here, so they need to be implemented in a C++ implementation file.