cmake - cmake - 链接静态库pytorch在构建期间找不到其内部函数
问题描述
我正在尝试使用 cmake 构建一个程序。由于几个原因,程序必须使用静态库而不是动态库构建,我需要使用 PyTorch,所以这就是我所做的:
- 下载并安装 PyTorch 静态库(我
libtorch.a
在正确的路径中找到,在/home/me/pytorch/torch/lib
) - 由
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
,老实说也不完全确定。
我做错了什么,还是有解决这个问题的方法?任何帮助或朝着正确的方向推动将不胜感激。
附言
确切的错误没有发布,因为它太长了,但它主要由
undefined reference to ~
错误组成。如果查看错误消息可能对某些人有帮助,我很乐意编辑问题并发布。build
如果我从代码中删除需要库函数的部分而不从.#include <torch/torch.h>
example-app.cpp
解决方案
最近通过 PyTorch 的静态链接经历了类似的过程,老实说,它并不太漂亮。
我将概述我已采取的步骤(您可以在torchlambda中找到确切的源代码,这里是CMakeLists.txt
(它还包括 AWS SDK 和 AWS Lambda 静态构建),这是从源代码构建的脚本pytorch
(克隆和构建通过/scripts/build_mobile.sh
仅支持 CPU) ),尽管它仅支持 CPU(尽管如果您需要 CUDA,类似的步骤应该没问题,但它至少可以帮助您入门)。
Pytorch 静态库
预构建的静态 PyTorch
首先,您需要预先构建的静态库文件(所有这些文件都需要是静态的,因此不需要.so
,只有带有.a
扩展名的文件才合适)。
Tbh 我一直在寻找安装页面PyTorch
上提供的那些,但只有版本。在一个 GitHub 问题中,我找到了一种下载它们的方法,如下所示:shared
而不是下载(此处通过wget
)共享库:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-shared-with-deps-1.4.0.zip
您重命名shared
为static
(如本期所述),因此它将变为:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-static-with-deps-1.4.0.zip
然而,当你下载它时,没有libtorch.a
下文件夹(如本期lib
所示,也没有找到),所以我剩下的就是从源代码显式构建。libcaffe2.a
如果您以某种方式拥有这些文件(如果有,请提供您从哪里获得这些文件),您可以跳过下一步。
从源头构建
对于 CPU 版本,我使用了 /pytorch/scripts/build_mobile.sh文件,如果需要 GPU 支持,您可以以此为基础构建您的版本(也许您只需要传递-DUSE_CUDA=ON
给此脚本,但不确定)。
最重要cmake
的是-DBUILD_SHARED_LIBS=OFF
为了将一切构建为static
库。您还可以从我的工具中检查脚本,该工具也将参数传递给build_mobile.sh
。
默认情况下,在上面运行将为您提供静态文件,/pytorch/build_mobile/install
其中包含您需要的一切。
制作
现在您可以将上面的构建文件复制到/usr/local
(最好不要,除非您使用Docker
as 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
,尽管我在Amazon Linux AMI上构建时需要它。-lpthread
${CMAKE_DL_LIBS}
建造
现在你要开始构建你的应用程序了。标准libtorch
方式应该没问题,但这是我使用的另一个命令:
mkdir build && \
cd build && \
cmake .. && \
cmake --build . --config Release
上面将创建二进制文件现在应该安全build
放置的文件夹。example-app
最后用于ld build/example-app
验证所有内容PyTorch
都是静态链接的,请参阅上述问题点5.
,您的输出应该看起来相似。
推荐阅读
- python - 使用 scikit-learn 对具有乘法输入的 Keras 模型进行交叉验证
- git - 我创建了新的本地 git 存储库,但它显示了此消息。致命的:错误的修订版“头”
- javascript - 整数Javascript的锯齿波函数
- c# - 如何使用 OpenXML SDK 在 Excel 中附加 .eml 文件?
- c# - 我如何在我的 Visual Studio 代码项目中正确引用 microsoft ASPNETCORE Identity?
- python-3.x - Python-docx:编辑预先存在的运行
- reactjs - 允许通过 GraphQL 为 Elixir 后端上传多部分(图像)
- django - 有一个使用 Pinax 和模板的 Django 项目说“加载引导程序”。但它在哪里?
- typescript - 在Typescript中,为什么我需要在用implements定义接口后重新定义接口及其类
- ios - iOS 为什么requestEndDate 早于requestStartDate?