将 json 库添加到 clang libtooling 项目

Posted

技术标签:

【中文标题】将 json 库添加到 clang libtooling 项目【英文标题】:Adding json library to clang libtooling project 【发布时间】:2016-06-29 05:48:31 【问题描述】:

我正在使用 clang libtool 编写一个 RecursiveASTVisitor。

现在我正在尝试读取一个 json 文件并从 https://github.com/open-source-parsers/jsoncpp 下载了 json 库

我已将文件夹“include/json”复制到我的项目路径“llvm/tools/clang/include”

使用 ninja 命令编译时,include 命令不会抛出任何错误include "json/json.h"

但是,当我尝试输入一行代码 Json::Value root 时,它会引发链接错误..

完整的错误日志:

ninja -v
[1/1] : && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++   -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Werror=date-time -std=c++11 -fcolor-diagnostics -fno-common -Woverloaded-virtual -Wno-nested-anon-types -g -Wl,-search_paths_first -Wl,-headerpad_max_install_names  tools/clang/tools/extra/myASTChecker/CMakeFiles/MyASTChecker.dir/MyASTChecker.cpp.o  -o bin/MyASTChecker  lib/libLLVMSupport.a lib/libclangTooling.a lib/libclangASTMatchers.a lib/libclangFormat.a lib/libclangFrontend.a lib/libclangDriver.a lib/libLLVMOption.a lib/libclangParse.a lib/libLLVMMCParser.a lib/libclangSerialization.a lib/libclangSema.a lib/libclangEdit.a lib/libclangAnalysis.a lib/libLLVMBitReader.a lib/libLLVMProfileData.a lib/libclangToolingCore.a lib/libclangAST.a lib/libclangRewrite.a lib/libclangLex.a lib/libclangBasic.a lib/libLLVMCore.a lib/libLLVMMC.a lib/libLLVMSupport.a -lcurses -lpthread -lz -lm -Wl,-rpath,@executable_path/../lib && :
FAILED: bin/MyASTChecker 
: && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++   -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Werror=date-time -std=c++11 -fcolor-diagnostics -fno-common -Woverloaded-virtual -Wno-nested-anon-types -g -Wl,-search_paths_first -Wl,-headerpad_max_install_names  tools/clang/tools/extra/myASTChecker/CMakeFiles/MyASTChecker.dir/MyASTChecker.cpp.o  -o bin/MyASTChecker  lib/libLLVMSupport.a lib/libclangTooling.a lib/libclangASTMatchers.a lib/libclangFormat.a lib/libclangFrontend.a lib/libclangDriver.a lib/libLLVMOption.a lib/libclangParse.a lib/libLLVMMCParser.a lib/libclangSerialization.a lib/libclangSema.a lib/libclangEdit.a lib/libclangAnalysis.a lib/libLLVMBitReader.a lib/libLLVMProfileData.a lib/libclangToolingCore.a lib/libclangAST.a lib/libclangRewrite.a lib/libclangLex.a lib/libclangBasic.a lib/libLLVMCore.a lib/libLLVMMC.a lib/libLLVMSupport.a -lcurses -lpthread -lz -lm -Wl,-rpath,@executable_path/../lib && :
Undefined symbols for architecture x86_64:
  "Json::Value::Value(Json::ValueType)", referenced from:
      MyASTFrontendAction::CreateASTConsumer(clang::CompilerInstance&, llvm::StringRef) in MyASTChecker.cpp.o
  "Json::Value::~Value()", referenced from:
      MyASTFrontendAction::CreateASTConsumer(clang::CompilerInstance&, llvm::StringRef) in MyASTChecker.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

我错过了什么或应该做什么??

【问题讨论】:

【参考方案1】:

使用 ninja 命令编译时,include 命令不会抛出任何错误include "json/json.h"

当您将头文件复制粘贴到编译器的包含搜索路径中已经存在的文件夹中时。你不会在#include "json/json.h" 中遇到问题,因为是的,文件在那里,你还没有使用它的任何东西,所以它只是一些函数,类声明将被忽略。

但是,当我尝试输入一行代码 Json::Value root 时,它会引发链接错误。

现在,当写Json::Value root; 时发生的事情是你调用了Json::Value 的构造函数,它在包含的头文件中声明,但在源文件中实现。因此,编译器无法找到构造函数的实现并抱怨它。

在包含的头文件中实现了整个 Json 解析器库。这样编译器就会找到带有定义的声明。

您真正想要做的是在编译器的包含搜索目录中包含包含文件,然后是 json 解析器的编译库文件,您可以将其链接到您的 ASTVisitor。

分辨率:

首先,我不鼓励将 json 解析器包含文件复制粘贴到 clang 的包含目录中。相反,您可以在这里做两件事:

    将包含文件粘贴到一般包含目录中,例如/usr/local/include 将您的包含目录添加到CPLUS_INCLUDE_PATH

一旦你完成了包含文件的设置,你会想要编译来自 github 的 json 解析器,然后将你的 recursiveASTVisitor 链接到它。

回答

我看到你链接的 jsonparser 有一个 cmakelist 文件,如果你只是想让它完成这项工作,它真的很有帮助。

一旦你克隆了 repo,就按照他们说的编译他们的库。

mkdir -p build/debug
cd build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
make

在此之后,您可以调用sudo make install,这会将包含文件复制到正确的包含目录中,该目录会被您的操作系统索引以供搜索,并且对编译的库也执行相同的操作。在此链接到您的图书馆之后就像

CFLAGS = `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`

% : %.cpp
        g++ $(CFLAGS) $(LIBS) -o $@ $<

如果您使用 MAKEFILE 编译您的 ASTVisitor (make ASTvisitor.cpp)。或

target_link_library(target jsoncpp)

如果您使用 CMAKELIST 来编译您的 ASTVisitor

【讨论】:

我对静态库链接不是很熟悉。你对 CFLAGS 是什么意思,它应该放在哪里? RecursiveASTVisitor 是用 ninja 构建的。。会不会有一个特定的地方需要我去添加库链接? 我在与我的 ASTVisitor 文件夹相同的文件夹中找到了一个 CMakeLists.txt 并添加了 target_link_libraries(MyASTChecker jsoncpp) 但编译告诉我 library not found for -ljsoncpp 您可以通过两种方式做到这一点。首先,target_link_libraries(&lt;target&gt; &lt;path_to_compiled_jsoncpp_library&gt;)。其次,制作jsoncpp,然后在jsoncpp文件夹中调用sudo make install,这样就没有jsoncpp库,然后你当前的CMakeList文件就可以找到它了。

以上是关于将 json 库添加到 clang libtooling 项目的主要内容,如果未能解决你的问题,请参考以下文章

命令 libtool 失败,退出代码为 1

Libtool 为对象添加前缀,但 gcov 要求它们不带前缀

使用ar或libtool创建静态存档在越狱iOS上失败

如何将共享库与 --as-needed 与 automake 链接?

automake 和 libtool 中的链接库问题

使用 GNU Libtool 创建库