Linking error when calling Pytorch c++ API from my c++ project for Android

Limba: <p>Hi,<br>
I’m following this example: <a href="https://github.com/ljk53/pytorch-android-cpp-demo" rel="nofollow noopener">pytorch-android-cpp-demo</a><br>
and I successfully compiled libtorch for Android but I’m having problems linking the static libs to my c++ project.<br>
Here are the details:</p>
<h1>Steps</h1>
<ol>
<li>Compiling libtorch for Android on  <strong>Linux</strong>  as explained in the example using:</li>
</ol>
<ul>
<li>Ubuntu 20.04</li>
<li>NDK 21 (for Linux 64b)</li>
<li>Cmake 3.16.3<br>
The resulting files are  <strong>static (.a)</strong>  files.</li>
</ul>
<ol start="2">
<li>Linking torch .a files to an Android c++ project on  <strong>Windows</strong>  using:</li>
</ol>
<ul>
<li>NDK 21 (for Windows)</li>
<li>Android .mk files (I can’t use Cmake)
<ul>
<li>Compiled for armeabi-v7a arch. (32b)</li>
<li>Used  <code>APP_STL := c++_static</code>
</li>
<li>Used prebuilt and LOCAL_STATIC_LIBRARIES to link the torch libraries:</li>
</ul>
</li>
</ul>
<pre><code class="lang-auto">LOCAL_STATIC_LIBRARIES += c10-prebuilt
LOCAL_STATIC_LIBRARIES += torch-prebuilt
LOCAL_STATIC_LIBRARIES += torch_cpu-prebuilt

