我想将经验丰富的'parquet'项目(https://github.com/apache/arrow/tree/master/cpp)链接为我当前在Linux上的项目的一部分。
为此,我用这样的参数运行镶木地板
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链接到我自己的项目中时,为什么lib在镶木地板项目本身中编译良好,但是现在还有很多未解决的问题?此外,我为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文件?)
答案 0 :(得分:0)
如Uwe在评论中所写,https://github.com/apache/parquet-cpp存储库已过时,并且Parquet C ++库正在作为Apache Arrow C ++代码库https://github.com/apache/arrow/tree/master/cpp的一部分进行开发。您可以尝试以此为基础进行构建吗?如果遇到问题,可以将其发布在dev@arrow.apache.org邮件列表中吗?
答案 1 :(得分:0)
与 shared (.so
)库而不是 static (.a
)库链接时,您已经成功构建了项目。
(命令find_library
实际上会查找一个库,该名称在NAMES选项中列出。在您的情况下,它找到了.so
库,因为它的名称位于{ {1}}一个。
实际上,共享和静态 .a
库都包含相同一组符号,并且这两个集合均不足用于链接。区别在于共享库包含信息,可以在其中找到剩余符号(在您的案例中,parquet
库中),而静态库则不
要与 static 库正确链接,您需要手动列出相关的库。
在Windows thrift
文件中,静态库或共享({{1 }})一。看来您与动态链接(它没有.lib
)连接了,就像在Linux上一样。