Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: use llvm-config for bitcoin-tidy example #28245

Merged
merged 1 commit into from
Aug 11, 2023

Conversation

fanquake
Copy link
Member

@fanquake fanquake commented Aug 9, 2023

An LLVM installation will have llvm-config available to query for info. Ask it for the --cmakedir, and use that in our bitcoin-tidy example, rather than listing multiple different (potential) paths per distro/OS etc.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 9, 2023

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK TheCharlatan, theuni, jonatack

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Copy link
Contributor

@TheCharlatan TheCharlatan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 8651b99

@fanquake fanquake requested a review from theuni August 9, 2023 13:22
make -C build -j$(nproc)
cmake -S . -B build -DLLVM_DIR=$(llvm-config --libdir)/cmake/llvm -DCMAKE_BUILD_TYPE=Release

cmake --build build -j$(nproc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK on improving the example usage. Any tips on how to make it work with macOS 13.5 arm64? Seeing Undefined symbols for architecture arm64 errors at this step in both versions of this README (thanks!)

terminal output

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake --version
cmake version 3.27.1
jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake -S . -B build -DLLVM_DIR=$(llvm-config --libdir)/cmake/llvm -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is AppleClang 14.0.3.14030022
-- The CXX compiler identification is AppleClang 14.0.3.14030022
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/homebrew/opt/ccache/libexec/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/homebrew/opt/ccache/libexec/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_FFI_CALL
-- Performing Test HAVE_FFI_CALL - Success
-- Found FFI: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libffi.tbd  
-- Performing Test Terminfo_LINKABLE
-- Performing Test Terminfo_LINKABLE - Success
-- Found Terminfo: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libcurses.tbd  
-- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libz.tbd (found version "1.2.11")  
-- Found zstd: /opt/homebrew/lib/libzstd.dylib  
-- Found LibXml2: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libxml2.tbd (found version "2.9.13") 
-- Found LLVM 16.0.6
-- Found clang-tidy: /opt/homebrew/Cellar/llvm/16.0.6/bin/clang-tidy
-- Configuring done (1.1s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build
jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake --build build -j11                                                                    
[ 33%] Building CXX object CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o
[ 66%] Building CXX object CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Finder' [-Wunused-parameter]
AST_MATCHER(clang::StringLiteral, unterminated)
^
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:112:56: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
                                                       ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Builder' [-Wunused-parameter]
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:113:63: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
                                                              ^
2 warnings generated.
[100%] Linking CXX shared module libbitcoin-tidy.so
Undefined symbols for architecture arm64:
  "llvm::SmallVectorBase<unsigned int>::mallocForGrow(void*, unsigned long, unsigned long, unsigned long&)", referenced from:
      llvm::SmallVectorTemplateBase<clang::FixItHint, false>::reserveForParamAndGetAddress(clang::FixItHint const&, unsigned long) in logprintf.cpp.o
  "llvm::DisableABIBreakingChecks", referenced from:
      llvm::VerifyDisableABIBreakingChecks in bitcoin-tidy.cpp.o
      llvm::VerifyDisableABIBreakingChecks in logprintf.cpp.o
  "llvm::Registry<clang::tidy::ClangTidyModule>::add_node(llvm::Registry<clang::tidy::ClangTidyModule>::node*)", referenced from:
      __GLOBAL__sub_I_bitcoin_tidy.cpp in bitcoin-tidy.cpp.o
  "clang::ASTNodeKind::getFromNode(clang::Decl const&)", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ASTNodeKind::getFromNode(clang::Stmt const&)", referenced from:
      clang::ast_matchers::internal::matcher_thisPointerType0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_onImplicitObjectArgument0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_callee1Matcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_callee1Matcher<clang::CXXMemberCallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CXXMemberCallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::MatchFinder::addMatcher(clang::ast_matchers::internal::Matcher<clang::Stmt> const&, clang::ast_matchers::MatchFinder::MatchCallback*)", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::MatchFinder::MatchCallback::~MatchCallback()", referenced from:
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
  "clang::ast_matchers::cxxMemberCallExpr", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::anyOf", referenced from:
      clang::ast_matchers::internal::matcher_thisPointerType0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::callExpr", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::internal::HasNameMatcher::HasNameMatcher(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>)", referenced from:
      clang::ast_matchers::hasName(llvm::StringRef) in logprintf.cpp.o
  "clang::ast_matchers::internal::DynTypedMatcher::trueMatcher(clang::ASTNodeKind)", referenced from:
      clang::ast_matchers::internal::BindableMatcher<clang::QualType> clang::ast_matchers::internal::makeAllOfComposite<clang::QualType>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::QualType> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXRecordDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXRecordDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXRecordDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::FunctionDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::FunctionDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::FunctionDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::StringLiteral> clang::ast_matchers::internal::makeAllOfComposite<clang::StringLiteral>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::StringLiteral> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CallExpr> clang::ast_matchers::internal::makeAllOfComposite<clang::CallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CallExpr> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXMethodDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXMethodDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXMemberCallExpr> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXMemberCallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr> const*>) in logprintf.cpp.o
      ...
  "clang::ast_matchers::internal::DynTypedMatcher::constructVariadic(clang::ast_matchers::internal::DynTypedMatcher::VariadicOperator, clang::ASTNodeKind, std::__1::vector<clang::ast_matchers::internal::DynTypedMatcher, std::__1::allocator<clang::ast_matchers::internal::DynTypedMatcher>>)", referenced from:
      clang::ast_matchers::internal::VariadicOperatorMatcher<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>>::operator clang::ast_matchers::internal::Matcher<clang::Expr><clang::Expr>() && in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::QualType> clang::ast_matchers::internal::makeAllOfComposite<clang::QualType>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::QualType> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXRecordDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXRecordDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXRecordDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::FunctionDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::FunctionDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::FunctionDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::StringLiteral> clang::ast_matchers::internal::makeAllOfComposite<clang::StringLiteral>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::StringLiteral> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CallExpr> clang::ast_matchers::internal::makeAllOfComposite<clang::CallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CallExpr> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXMethodDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXMethodDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl> const*>) in logprintf.cpp.o
      ...
  "clang::DiagnosticsEngine::EmitCurrentDiagnostic(bool)", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::Expr::IgnoreParenImpCasts()", referenced from:
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CXXMemberCallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::Expr::getReferencedDeclOfCallee()", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::tidy::ClangTidyCheck::run(clang::ast_matchers::MatchFinder::MatchResult const&)", referenced from:
      vtable for bitcoin::LogPrintfCheck in logprintf.cpp.o
  "clang::tidy::ClangTidyCheck::diag(clang::SourceLocation, llvm::StringRef, clang::DiagnosticIDs::Level)", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::tidy::ClangTidyCheck::ClangTidyCheck(llvm::StringRef, clang::tidy::ClangTidyContext*)", referenced from:
      std::__1::__function::__func<void clang::tidy::ClangTidyCheckFactories::registerCheck<bitcoin::LogPrintfCheck>(llvm::StringRef)::'lambda'(llvm::StringRef, clang::tidy::ClangTidyContext*), std::__1::allocator<void clang::tidy::ClangTidyCheckFactories::registerCheck<bitcoin::LogPrintfCheck>(llvm::StringRef)::'lambda'(llvm::StringRef, clang::tidy::ClangTidyContext*)>, std::__1::unique_ptr<clang::tidy::ClangTidyCheck, std::__1::default_delete<clang::tidy::ClangTidyCheck>> (llvm::StringRef, clang::tidy::ClangTidyContext*)>::operator()(llvm::StringRef&&, clang::tidy::ClangTidyContext*&&) in bitcoin-tidy.cpp.o
  "clang::tidy::ClangTidyModule::getModuleOptions()", referenced from:
      vtable for BitcoinModule in bitcoin-tidy.cpp.o
  "clang::tidy::ClangTidyCheckFactories::registerCheckFactory(llvm::StringRef, std::__1::function<std::__1::unique_ptr<clang::tidy::ClangTidyCheck, std::__1::default_delete<clang::tidy::ClangTidyCheck>> (llvm::StringRef, clang::tidy::ClangTidyContext*)>)", referenced from:
      BitcoinModule::addCheckFactories(clang::tidy::ClangTidyCheckFactories&) in bitcoin-tidy.cpp.o
  "clang::ASTNodeKind::isBaseOf(clang::ASTNodeKind, unsigned int*) const", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::TemplateName::getAsTemplateDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::MatchFinder::MatchCallback::getCheckTraversalKind() const", referenced from:
      vtable for bitcoin::LogPrintfCheck in logprintf.cpp.o
  "clang::ast_matchers::internal::ASTMatchFinder::isTraversalIgnoringImplicitNodes() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CXXMemberCallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::internal::DynTypedMatcher::matches(clang::DynTypedNode const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const", referenced from:
      clang::ast_matchers::internal::matcher_thisPointerType0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_onImplicitObjectArgument0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_pointsTo0Matcher::matches(clang::QualType const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasType0Matcher<clang::Expr, clang::ast_matchers::internal::Matcher<clang::QualType>>::matches(clang::Expr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_callee1Matcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      ...
  "clang::ast_matchers::internal::DynTypedMatcher::tryBind(llvm::StringRef) const", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::internal::DynTypedMatcher::dynCastTo(clang::ASTNodeKind) const", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::VariadicFunction<clang::ast_matchers::internal::BindableMatcher<clang::Stmt>, clang::ast_matchers::internal::Matcher<clang::CallExpr>, &clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::makeDynCastAllOfComposite<clang::Stmt, clang::CallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CallExpr> const*>)>::operator()<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>>(clang::ast_matchers::internal::Matcher<clang::CallExpr> const&, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>> const&) const in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::VariadicFunction<clang::ast_matchers::internal::BindableMatcher<clang::Stmt>, clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr>, &clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::makeDynCastAllOfComposite<clang::Stmt, clang::CXXMemberCallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr> const*>)>::operator()<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_callee1Matcher, void (clang::ast_matchers::internal::TypeList<clang::ObjCMessageExpr, clang::CallExpr>), clang::ast_matchers::internal::Matcher<clang::Decl>>, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>>(clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr> const&, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_callee1Matcher, void (clang::ast_matchers::internal::TypeList<clang::ObjCMessageExpr, clang::CallExpr>), clang::ast_matchers::internal::Matcher<clang::Decl>> const&, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>> const&) const in logprintf.cpp.o
      clang::ast_matchers::internal::VariadicOperatorMatcher<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>>::operator clang::ast_matchers::internal::Matcher<clang::Expr><clang::Expr>() && in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::QualType> clang::ast_matchers::internal::makeAllOfComposite<clang::QualType>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::QualType> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXRecordDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXRecordDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXRecordDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::FunctionDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::FunctionDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::FunctionDecl> const*>) in logprintf.cpp.o
      ...
  "clang::StringLiteral::getLocationOfByte(unsigned int, clang::SourceManager const&, clang::LangOptions const&, clang::TargetInfo const&, unsigned int*, unsigned int*) const", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::CXXMemberCallExpr::getImplicitObjectArgument() const", referenced from:
      clang::ast_matchers::internal::matcher_onImplicitObjectArgument0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ObjCInterfaceType::getDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::InjectedClassNameType::getDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::Type::getPointeeType() const", referenced from:
      clang::ast_matchers::internal::matcher_pointsTo0Matcher::matches(clang::QualType const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::Type::getUnqualifiedDesugaredType() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::TagType::getDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::UsingType::getUnderlyingType() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "vtable for clang::tidy::ClangTidyCheck", referenced from:
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libbitcoin-tidy.so] Error 1
make[1]: *** [CMakeFiles/bitcoin-tidy.dir/all] Error 2
make: *** [all] Error 2

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use vanilla LLVM/Clang, Not Apple LLVM/Clang.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, LLVM should be header-only, so I think this is indicative of some real problem.

Could you please paste your link line generated by make VERBOSE=1? For Linux mine is:
/usr/bin/c++ -fPIC -O3 -DNDEBUG -shared -o libbitcoin-tidy.so "CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o" "CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o"


A few possibilities:

  1. Something about the way it's being compiled/linked makes ld64 grumpy.
  2. Something related to this magic line.

For 1:

Could you please try this and seeing if anything changes for better or worse (and see how the link-line changes)?

diff --git a/contrib/devtools/bitcoin-tidy/CMakeLists.txt b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
index 9ed18696d4..ae168c77af 100644
--- a/contrib/devtools/bitcoin-tidy/CMakeLists.txt
+++ b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
@@ -14,7 +14,7 @@ find_program(CLANG_TIDY_EXE NAMES "clang-tidy-${LLVM_VERSION_MAJOR}" "clang-tidy
 message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
 message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXE}")

-add_library(bitcoin-tidy MODULE bitcoin-tidy.cpp logprintf.cpp)
+add_library(bitcoin-tidy SHARED bitcoin-tidy.cpp logprintf.cpp)
 target_include_directories(bitcoin-tidy SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS})

 # Disable RTTI and exceptions as necessary