include $(CLEAR_VARS)
LOCAL_MODULE := c10-prebuilt
LOCAL_SRC_FILES := C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libc10.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := torch-prebuilt
LOCAL_SRC_FILES := C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := torch_cpu-prebuilt
LOCAL_SRC_FILES := C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch_cpu.a
include $(PREBUILT_STATIC_LIBRARY)
</code></pre>
<h1>Error Message</h1>
<p>This is the error message I’m getting when compiling my project:</p>
<p>/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/core/ivalue.cpp:430: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::Device const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/core/ivalue.cpp:489: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::Device const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/aten/src/ATen/Functions.cpp:145: error: undefined reference to ‘c10::toString(c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/aten/src/ATen/Functions.cpp:165: error: undefined reference to ‘c10::toString(c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/core/TensorOptions.h:252: error: undefined reference to ‘c10::get_default_dtype()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/core/TensorOptions.h:252: error: undefined reference to ‘c10::get_default_dtype()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/aten/src/ATen/Functions.cpp:289: error: undefined reference to ‘c10::toString(c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/aten/src/ATen/Functions.cpp:827: error: undefined reference to ‘c10::toString(c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DeviceType)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/core/impl/DeviceGuardImplInterface.h:0: error: undefined reference to ‘c10::impl::device_guard_impl_registry’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DeviceType)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/jit/ir/constants.cpp:110: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::Device const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/jit/ir/constants.cpp:177: error: undefined reference to ‘c10::Device::Device(std::__ndk1::basic_string&lt;char, std::__ndk1::char_traits, std::__ndk1::allocator &gt; const&amp;)’<br>
/mnt/c/Android/linux/android-ndk-r21d/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/memory:0: error: undefined reference to ‘c10::detail::deleteNothing(void*)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/intrusive_ptr.h:0: error: undefined reference to ‘c10::detail::deleteNothing(void*)’<br>
/mnt/c/Android/linux/android-ndk-r21d/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/new:0: error: undefined reference to ‘c10::detail::deleteNothing(void*)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/core/TensorOptions.h:252: error: undefined reference to ‘c10::get_default_dtype()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/jit/serialization/unpickler.cpp:399: error: undefined reference to ‘c10::Device::Device(std::__ndk1::basic_string&lt;char, std::__ndk1::char_traits, std::__ndk1::allocator &gt; const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/jit/serialization/unpickler.cpp:425: error: undefined reference to ‘c10::DeviceTypeName(c10::DeviceType, bool)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/jit/serialization/unpickler.cpp:542: error: undefined reference to ‘c10::Device::Device(std::__ndk1::basic_string&lt;char, std::__ndk1::char_traits, std::__ndk1::allocator &gt; const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/jit/frontend/function_schema_parser.cpp:251: error: undefined reference to ‘c10::Device::Device(std::__ndk1::basic_string&lt;char, std::__ndk1::char_traits, std::__ndk1::allocator &gt; const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/core/Generator.h:102: error: undefined reference to ‘c10::GeneratorImpl::device() const’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/core/Generator.h:102: error: undefined reference to ‘c10::GeneratorImpl::device() const’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DeviceType)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DeviceType)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::Device const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/native/BinaryOps.cpp:173: error: undefined reference to ‘c10::get_default_dtype()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/core/Generator.h:102: error: undefined reference to ‘c10::GeneratorImpl::device() const’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/core/Generator.h:102: error: undefined reference to ‘c10::GeneratorImpl::device() const’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::TensorOptions const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/native/TensorShape.cpp:73: error: undefined reference to ‘c10::GetAllocator(c10::DeviceType const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/native/TypeProperties.cpp:84: error: undefined reference to ‘c10::get_default_complex_dtype()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/core/LegacyTypeDispatch.h:0: error: undefined reference to ‘c10::detail::deleteNothing(void*)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/native/xnnpack/Factory.cpp:17: error: undefined reference to ‘c10::GetDefaultMobileCPUAllocator()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/native/xnnpack/Factory.cpp:41: error: undefined reference to ‘c10::GetDefaultMobileCPUAllocator()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/TH/THAllocator.cpp:25: error: undefined reference to ‘c10::GetCPUAllocator()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/TH/THAllocator.cpp:571: error: undefined reference to ‘c10::reportMemoryUsageToProfiler(void*, long long, c10::Device)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/quantized/Quantizer.cpp:75: error: undefined reference to ‘c10::GetDefaultMobileCPUAllocator()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/aten/src/ATen/native/cpu/BinaryOpsKernel.cpp.DEFAULT.cpp:78: error: undefined reference to ‘c10::Scalar::operator-() const’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/caffe2/serialize/inline_container.cc:222: error: undefined reference to ‘c10::GetCPUAllocator()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/CPUGeneratorImpl.cpp:18: error: undefined reference to ‘c10::detail::getNonDeterministicRandom(bool)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/CPUGeneratorImpl.cpp:43: error: undefined reference to ‘c10::GeneratorImpl::GeneratorImpl(c10::Device, c10::DispatchKeySet)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/CPUGeneratorImpl.cpp:73: error: undefined reference to ‘c10::detail::getNonDeterministicRandom(bool)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/CPUGeneratorImpl.cpp:43: error: undefined reference to ‘c10::GeneratorImpl::GeneratorImpl(c10::Device, c10::DispatchKeySet)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/PTThreadPool.h:13: error: undefined reference to ‘c10::ThreadPool::ThreadPool(int, int, std::__ndk1::function&lt;void ()&gt;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/ParallelThreadPoolNative.cpp:26: error: undefined reference to ‘c10::ThreadPoolRegistry()’<br>
/mnt/c/Android/linux/android-ndk-r21d/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/memory:2133: error: undefined reference to ‘c10::ThreadPool::~ThreadPool()’<br>
/mnt/c/Android/linux/android-ndk-r21d/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/memory:2133: error: undefined reference to ‘c10::ThreadPool::~ThreadPool()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/PTThreadPool.h:8: error: undefined reference to ‘c10::ThreadPool::~ThreadPool()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/PTThreadPool.h:14: error: undefined reference to ‘c10::setThreadName(std::__ndk1::basic_string&lt;char, std::__ndk1::char_traits, std::__ndk1::allocator &gt;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/ParallelThreadPoolNative.cpp:48: error: undefined reference to ‘c10::ThreadPoolRegistry()’<br>
C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch_cpu.a(ParallelThreadPoolNative.cpp.o):ParallelThreadPoolNative.cpp:vtable for at::PTThreadPool: error: undefined reference to ‘c10::ThreadPool::run(std::__ndk1::function&lt;void ()&gt;)’<br>
C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch_cpu.a(ParallelThreadPoolNative.cpp.o):ParallelThreadPoolNative.cpp:vtable for at::PTThreadPool: error: undefined reference to ‘c10::ThreadPool::size() const’<br>
C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch_cpu.a(ParallelThreadPoolNative.cpp.o):ParallelThreadPoolNative.cpp:vtable for at::PTThreadPool: error: undefined reference to ‘c10::ThreadPool::numAvailable() const’<br>
C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch_cpu.a(ParallelThreadPoolNative.cpp.o):ParallelThreadPoolNative.cpp:vtable for at::PTThreadPool: error: undefined reference to ‘c10::ThreadPool::inThreadPool() const’<br>
C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch_cpu.a(ParallelThreadPoolNative.cpp.o):ParallelThreadPoolNative.cpp:vtable for at::PTThreadPool: error: undefined reference to ‘c10::ThreadPool::~ThreadPool()’<br>
C:/REPOSITORIES/pytorch-android-cpp-demo/pytorch/build_android/install/lib/libtorch_cpu.a(ParallelThreadPoolNative.cpp.o):ParallelThreadPoolNative.cpp:typeinfo for at::PTThreadPool: error: undefined reference to ‘typeinfo for c10::ThreadPool’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DispatchKeySet)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/ThreadLocalState.cpp:11: error: undefined reference to ‘c10::ThreadLocalDebugInfo::current()’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/ATen/ThreadLocalState.cpp:32: error: undefined reference to ‘c10::ThreadLocalDebugInfo::_forceCurrentDebugInfo(std::__ndk1::shared_ptrc10::ThreadLocalDebugInfo const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/util/StringUtil.h:37: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::DispatchKey)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/TH/THGeneral.cpp:156: error: undefined reference to ‘c10::alloc_cpu(unsigned int)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/aten/src/TH/THGeneral.cpp:188: error: undefined reference to ‘c10::free_cpu(void*)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/autograd/engine.cpp:0: error: undefined reference to ‘c10::impl::device_guard_impl_registry’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/autograd/engine.cpp:621: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::TensorOptions const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/autograd/engine.cpp:621: error: undefined reference to ‘c10::operator&lt;&lt;(std::__ndk1::basic_ostream&lt;char, std::__ndk1::char_traits &gt;&amp;, c10::TensorOptions const&amp;)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/torch/csrc/autograd/engine.cpp:0: error: undefined reference to ‘c10::impl::device_guard_impl_registry’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/core/impl/InlineEvent.h:60: error: undefined reference to ‘c10::DeviceTypeName(c10::DeviceType, bool)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/core/impl/InlineEvent.h:60: error: undefined reference to ‘c10::DeviceTypeName(c10::DeviceType, bool)’<br>
/mnt/c/REPOSITORIES/pytorch-android-cpp-demo/pytorch/c10/core/impl/InlineEvent.h:76: error: undefined reference to ‘c10::DeviceTypeName(c10::DeviceType, bool)’<br>
clang++: error: linker command failed with exit code 1 (use -v to see invocation)<br>
make: *** [c:/Android/android-ndk-r21d/build//…/build/core/build-binary.mk:738: C:/REPOSITORIES/SVLTemp2/obj/local/armeabi-v7a/dczoom_native] Error 1</p>
<p>Can you please help me figure out what is wrong?<br>
Thank you</p>

walktim: <p>Hi~  I have the same problem.  Have you solved it？Can you post the answer? thankyou</p>

Cyrill: <p>I also got this error undefined reference to `c10::operator&lt;&lt;(std::__ndk1::basic_ostream</p>
<p>I know this is three years later, but It took me 8 hours to figure this out. The problem is <code>{ val }</code> curly brace syntax,  which works in the macOS as well as linux Libtorch, but in the stripped down (Android) Libtorch-Lite build it does not work.</p>
<pre><code class="lang-cpp">    int val = 42;
    // this fails: 
    torch::Tensor hasMaskInput = torch::tensor({ val }, torch::dtype(torch::kFloat32));

    // but this works:
    torch::Tensor hasMaskInput = torch::tensor(std::vector&lt;int&gt;{val} , torch::dtype(torch::kFloat32));
</code></pre>
<p>I really hope this helps somebody!</p>