Я хочу связать экспериментальный проект '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 хорошо скомпилирована в самом проекте паркетного компьютера, но сейчас у нее много нерешенных проблем, когда я использую ее для ссылок в своем собственном проекте? Более того, я скомпилировал проект для 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)