cmake - 链接静态库pytorch在构建期间找不到其内部函数
cmake - linking static library pytorch cannot find its internal functions during build
我正在尝试使用 cmake 构建程序。由于几个原因,程序必须使用静态库而不是动态库来构建,我需要使用 PyTorch 所以这就是我所做的:
- 已下载并安装 PyTorch 静态库(我在
/home/me/pytorch/torch/lib
的正确路径中找到了 libtorch.a
)
- 制作
CMakeLists.txt
内容如下:
cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
project(example-app LANGUAGES CXX)
find_package(Torch REQUIRED)
add_executable(example-app example-app.cpp argparse/argparse.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}" -static -fopenmp)
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
仅供参考,example-app.cpp
是具有主要功能的文件,argparse/
是一个目录,其中包含一些在 example-app.cpp
中调用的函数的源代码
到cmake -DCMAKE_PREFIX_PATH=/home/me/pytorch/torch ..
都有效,但是后面的build
会报错,说找不到对某些函数的引用,即以fbgemm::
开头的函数。 fbgemm
是(据我所知)用于实现 PyTorch 的某种 GEMM 库。
在我看来,在链接静态 PyTorch 库时,它的内部库 fbgemm
之类的东西没有正确链接,但我不是 cmake
方面的专家,老实说也不完全是当然。
我是不是做错了什么,或者是否有解决此问题的方法?任何帮助或推动正确的方向将不胜感激。
P.S.
确切的错误尚未 post 编辑,因为它太长了,但它主要由 undefined reference to ~
错误组成。如果查看错误消息可能对某些人有帮助,我很乐意编辑问题并post它。
build
ing 和 运行 如果我从代码 without 中删除需要库函数的部分,文件工作正常从 example-app.cpp
.
注释掉 #include <torch/torch.h>
最近通过 PyTorch 的静态链接经历了类似的过程,老实说它不太漂亮。
我将概述我已采取的步骤(您可以在 torchlambda, here is CMakeLists.txt
(it also includes AWS SDK and AWS Lambda static builds), here 中找到确切的源代码是一个从源代码构建 pytorch
的脚本(通过 /scripts/build_mobile.sh
克隆和构建仅 CPU支持)),
虽然它只有 CPU 支持(如果你需要 CUDA,类似的步骤应该没问题,它至少会让你开始)。
Pytorch 静态库
预建静态 PyTorch
首先,你需要预建静态库文件(所有都需要是静态的,因此没有.so
,只有[=19] =] 扩展是合适的)。
Tbh 我一直在寻找 PyTorch
在 installation page 上提供的那些,但只有 shared
版本。
在一个 GitHub 问题中,我找到了一种下载它们的方法,如下所示:
而不是下载(此处通过 wget
)共享库:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-shared-with-deps-1.4.0.zip
您将 shared
重命名为 static
(如 in this issue 所述),因此它将变为:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-static-with-deps-1.4.0.zip
然而,当你下载它时,lib
文件夹下没有libtorch.a
(也没有找到libcaffe2.a
,如this issue所示),所以我剩下的是从源代码明确构建。
如果您以某种方式拥有这些文件(如果有,请提供您从哪里获得它们),您可以跳过下一步。
从源代码构建
对于 CPU 版本,我使用了 /pytorch/scripts/build_mobile.sh 文件,如果需要 GPU 支持,您可以基于此版本(也许您只需要将 -DUSE_CUDA=ON
传递给此脚本, 虽然不确定)。
最重要的是 cmake
的 -DBUILD_SHARED_LIBS=OFF
,以便将所有内容构建为 static
库。您还可以检查 script from my tool 也将参数传递给 build_mobile.sh
。
运行 默认情况下会在 /pytorch/build_mobile/install
中为您提供静态文件,其中包含您需要的一切。
CMake
现在您可以将上述构建文件复制到 /usr/local
(最好不要复制,除非您将 Docker
用作 torchlambda
)或从您的 CMakeLists.txt
中设置它的路径] 像这样:
set(LIBTORCH "/path/to/pytorch/build_mobile/install")
# Below will append libtorch to path so CMake can see files
set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${LIBTORCH}")
现在其余的都很好 除了 target_link_libraries
,应该使用(如 this issue 所示,请参阅此处列出的相关问题以获取更多参考)使用 -Wl,--whole-archive
链接器标志,这让我想到了这个:
target_link_libraries(example-app PRIVATE -lm
-Wl,--whole-archive "${TORCH_LIBRARIES}"
-Wl,--no-whole-archive
-lpthread
${CMAKE_DL_LIBS})
您可能不需要 -lm
、-lpthread
或 ${CMAKE_DL_LIBS}
,尽管我在 Amazon Linux AMI.
上构建时需要它
建筑
现在您可以开始构建您的应用程序了。标准 libtorch
方式应该没问题,但这是我使用的另一个命令:
mkdir build && \
cd build && \
cmake .. && \
cmake --build . --config Release
上面将创建 build
文件夹,现在应该安全地放置 example-app
二进制文件。
最后使用 ld build/example-app
验证 PyTorch
中的所有内容都是静态链接的,参见 aforementioned issue 点 5.
,您的输出应该看起来相似。
我正在尝试使用 cmake 构建程序。由于几个原因,程序必须使用静态库而不是动态库来构建,我需要使用 PyTorch 所以这就是我所做的:
- 已下载并安装 PyTorch 静态库(我在
/home/me/pytorch/torch/lib
的正确路径中找到了libtorch.a
) - 制作
CMakeLists.txt
内容如下:
cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
project(example-app LANGUAGES CXX)
find_package(Torch REQUIRED)
add_executable(example-app example-app.cpp argparse/argparse.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}" -static -fopenmp)
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
仅供参考,example-app.cpp
是具有主要功能的文件,argparse/
是一个目录,其中包含一些在 example-app.cpp
到cmake -DCMAKE_PREFIX_PATH=/home/me/pytorch/torch ..
都有效,但是后面的build
会报错,说找不到对某些函数的引用,即以fbgemm::
开头的函数。 fbgemm
是(据我所知)用于实现 PyTorch 的某种 GEMM 库。
在我看来,在链接静态 PyTorch 库时,它的内部库 fbgemm
之类的东西没有正确链接,但我不是 cmake
方面的专家,老实说也不完全是当然。
我是不是做错了什么,或者是否有解决此问题的方法?任何帮助或推动正确的方向将不胜感激。
P.S.
确切的错误尚未 post 编辑,因为它太长了,但它主要由
undefined reference to ~
错误组成。如果查看错误消息可能对某些人有帮助,我很乐意编辑问题并post它。build
ing 和 运行 如果我从代码 without 中删除需要库函数的部分,文件工作正常从example-app.cpp
. 注释掉
#include <torch/torch.h>
最近通过 PyTorch 的静态链接经历了类似的过程,老实说它不太漂亮。
我将概述我已采取的步骤(您可以在 torchlambda, here is CMakeLists.txt
(it also includes AWS SDK and AWS Lambda static builds), here 中找到确切的源代码是一个从源代码构建 pytorch
的脚本(通过 /scripts/build_mobile.sh
克隆和构建仅 CPU支持)),
虽然它只有 CPU 支持(如果你需要 CUDA,类似的步骤应该没问题,它至少会让你开始)。
Pytorch 静态库
预建静态 PyTorch
首先,你需要预建静态库文件(所有都需要是静态的,因此没有.so
,只有[=19] =] 扩展是合适的)。
Tbh 我一直在寻找 PyTorch
在 installation page 上提供的那些,但只有 shared
版本。
在一个 GitHub 问题中,我找到了一种下载它们的方法,如下所示:
而不是下载(此处通过 wget
)共享库:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-shared-with-deps-1.4.0.zip
您将 shared
重命名为 static
(如 in this issue 所述),因此它将变为:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-static-with-deps-1.4.0.zip
然而,当你下载它时,lib
文件夹下没有libtorch.a
(也没有找到libcaffe2.a
,如this issue所示),所以我剩下的是从源代码明确构建。
如果您以某种方式拥有这些文件(如果有,请提供您从哪里获得它们),您可以跳过下一步。
从源代码构建
对于 CPU 版本,我使用了 /pytorch/scripts/build_mobile.sh 文件,如果需要 GPU 支持,您可以基于此版本(也许您只需要将 -DUSE_CUDA=ON
传递给此脚本, 虽然不确定)。
最重要的是 cmake
的 -DBUILD_SHARED_LIBS=OFF
,以便将所有内容构建为 static
库。您还可以检查 script from my tool 也将参数传递给 build_mobile.sh
。
运行 默认情况下会在 /pytorch/build_mobile/install
中为您提供静态文件,其中包含您需要的一切。
CMake
现在您可以将上述构建文件复制到 /usr/local
(最好不要复制,除非您将 Docker
用作 torchlambda
)或从您的 CMakeLists.txt
中设置它的路径] 像这样:
set(LIBTORCH "/path/to/pytorch/build_mobile/install")
# Below will append libtorch to path so CMake can see files
set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${LIBTORCH}")
现在其余的都很好 除了 target_link_libraries
,应该使用(如 this issue 所示,请参阅此处列出的相关问题以获取更多参考)使用 -Wl,--whole-archive
链接器标志,这让我想到了这个:
target_link_libraries(example-app PRIVATE -lm
-Wl,--whole-archive "${TORCH_LIBRARIES}"
-Wl,--no-whole-archive
-lpthread
${CMAKE_DL_LIBS})
您可能不需要 -lm
、-lpthread
或 ${CMAKE_DL_LIBS}
,尽管我在 Amazon Linux AMI.
建筑
现在您可以开始构建您的应用程序了。标准 libtorch
方式应该没问题,但这是我使用的另一个命令:
mkdir build && \
cd build && \
cmake .. && \
cmake --build . --config Release
上面将创建 build
文件夹,现在应该安全地放置 example-app
二进制文件。
最后使用 ld build/example-app
验证 PyTorch
中的所有内容都是静态链接的,参见 aforementioned issue 点 5.
,您的输出应该看起来相似。