构建 parquet-cpp 时如何静态链接 Arrow?

Posted

技术标签:

【中文标题】构建 parquet-cpp 时如何静态链接 Arrow?【英文标题】:How can I statically link Arrow when building parquet-cpp? 【发布时间】:2018-01-08 19:54:00 【问题描述】:

来自parquet-cpp home page:

默认情况下,Parquet 链接到 Arrow 的共享库。如果您希望静态链接箭头符号,请传递 -DPARQUET_ARROW_LINKAGE=static。

我确实想静态链接 Arrow,因为我想在其他没有安装 Arrow 的服务器上使用我的程序。我试过-DPARQUET_ARROW_LINKAGE=static,但我得到一个关于“缺少传递依赖”的错误:

# cmake -DPARQUET_BUILD_TESTS=Off -DCMAKE_BUILD_TYPE=Release -DPARQUET_MINIMAL_DEPENDENCY=ON -DPARQUET_ARROW_LINKAGE=static .
-- The C compiler identification is GNU 4.8.5
...
-- [ /usr/local/share/cmake-3.9/Modules/FindBoost.cmake:1717 ] Boost_FOUND = 1
-- Boost version: 1.55.0
...
-- THRIFT_HOME:
-- Thrift compiler/libraries NOT found:  (THRIFT_INCLUDE_DIR-NOTFOUND, THRIFT_STATIC_LIB-NOTFOUND). Looked in system search paths.
-- Thrift include dir: /root/tmp/parquet-cpp-master/thrift_ep/src/thrift_ep-install/include
-- Thrift static library: /root/tmp/parquet-cpp-master/thrift_ep/src/thrift_ep-install/lib/libthrift.a
-- Thrift compiler: /root/tmp/parquet-cpp-master/thrift_ep/src/thrift_ep-install/bin/thrift
-- Checking for module 'arrow'
--   No package 'arrow' found
-- Could not find the Arrow library. Looked for headers in , and for libs in
-- Building Apache Arrow from commit: 501d60e918bd4d10c429ab34e0b8e8a87dffb732
-- CMAKE_CXX_FLAGS:  -O3 -DNDEBUG  -Wall -std=c++11
-- Found cpplint executable at /root/tmp/parquet-cpp-master/build-support/cpplint.py
CMake Error at CMakeLists.txt:515 (message):
  Missing transitive dependencies for Arrow static linking

所以我found the code 产生了错误:

  if (NOT DEFINED ENVBROTLI_STATIC_LIB_ENC OR
      NOT DEFINED ENVBROTLI_STATIC_LIB_DEC OR
      NOT DEFINED ENVBROTLI_STATIC_LIB_COMMON OR
      NOT DEFINED ENVSNAPPY_STATIC_LIB OR
      NOT DEFINED ENVZLIB_STATIC_LIB OR
      NOT DEFINED ENVLZ4_STATIC_LIB OR
      NOT DEFINED ENVZSTD_STATIC_LIB)
    message(FATAL_ERROR "Missing transitive dependencies for Arrow static linking")

但这并没有真正帮助我,因为我不知道如何定义这些环境变量。

我需要先编译 Arrow 并安装自己吗? (我宁愿让 parquet-cpp 为我做这件事。)

【问题讨论】:

至少,看起来你需要install Thrift(并且可能构建其库的静态版本)。 感谢@JerryCoffin,但是当我之前使用箭头链接设置为shared 而不是static 进行构建时,我看到了关于找不到 Thrift 库的相同消息。然后当我运行make(这是运行cmake 之后的下一步)时,它拉下并编译了所需的节俭的东西。第一步只是设置构建文件。所以我假设我可以放心地忽略有关缺少 Thrift 库的消息。 好的,很公平(尽管在问题中澄清这一点可能不会有什么坏处)。 【参考方案1】:

我安排了一个脚本来下载依赖源,设置环境变量并在最后运行cmake 行。只需更改 DEPDIR 变量值,将其设置为选择的目录。

#!/bin/bash

CMKDIR=$PWD
DEPDIR=/tmp

cd $DEPDIR

#snappy
git clone https://github.com/google/snappy.git
cd snappy
mkdir build 
cd build 
cmake ..
make

export SNAPPY_STATIC_LIB=$DEPDIR/snappy/build/libsnappy.a

cd $DEPDIR

#brotli
git clone https://github.com/google/brotli.git
cd brotli
mkdir out
cd out
../configure-cmake
make

export BROTLI_STATIC_LIB_ENC=$DEPDIR/brotli/out/libbrotlienc-static.a
export BROTLI_STATIC_LIB_DEC=$DEPDIR/brotli/out/libbrotlidec-static.a
export BROTLI_STATIC_LIB_COMMON=$DEPDIR/brotli/out/libbrotlicommon-static.a

cd $DEPDIR

#zlib
git clone https://github.com/madler/zlib.git
cd zlib
./configure
make

export ZLIB_STATIC_LIB=$DEPDIR/zlib/libz.a

cd $DEPDIR

#lz4
git clone https://github.com/lz4/lz4.git
cd lz4
make

export LZ4_STATIC_LIB=$DEPDIR/lz4/lib/liblz4.a

cd $DEPDIR

#zstd
git clone https://github.com/facebook/zstd.git
cd zstd
make

export ZSTD_STATIC_LIB=$DEPDIR/zstd/lib/libzstd.a

cd $CMKDIR

cmake -DPARQUET_BUILD_TESTS=Off -DCMAKE_BUILD_TYPE=Release -DPARQUET_MINIMAL_DEPENDENCY=ON -DPARQUET_ARROW_LINKAGE=static

这个脚本很简单,但应该很有效。只需将其复制到一个新文件中(在同一 CMakeLists.txt 目录中),赋予该文件执行权限(即sudo chmod +x filename)并像这样执行它:

./filename.sh 

关于fPIC选项问题,需要修改一些文件:

snappy:在 CMakeLists.txt 中添加这一行,在开头,前两行之后:

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

lz4zstd:编辑 lib 子目录中的 Makefile,在这一行之后

CFLAGS  += $(DEBUGFLAGS) $(MOREFLAGS)

添加这一行:

CFLAGS += -fPIC

zlib:编辑 Makefile,在这一行之后

CFLAGS=-O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN

添加这一行:

CFLAGS += -fPIC

brotli:就我从 make 输出中看到的,该选项已经设置好了。

在再次运行 make 之前,执行这个脚本:

#!/bin/bash

DEPDIR=/tmp

cd $DEPDIR/snappy/build
cmake ..
make clean
make

cd $DEPDIR/lz4
make clean
make

cd $DEPDIR/zstd
make clean
make

【讨论】:

谢谢。它几乎奏效了。我需要用-fPIC:/bin/ld: /tmp/snappy/build/libsnappy.a(snappy.cc.o): relocation R_X86_64_32 against '.rodata' can not be used when making a shared object; recompile with -fPIC 编译依赖项。您知道如何将这个编译标志添加到上述每个依赖项中吗? 嗨@MarkRajcok,我编辑了解决-fPIC问题的答案。 谢谢。我还必须修改 zlib Makefile(我编辑了你的答案)。

以上是关于构建 parquet-cpp 时如何静态链接 Arrow?的主要内容,如果未能解决你的问题,请参考以下文章

使用 gcc-ar 和 gcc-ranlib 的 autoconf 配方

构建 R 包时如何链接静态库

如何在链接到静态库的 DEV-CPP 中构建控制台应用程序时解决对 _imp__** 的未定义引用?

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

zt:我使用过的Linux命令之ar - 创建静态库.a文件

转载我使用过的Linux命令之ar - 创建静态库.a文件