For 2, I must admit I haven't really looked into what the magic is doing so there's a good chance I didn't get it hooked up correctly. I'm guessing the objects need to reference each-other to keep symbols from being optimized out. Upstream LLVM seems kinda inconsistent about how they use the anchors, but I think this one would be a good one to follow:

Could you please try:

diff --git a/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp b/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
index 0f34d37793..ec89590aa8 100644
--- a/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
+++ b/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
@@ -19,4 +19,4 @@ public:
 static clang::tidy::ClangTidyModuleRegistry::Add<BitcoinModule>
     X("bitcoin-module", "Adds bitcoin checks.");

-volatile int BitcoinModuleAnchorSource = 0;
+extern volatile int BitcoinModuleAnchorSource;
diff --git a/contrib/devtools/bitcoin-tidy/logprintf.cpp b/contrib/devtools/bitcoin-tidy/logprintf.cpp
index 1690c8fde0..b79e6f1486 100644
--- a/contrib/devtools/bitcoin-tidy/logprintf.cpp
+++ b/contrib/devtools/bitcoin-tidy/logprintf.cpp
@@ -60,3 +60,5 @@ void LogPrintfCheck::check(const clang::ast_matchers::MatchFinder::MatchResult&
 }

 } // namespace bitcoin
+
+int BitcoinModuleAnchorSource = 0;

