정진하*_*정진하 6 cmake static-libraries static-linking pytorch libtorch
我正在尝试使用 cmake 构建一个程序。由于多种原因,必须使用静态库而不是动态库构建程序,并且我需要使用 PyTorch,所以这就是我所做的:
libtorch.a下载并安装了 PyTorch 静态库(我在正确的路径中找到了/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)
Run Code Online (Sandbox Code Playgroud)
仅供参考,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(仅通过 CPU 支持进行克隆和构建/scripts/build_mobile.sh) ),尽管它仅支持 CPU(尽管如果您需要 CUDA,类似的步骤应该没问题,但它至少可以帮助您入门)。
首先,您需要预先构建的静态库文件(所有这些文件都需要是静态的,因此不需要.so,只有带有.a扩展名的才适合)。
老实说,我一直在寻找安装页面PyTorch上提供的那些,但只有版本。在一个 GitHub 问题中,我找到了一种下载它们的方法,如下所示:shared
而不是下载(此处通过wget)共享库:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-shared-with-deps-1.4.0.zip
Run Code Online (Sandbox Code Playgroud)
您重命名shared为static(如本期所述),因此它将变为:
$ wget https://download.pytorch.org/libtorch/cu101/libtorch-static-with-deps-1.4.0.zip
Run Code Online (Sandbox Code Playgroud)
然而,当您下载它时,没有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(最好不要这样做,除非您使用Dockeras 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}")
Run Code Online (Sandbox Code Playgroud)
现在剩下的都很好,除了target_link_libraries,它应该(如本期所示,请参阅那里列出的相关问题以获取更多参考)与-Wl,--whole-archive链接器标志一起使用,这让我想到了这一点:
target_link_libraries(example-app PRIVATE -lm
-Wl,--whole-archive "${TORCH_LIBRARIES}"
-Wl,--no-whole-archive
-lpthread
${CMAKE_DL_LIBS})
Run Code Online (Sandbox Code Playgroud)
您可能不需要-lm、-lpthread或,尽管我在Amazon Linux AMI${CMAKE_DL_LIBS}上构建时需要它。
现在您可以开始构建您的应用程序了。标准libtorch方法应该没问题,但这是我使用的另一个命令:
mkdir build && \
cd build && \
cmake .. && \
cmake --build . --config Release
Run Code Online (Sandbox Code Playgroud)
上面将创建二进制build文件example-app现在应该安全放置的文件夹。
最后用于ld build/example-app验证所有内容是否PyTorch静态链接,请参阅上述问题点5.,您的输出应该看起来类似。