Compilation Error during Linkage with CMake

Packers: <p>I tried to incorporate pytorch C++ extension to my existing project, but I encountered a linkage error. I have been able to replicated it using a small example<br>
<strong>utils.hpp</strong></p>
<pre><code class="lang-auto">#pragma once

#include &lt;string&gt;

namespace example {
enum EnumExample : uint8_t { TEST1, TEST2 };

class Utils {
public:
  static std::string getString(EnumExample);
};
} // namespace example
</code></pre>
<p><strong>utils.cpp</strong></p>
<pre><code class="lang-auto">#include "utils.hpp"

namespace example {
std::string Utils::getString(EnumExample example) {
  if (example == TEST1)
    return "TEST1";
  else if (example == TEST2)
    return "TEST2";
}
} // namespace example                                                                                                             
</code></pre>
<p><strong>main.cpp</strong></p>
<pre><code class="lang-auto">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;torch/script.h&gt;

#include "utils.hpp"

int main(int argc, const char *argv[]) {
  if (argc != 2) {
    std::cerr &lt;&lt; "usage: example-app &lt;path-to-exported-script-module&gt;\n";
    return -1;
  }

  torch::jit::script::Module module;
  try {
    // Deserialize the ScriptModule from a file using torch::jit::load().                                                          
    module = torch::jit::load(argv[1]);
  } catch (const c10::Error &amp;e) {
    std::cerr &lt;&lt; "error loading the model\n";
    return -1;
  }
  std::cout &lt;&lt; "Model " &lt;&lt; argv[1] &lt;&lt; " loaded fine\n";

  // Create a vector of inputs.                                                                                                    
  std::vector&lt;torch::jit::IValue&gt; inputs;
  inputs.push_back(torch::randn({1, 1, 64, 101}));

  // Execute the model and turn its output into a tensor.                                                                          
  at::Tensor output = module.forward(inputs).toTensor();
  std::cout &lt;&lt; output &lt;&lt; "\n";
  int y_hat = output.argmax(1).item().toInt();
  std::cout &lt;&lt; "Predicted class: " &lt;&lt; y_hat &lt;&lt; "\n";

  std::cout &lt;&lt; example::Utils::getString(example::TEST1);
}
</code></pre>
<p><strong>CMakeLists.txt</strong></p>
<pre><code class="lang-auto">cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)

find_package(Torch REQUIRED)

add_library(example_lib
  utils.cpp)

add_executable(example-app main.cpp)
target_link_libraries(example-app
  PRIVATE ${TORCH_LIBRARIES})
</code></pre>
<p>The compilation error is as follows:</p>
<pre><code class="lang-auto">CMakeFiles/example-app.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x549): undefined reference to `example::Utils::getString[abi:cxx11](example::EnumExample)'
collect2: error: ld returned 1 exit status
CMakeFiles/example-app.dir/build.make:87: recipe for target 'example-app' failed
make[2]: *** [example-app] Error 1
CMakeFiles/Makefile2:77: recipe for target 'CMakeFiles/example-app.dir/all' failed
make[1]: *** [CMakeFiles/example-app.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
</code></pre>
<p>If I removed the last cout line from <strong>main.cpp</strong>, the compilation would work</p>