Copy link
Member

@jonatack jonatack Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @fanquake and @theuni. I thought I was using clang/llvm from homebrew (and have export PATH="/opt/homebrew/opt/llvm/bin:$PATH" in .zshrc) but could be missing something (edit: and the cmake output below prints AppleClang 14). Tried 1. and 2. above and still see Undefined symbols for architecture arm64 at the second step.

output of make VERBOSE=1

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ clang --version  
Homebrew clang version 16.0.6
Target: arm64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm/bin

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ which clang      
/opt/homebrew/opt/llvm/bin/clang

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ rm -rf build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake -S . -B build -DLLVM_DIR=$(llvm-config --cmakedir) -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is AppleClang 14.0.3.14030022
-- The CXX compiler identification is AppleClang 14.0.3.14030022
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/homebrew/opt/ccache/libexec/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/homebrew/opt/ccache/libexec/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_FFI_CALL
-- Performing Test HAVE_FFI_CALL - Success
-- Found FFI: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libffi.tbd  
-- Performing Test Terminfo_LINKABLE
-- Performing Test Terminfo_LINKABLE - Success
-- Found Terminfo: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libcurses.tbd  
-- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libz.tbd (found version "1.2.11")  
-- Found zstd: /opt/homebrew/lib/libzstd.dylib  
-- Found LibXml2: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libxml2.tbd (found version "2.9.13") 
-- Found LLVM 16.0.6
-- Found clang-tidy: /opt/homebrew/Cellar/llvm/16.0.6/bin/clang-tidy
-- Configuring done (1.1s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ make VERBOSE=1                                                                     
make: *** No targets specified and no makefile found.  Stop.

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cd build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build$ make VERBOSE=1
/opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -S/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy -B/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build --check-build-system CMakeFiles/Makefile.cmake 0
/opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -E cmake_progress_start /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/CMakeFiles /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build//CMakeFiles/progress.marks
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/Makefile2 all
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/bitcoin-tidy.dir/build.make CMakeFiles/bitcoin-tidy.dir/depend
cd /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build && /opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/CMakeFiles/bitcoin-tidy.dir/DependInfo.cmake "--color="
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/bitcoin-tidy.dir/build.make CMakeFiles/bitcoin-tidy.dir/build
[ 33%] Building CXX object CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o
/opt/homebrew/opt/ccache/libexec/c++ -Dbitcoin_tidy_EXPORTS -isystem /opt/homebrew/Cellar/llvm/16.0.6/include -O3 -DNDEBUG -std=c++17 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk -fPIC -fno-rtti -fno-exceptions -Wall -Wextra -MD -MT CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o -MF CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o.d -o CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o -c /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
[ 66%] Building CXX object CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o
/opt/homebrew/opt/ccache/libexec/c++ -Dbitcoin_tidy_EXPORTS -isystem /opt/homebrew/Cellar/llvm/16.0.6/include -O3 -DNDEBUG -std=c++17 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk -fPIC -fno-rtti -fno-exceptions -Wall -Wextra -MD -MT CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o -MF CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o.d -o CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o -c /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Finder' [-Wunused-parameter]
AST_MATCHER(clang::StringLiteral, unterminated)
^
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:112:56: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
                                                       ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Builder' [-Wunused-parameter]
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:113:63: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
                                                              ^
2 warnings generated.
[100%] Linking CXX shared module libbitcoin-tidy.so
/opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -E cmake_link_script CMakeFiles/bitcoin-tidy.dir/link.txt --verbose=1
/opt/homebrew/opt/ccache/libexec/c++ -O3 -DNDEBUG -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk -bundle -Wl,-headerpad_max_install_names -o libbitcoin-tidy.so "CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o" "CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o" 
Undefined symbols for architecture arm64:
  "llvm::SmallVectorBase<unsigned int>::mallocForGrow(void*, unsigned long, unsigned long, unsigned long&)", referenced from:
      llvm::SmallVectorTemplateBase<clang::FixItHint, false>::reserveForParamAndGetAddress(clang::FixItHint const&, unsigned long) in logprintf.cpp.o
  "llvm::DisableABIBreakingChecks", referenced from:
      llvm::VerifyDisableABIBreakingChecks in bitcoin-tidy.cpp.o
      llvm::VerifyDisableABIBreakingChecks in logprintf.cpp.o
  "llvm::Registry<clang::tidy::ClangTidyModule>::add_node(llvm::Registry<clang::tidy::ClangTidyModule>::node*)", referenced from:
      __GLOBAL__sub_I_bitcoin_tidy.cpp in bitcoin-tidy.cpp.o
  "clang::ASTNodeKind::getFromNode(clang::Decl const&)", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ASTNodeKind::getFromNode(clang::Stmt const&)", referenced from:
      clang::ast_matchers::internal::matcher_thisPointerType0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_onImplicitObjectArgument0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_callee1Matcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_callee1Matcher<clang::CXXMemberCallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CXXMemberCallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::MatchFinder::addMatcher(clang::ast_matchers::internal::Matcher<clang::Stmt> const&, clang::ast_matchers::MatchFinder::MatchCallback*)", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::MatchFinder::MatchCallback::~MatchCallback()", referenced from:
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
  "clang::ast_matchers::cxxMemberCallExpr", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::anyOf", referenced from:
      clang::ast_matchers::internal::matcher_thisPointerType0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::callExpr", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::internal::HasNameMatcher::HasNameMatcher(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>)", referenced from:
      clang::ast_matchers::hasName(llvm::StringRef) in logprintf.cpp.o
  "clang::ast_matchers::internal::DynTypedMatcher::trueMatcher(clang::ASTNodeKind)", referenced from:
      clang::ast_matchers::internal::BindableMatcher<clang::QualType> clang::ast_matchers::internal::makeAllOfComposite<clang::QualType>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::QualType> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXRecordDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXRecordDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXRecordDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::FunctionDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::FunctionDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::FunctionDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::StringLiteral> clang::ast_matchers::internal::makeAllOfComposite<clang::StringLiteral>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::StringLiteral> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CallExpr> clang::ast_matchers::internal::makeAllOfComposite<clang::CallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CallExpr> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXMethodDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXMethodDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXMemberCallExpr> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXMemberCallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr> const*>) in logprintf.cpp.o
      ...
  "clang::ast_matchers::internal::DynTypedMatcher::constructVariadic(clang::ast_matchers::internal::DynTypedMatcher::VariadicOperator, clang::ASTNodeKind, std::__1::vector<clang::ast_matchers::internal::DynTypedMatcher, std::__1::allocator<clang::ast_matchers::internal::DynTypedMatcher>>)", referenced from:
      clang::ast_matchers::internal::VariadicOperatorMatcher<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>>::operator clang::ast_matchers::internal::Matcher<clang::Expr><clang::Expr>() && in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::QualType> clang::ast_matchers::internal::makeAllOfComposite<clang::QualType>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::QualType> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXRecordDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXRecordDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXRecordDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::FunctionDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::FunctionDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::FunctionDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::StringLiteral> clang::ast_matchers::internal::makeAllOfComposite<clang::StringLiteral>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::StringLiteral> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CallExpr> clang::ast_matchers::internal::makeAllOfComposite<clang::CallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CallExpr> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXMethodDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXMethodDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl> const*>) in logprintf.cpp.o
      ...
  "clang::DiagnosticsEngine::EmitCurrentDiagnostic(bool)", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::Expr::IgnoreParenImpCasts()", referenced from:
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CXXMemberCallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::Expr::getReferencedDeclOfCallee()", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::tidy::ClangTidyCheck::run(clang::ast_matchers::MatchFinder::MatchResult const&)", referenced from:
      vtable for bitcoin::LogPrintfCheck in logprintf.cpp.o
  "clang::tidy::ClangTidyCheck::diag(clang::SourceLocation, llvm::StringRef, clang::DiagnosticIDs::Level)", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::tidy::ClangTidyCheck::ClangTidyCheck(llvm::StringRef, clang::tidy::ClangTidyContext*)", referenced from:
      std::__1::__function::__func<void clang::tidy::ClangTidyCheckFactories::registerCheck<bitcoin::LogPrintfCheck>(llvm::StringRef)::'lambda'(llvm::StringRef, clang::tidy::ClangTidyContext*), std::__1::allocator<void clang::tidy::ClangTidyCheckFactories::registerCheck<bitcoin::LogPrintfCheck>(llvm::StringRef)::'lambda'(llvm::StringRef, clang::tidy::ClangTidyContext*)>, std::__1::unique_ptr<clang::tidy::ClangTidyCheck, std::__1::default_delete<clang::tidy::ClangTidyCheck>> (llvm::StringRef, clang::tidy::ClangTidyContext*)>::operator()(llvm::StringRef&&, clang::tidy::ClangTidyContext*&&) in bitcoin-tidy.cpp.o
  "clang::tidy::ClangTidyModule::getModuleOptions()", referenced from:
      vtable for BitcoinModule in bitcoin-tidy.cpp.o
  "clang::tidy::ClangTidyCheckFactories::registerCheckFactory(llvm::StringRef, std::__1::function<std::__1::unique_ptr<clang::tidy::ClangTidyCheck, std::__1::default_delete<clang::tidy::ClangTidyCheck>> (llvm::StringRef, clang::tidy::ClangTidyContext*)>)", referenced from:
      BitcoinModule::addCheckFactories(clang::tidy::ClangTidyCheckFactories&) in bitcoin-tidy.cpp.o
  "clang::ASTNodeKind::isBaseOf(clang::ASTNodeKind, unsigned int*) const", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::TemplateName::getAsTemplateDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::MatchFinder::MatchCallback::getCheckTraversalKind() const", referenced from:
      vtable for bitcoin::LogPrintfCheck in logprintf.cpp.o
  "clang::ast_matchers::internal::ASTMatchFinder::isTraversalIgnoringImplicitNodes() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CXXMemberCallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ast_matchers::internal::DynTypedMatcher::matches(clang::DynTypedNode const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const", referenced from:
      clang::ast_matchers::internal::matcher_thisPointerType0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_onImplicitObjectArgument0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_pointsTo0Matcher::matches(clang::QualType const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasType0Matcher<clang::Expr, clang::ast_matchers::internal::Matcher<clang::QualType>>::matches(clang::Expr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_hasArgument0Matcher<clang::CallExpr, unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      clang::ast_matchers::internal::matcher_callee1Matcher<clang::CallExpr, clang::ast_matchers::internal::Matcher<clang::Decl>>::matches(clang::CallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
      ...
  "clang::ast_matchers::internal::DynTypedMatcher::tryBind(llvm::StringRef) const", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
  "clang::ast_matchers::internal::DynTypedMatcher::dynCastTo(clang::ASTNodeKind) const", referenced from:
      bitcoin::LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder*) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::VariadicFunction<clang::ast_matchers::internal::BindableMatcher<clang::Stmt>, clang::ast_matchers::internal::Matcher<clang::CallExpr>, &clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::makeDynCastAllOfComposite<clang::Stmt, clang::CallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CallExpr> const*>)>::operator()<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>>(clang::ast_matchers::internal::Matcher<clang::CallExpr> const&, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>> const&) const in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::VariadicFunction<clang::ast_matchers::internal::BindableMatcher<clang::Stmt>, clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr>, &clang::ast_matchers::internal::BindableMatcher<clang::Stmt> clang::ast_matchers::internal::makeDynCastAllOfComposite<clang::Stmt, clang::CXXMemberCallExpr>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr> const*>)>::operator()<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_callee1Matcher, void (clang::ast_matchers::internal::TypeList<clang::ObjCMessageExpr, clang::CallExpr>), clang::ast_matchers::internal::Matcher<clang::Decl>>, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>>>(clang::ast_matchers::internal::Matcher<clang::CXXMemberCallExpr> const&, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_callee1Matcher, void (clang::ast_matchers::internal::TypeList<clang::ObjCMessageExpr, clang::CallExpr>), clang::ast_matchers::internal::Matcher<clang::Decl>> const&, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasArgument0Matcher, void (clang::ast_matchers::internal::TypeList<clang::CallExpr, clang::CXXConstructExpr, clang::CXXUnresolvedConstructExpr, clang::ObjCMessageExpr>), unsigned int, clang::ast_matchers::internal::Matcher<clang::Expr>> const&) const in logprintf.cpp.o
      clang::ast_matchers::internal::VariadicOperatorMatcher<clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>, clang::ast_matchers::internal::PolymorphicMatcher<clang::ast_matchers::internal::matcher_hasType0Matcher, void (clang::ast_matchers::internal::TypeList<clang::Expr, clang::FriendDecl, clang::TypedefNameDecl, clang::ValueDecl, clang::CXXBaseSpecifier>), clang::ast_matchers::internal::Matcher<clang::QualType>>>::operator clang::ast_matchers::internal::Matcher<clang::Expr><clang::Expr>() && in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::QualType> clang::ast_matchers::internal::makeAllOfComposite<clang::QualType>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::QualType> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::CXXRecordDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::CXXRecordDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::CXXRecordDecl> const*>) in logprintf.cpp.o
      clang::ast_matchers::internal::BindableMatcher<clang::FunctionDecl> clang::ast_matchers::internal::makeAllOfComposite<clang::FunctionDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::FunctionDecl> const*>) in logprintf.cpp.o
      ...
  "clang::StringLiteral::getLocationOfByte(unsigned int, clang::SourceManager const&, clang::LangOptions const&, clang::TargetInfo const&, unsigned int*, unsigned int*) const", referenced from:
      bitcoin::LogPrintfCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) in logprintf.cpp.o
  "clang::CXXMemberCallExpr::getImplicitObjectArgument() const", referenced from:
      clang::ast_matchers::internal::matcher_onImplicitObjectArgument0Matcher::matches(clang::CXXMemberCallExpr const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::ObjCInterfaceType::getDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::InjectedClassNameType::getDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::Type::getPointeeType() const", referenced from:
      clang::ast_matchers::internal::matcher_pointsTo0Matcher::matches(clang::QualType const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::Type::getUnqualifiedDesugaredType() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::TagType::getDecl() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "clang::UsingType::getUnderlyingType() const", referenced from:
      clang::ast_matchers::internal::HasDeclarationMatcher<clang::QualType, clang::ast_matchers::internal::Matcher<clang::Decl>>::matchesSpecialized(clang::Type const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*) const in logprintf.cpp.o
  "vtable for clang::tidy::ClangTidyCheck", referenced from:
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
      bitcoin::LogPrintfCheck::~LogPrintfCheck() in logprintf.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libbitcoin-tidy.so] Error 1
make[1]: *** [CMakeFiles/bitcoin-tidy.dir/all] Error 2
make: *** [all] Error 2

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think I see. I can force a similar error on Linux by adding "-Wl,-no-undefined" to the link-line.

I'm guessing ld64 is opinionated about undefined symbols by default. And in this case we're relying on them.

Could you try messing with undefined symbol behavior and seeing what happens?

/opt/homebrew/opt/ccache/libexec/c++ -O3 -DNDEBUG -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk -bundle -Wl,-headerpad_max_install_names -o libbitcoin-tidy.so "CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o" "CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o" -Wl,-flat_namespace -Wl,-undefined,suppress

That should link either way (assuming I'm correct about the problem), but that doesn't necessarily mean it'll work.

(You might also try -Wl,-undefined,dynamic_lookup)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ rm -rf build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake -S . -B build -DLLVM_DIR=$(llvm-config --cmakedir) -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is AppleClang 14.0.3.14030022
-- The CXX compiler identification is AppleClang 14.0.3.14030022
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/homebrew/opt/ccache/libexec/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/homebrew/opt/ccache/libexec/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_FFI_CALL
-- Performing Test HAVE_FFI_CALL - Success
-- Found FFI: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libffi.tbd  
-- Performing Test Terminfo_LINKABLE
-- Performing Test Terminfo_LINKABLE - Success
-- Found Terminfo: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libcurses.tbd  
-- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libz.tbd (found version "1.2.11")  
-- Found zstd: /opt/homebrew/lib/libzstd.dylib  
-- Found LibXml2: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libxml2.tbd (found version "2.9.13") 
-- Found LLVM 16.0.6
-- Found clang-tidy: /opt/homebrew/Cellar/llvm/16.0.6/bin/clang-tidy
-- Configuring done (1.2s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake --build build
[ 33%] Building CXX object CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o
[ 66%] Building CXX object CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Finder' [-Wunused-parameter]
AST_MATCHER(clang::StringLiteral, unterminated)
^
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:112:56: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
                                                       ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Builder' [-Wunused-parameter]
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:113:63: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
                                                              ^
2 warnings generated.
[100%] Linking CXX shared module libbitcoin-tidy.so
[100%] Built target bitcoin-tidy

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake --build build --target bitcoin-tidy-tests                                    
[ 75%] Built target bitcoin-tidy
[100%] Building CXX object CMakeFiles/bitcoin-tidy-tests.dir/example_logprintf.cpp.o
USAGE: clang-tidy [options] <source0> [... <sourceN>]

...list of cmake options...

Error opening '/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/libbitcoin-tidy.dylib': dlopen(/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/libbitcoin-tidy.dylib, 0x0009): tried: '/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/libbitcoin-tidy.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/libbitcoin-tidy.dylib' (no such file), '/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/libbitcoin-tidy.dylib' (no such file)
  -load request ignored.
Error: no checks enabled.
make[3]: *** [CMakeFiles/bitcoin-tidy-tests.dir/example_logprintf.cpp.o] Error 1
make[2]: *** [CMakeFiles/bitcoin-tidy-tests.dir/all] Error 2
make[1]: *** [CMakeFiles/bitcoin-tidy-tests.dir/rule] Error 2
make: *** [bitcoin-tidy-tests] Error 2

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cd build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build$ make
[100%] Built target bitcoin-tidy

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build$ make bitcoin-tidy-tests
[ 75%] Built target bitcoin-tidy
[100%] Building CXX object CMakeFiles/bitcoin-tidy-tests.dir/example_logprintf.cpp.o
USAGE: clang-tidy [options] <source0> [... <sourceN>]

...same errors as above...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, we're getting there. Thanks for your patience!

This should get you one step further:

diff --git a/contrib/devtools/bitcoin-tidy/CMakeLists.txt b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
index 9ed18696d4..ea74b98620 100644
--- a/contrib/devtools/bitcoin-tidy/CMakeLists.txt
+++ b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
@@ -33,7 +33,7 @@ else()
     target_compile_options(bitcoin-tidy PRIVATE -Wextra)
 endif()

-set(CLANG_TIDY_COMMAND "${CLANG_TIDY_EXE}" "--load=${CMAKE_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}bitcoin-tidy${CMAKE_SHARED_LIBRARY_SUFFIX}" "-checks=-*,bitcoin-*")
+set(CLANG_TIDY_COMMAND "${CLANG_TIDY_EXE}" "--load=${CMAKE_BINARY_DIR}/${CMAKE_SHARED_MODULE_PREFIX}bitcoin-tidy${CMAKE_SHARED_MODULE_SUFFIX}" "-checks=-*,bitcoin-*")

 # Create a dummy library that runs clang-tidy tests as a side-effect of building
 add_library(bitcoin-tidy-tests OBJECT EXCLUDE_FROM_ALL example_logprintf.cpp)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming this is close to working, I've got a branch ready to PR here: https://github.com/theuni/bitcoin/tree/bitcoin-tidy-macos

Copy link
Member

@jonatack jonatack Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to be learning a little about cmake by doing 😄

Using your branch, with the updated doc here:

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake -S . -B build
-DLLVM_DIR=$(llvm-config --cmakedir) -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is AppleClang 14.0.3.14030022
-- The CXX compiler identification is AppleClang 14.0.3.14030022
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/homebrew/opt/ccache/libexec/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/homebrew/opt/ccache/libexec/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_FFI_CALL
-- Performing Test HAVE_FFI_CALL - Success
-- Found FFI: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libffi.tbd  
-- Performing Test Terminfo_LINKABLE
-- Performing Test Terminfo_LINKABLE - Success
-- Found Terminfo: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libcurses.tbd  
-- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libz.tbd (found version "1.2.11")  
-- Found zstd: /opt/homebrew/lib/libzstd.dylib  
-- Found LibXml2: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/lib/libxml2.tbd (found version "2.9.13") 
-- Found LLVM 16.0.6
-- Found clang-tidy: /opt/homebrew/Cellar/llvm/16.0.6/bin/clang-tidy
-- Configuring done (1.4s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake --build build
[ 33%] Building CXX object CMakeFiles/bitcoin-tidy.dir/bitcoin-tidy.cpp.o
[ 66%] Building CXX object CMakeFiles/bitcoin-tidy.dir/logprintf.cpp.o
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Finder' [-Wunused-parameter]
AST_MATCHER(clang::StringLiteral, unterminated)
^
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:112:56: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
                                                       ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/logprintf.cpp:12:1: warning: unused parameter 'Builder' [-Wunused-parameter]
/opt/homebrew/Cellar/llvm/16.0.6/include/clang/ASTMatchers/ASTMatchersMacros.h:113:63: note: expanded from macro 'AST_MATCHER'
      ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
                                                              ^
2 warnings generated.
[100%] Linking CXX shared module libbitcoin-tidy.so
[100%] Built target bitcoin-tidy

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cmake --build build --target bitcoin-tidy-tests  
[ 75%] Built target bitcoin-tidy
[100%] Building CXX object CMakeFiles/bitcoin-tidy-tests.dir/example_logprintf.cpp.o
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:65:15: warning: Unterminated format string used with LogPrintf [bitcoin-unterminated-logprintf]
    LogPrintf("hello world!");
              ^
                           \n
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:22:68: note: expanded from macro 'LogPrintf'
#define LogPrintf(...) LogPrintLevel_(LogFlags::NONE, Level::None, __VA_ARGS__)
                                                                   ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:21:104: note: expanded from macro 'LogPrintLevel_'
#define LogPrintLevel_(category, level, ...) LogPrintf_(__func__, __FILE__, __LINE__, category, level, __VA_ARGS__)
                                                                                                       ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:69:15: warning: Unterminated format string used with LogPrintf [bitcoin-unterminated-logprintf]
    LogPrintf("");
              ^
               \n
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:22:68: note: expanded from macro 'LogPrintf'
#define LogPrintf(...) LogPrintLevel_(LogFlags::NONE, Level::None, __VA_ARGS__)
                                                                   ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:21:104: note: expanded from macro 'LogPrintLevel_'
#define LogPrintLevel_(category, level, ...) LogPrintf_(__func__, __FILE__, __LINE__, category, level, __VA_ARGS__)
                                                                                                       ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:74:15: warning: Unterminated format string used with LogPrintf [bitcoin-unterminated-logprintf]
    LogPrintf("hello world!...");
              ^
                              \n
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:22:68: note: expanded from macro 'LogPrintf'
#define LogPrintf(...) LogPrintLevel_(LogFlags::NONE, Level::None, __VA_ARGS__)
                                                                   ^
/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/example_logprintf.cpp:21:104: note: expanded from macro 'LogPrintLevel_'
#define LogPrintLevel_(category, level, ...) LogPrintf_(__func__, __FILE__, __LINE__, category, level, __VA_ARGS__)
                                                                                                       ^
[100%] Built target bitcoin-tidy-tests
jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy$ cd build

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build$ make
[100%] Built target bitcoin-tidy

jon|master =:~/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build$ make bitcoin-tidy-tests
[ 75%] Built target bitcoin-tidy
[100%] Built target bitcoin-tidy-tests
$ make VERBOSE=1         
/opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -S/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy -B/Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build --check-build-system CMakeFiles/Makefile.cmake 0
/opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -E cmake_progress_start /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/CMakeFiles /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build//CMakeFiles/progress.marks
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/Makefile2 all
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/bitcoin-tidy.dir/build.make CMakeFiles/bitcoin-tidy.dir/depend
cd /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build && /opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/CMakeFiles/bitcoin-tidy.dir/DependInfo.cmake "--color="
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/bitcoin-tidy.dir/build.make CMakeFiles/bitcoin-tidy.dir/build
make[2]: Nothing to be done for `CMakeFiles/bitcoin-tidy.dir/build'.
[100%] Built target bitcoin-tidy
/opt/homebrew/Cellar/cmake/3.27.1/bin/cmake -E cmake_progress_start /Users/jon/bitcoin/bitcoin/contrib/devtools/bitcoin-tidy/build/CMakeFiles 0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woohoo! I'll PR that commit.

Thanks again for testing, glad to see it's working on macOS (and arm64 even).

An LLVM installation will have `llvm-config` available to query for
info. Ask it for the `--cmakedir`, and use that in our bitcoin-tidy
example, rather than listing multiple different (potential) paths per
distro/OS etc.
@fanquake fanquake force-pushed the bitcoin_tidy_llvm_config_dir branch from 8651b99 to d82bb90 Compare August 10, 2023 10:40
@fanquake
Copy link
Member Author

Simplifed this further, given we can actually just ask for llvm-config --cmakedir.

Copy link
Contributor

@TheCharlatan TheCharlatan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, Re-ACK d82bb90

@theuni
Copy link
Member

theuni commented Aug 10, 2023

Nit: stale description.

@jonatack's issue is valid but unrelated. I'll PR a fix for that separately once we have it nailed down.

ACK d82bb90.

@DrahtBot DrahtBot removed the request for review from theuni August 10, 2023 19:56
@jonatack
Copy link
Member

jonatack commented Aug 10, 2023

ACK d82bb90

Tested the updated steps are working in #28245 (comment).

@fanquake
Copy link
Member Author

Nit: stale description.

Updated the description.

@fanquake fanquake merged commit 3654d84 into bitcoin:master Aug 11, 2023
@fanquake fanquake deleted the bitcoin_tidy_llvm_config_dir branch August 11, 2023 09:38
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Aug 13, 2023
d82bb90 doc: use llvm-config for bitcoin-tidy example (fanquake)

Pull request description:

  An LLVM installation will have `llvm-config` available to query for info. Ask it for the `--cmakedir`, and use that in our bitcoin-tidy example, rather than listing multiple different (potential) paths per distro/OS etc.

ACKs for top commit:
  theuni:
    ACK d82bb90.
  jonatack:
    ACK d82bb90
  TheCharlatan:
    Nice, Re-ACK d82bb90

Tree-SHA512: e07e979231f8f000deafce0751bed4b73ff0eff995bec49e90f579c9051cf5859dac5e49554b8219d33b00c81192db979eed98fee1c643a9205ea8babfce2c5d
@bitcoin bitcoin locked and limited conversation to collaborators Aug 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants