linux - 来自外部镶木地板项目的静态库的“未定义引用”错误
问题描述
我想将 expernal 'parquet' 项目(https://github.com/apache/arrow/tree/master/cpp)链接为我当前在 Linux 上的项目的一部分。
为此,我使用这些参数运行了镶木地板的 cmake
cd build_parquet
cmake -DCMAKE_BUILD_TYPE=Release -DARROW_PARQUET=ON \
-DBoost_NO_BOOST_CMAKE=TRUE -DBoost_NO_SYSTEM_PATHS=TRUE -DBOOST_ROOT=${BOOST_BUILD_DIR}/include -DBOOST_LIBRARYDIR=${BOOST_BUILD_DIR}/lib/boost -DARROW_BOOST_USE_SHARED=OFF -DBOOST_INCLUDEDIR=${BOOST_BUILD_DIR}/include/boost ..
cmake --build . --config Release
// 除了boost还有很多依赖,但是只有boost需要安装在系统上,其他的可以通过cmake脚本下载安装
项目编译成功。我得到了可以启动的可执行文件,生成了静态库 libarrow.a、libparquet.a、共享库 libarrow.so、libparquet.so
在我的主项目中,我想使用这样的库,我在 cmake 中使用这样的命令来找到它们
find_path(PARQUET_INCLUDE_DIR NAMES arrow/api.h PATHS ${PARQUET_DIR}/src)
find_library(PARQUET_LIBRARY_RELEASE NAMES parquet.a
PATHS build_parquet/release/Release/ )
find_library(ARROW_LIBRARY_RELEASE NAMES arrow.a
PATHS build_parquet/release/Release/ )
set(PARQUET_LIBRARIES_RELEASE ${PARQUET_LIBRARY_RELEASE} ${ARROW_LIBRARY_RELEASE} )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Parquet DEFAULT_MSG PARQUET_INCLUDE_DIR
${PARQUET_LIBRARIES_RELEASE } )
没关系,找到了库和包含。
然后我将这个库链接到我的项目
target_link_libraries(${myExe} ${PARQUET_LIBRARIES_RELEASE} ${mySomeOtherLibraries} )
在此之后,我得到了大量的链接器错误,例如
libparquet.a(column_writer.cc.o): In function `apache::thrift::transport::TMemoryBuffer::~TMemoryBuffer()':
column_writer.cc:(.text._ZN6apache6thrift9transport13TMemoryBufferD0Ev[_ZN6apache6thrift9transport13TMemoryBufferD5Ev]+0x3): undefined reference to `vtable for apache::thrift::transport::TMemoryBuffer'
.....
所以这就是我不太了解的,为什么lib在parquet项目本身中编译得很好,但现在有很多未解决的问题,当我用它来链接我自己的项目时?此外,我为 windows 编译了项目,当我做同样的事情时,但使用 arrow.lib 和 parquet.lib (而不是 libparquet.a 和 libarrow.a ),一切正常!我只需要将 arrow.dll、parquet.dll 放入可执行文件即可运行项目。但是在Linux中我已经崩溃了
那么,为什么它不起作用,我应该怎么做才能最终将项目与库链接?
更新
我发现了问题,我必须像这样添加 .so 文件(不仅是 .a 文件)来链接库
find_library(PARQUET_LIBRARY_RELEASE NAMES parquet.so parquet.a
PATHS build_parquet/release/Release/ )
find_library(ARROW_LIBRARY_RELEASE NAMES arrow.so arrow.a
PATHS build_parquet/release/Release/ )
set(PARQUET_LIBRARIES_RELEASE ${PARQUET_LIBRARY_RELEASE} ${ARROW_LIBRARY_RELEASE} )
项目已建成。所以现在的问题是,为什么我需要将 .so 文件添加到链接器(在 Windows 中只有静态 .lib 就足够了),在 Linux 中构建项目时总是这样吗?链接顺序重要吗(首先是 .so 文件,然后是 .a 文件?)
解决方案
正如 Uwe 在评论中所写,https://github.com/apache/parquet-cpp存储库已被弃用,Parquet C++ 库正在开发为 Apache Arrow C++ 代码库https://github.com/apache /arrow/tree/master/cpp。你可以尝试在此基础上进行构建吗?如果遇到问题,你可以在 dev@arrow.apache.org 邮件列表上发帖吗?
推荐阅读
- swift - 是否可以在不重新构建/部署代码的情况下调试在设备上运行的 iOS 应用程序?
- mongodb - Helm:无法从值设置 mongodb root 密码
- python - 在另一个脚本中使用 argparse 运行 python 脚本
- swift - 基于 JSExport 的类未在 JSContext 中发布
- android - Android 的 Firebase Firestore 和 Places Api 之间的冲突
- c# - TFS 构建代理上出现错误 CS0579,但在本地运行构建时成功
- jsf - 通过对每一行的删除按钮删除 P:DATATABLE 行
- python - 减去数据框中的两个值
- wordpress - 多种帖子类型,但仅为一种设置偏移量
- sql-server - 使用警卫停止递归 CTE