1

I am having following compilation issue with my project with template class

Undefined symbols for architecture x86_64:
  "Node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Node(int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [apps/main] Error 1
make[1]: *** [apps/CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2

my files are structured as follows:

├── include
│   └── maple
│       └── node.hpp
├── src
│   ├── CMakeLists.txt
│   └── node.cpp
├── apps
│   ├── CMakeLists.txt
│   └── main.cpp
└── CMakeLists.txt

/CmakeLists.txt

add_subdirectory(src)
add_subdirectory(apps)

/src/CMakeLists.txt

set(HEADER_LIST "${maple_SOURCE_DIR}/include/maple/node.hpp")
add_library(node_lib STATIC node.cpp ${HEADER_LIST})
target_include_directories(node_lib PUBLIC ../include)

/app/CMakeLists.txt

add_executable(main main.cpp)
target_link_libraries(main PRIVATE node_lib)

/include/maple/node.hpp

template <class T>
class Node
{
private:
    int key;
    T value;
public:
    Node();
    Node(int key, T value);
};

/src/node.cpp

template<class T>
Node<T>::Node() {
}

template<class T>
Node<T>::Node(int key, T value) {
    key = key;
    value = value;
}

template Node<std::string>;

/app/main.cpp

int main()  {
   Node<std::string> node(3, "abc");
   return 0;
}

Can anyone guide me on how to compile this project right?

I am already aware that the template class needs the implementation along with the definition

I am asking how to achieve compilation using Cmake when .h and .cpp for template class are in different directories, as in a typical C++ project.

Brandon Lee
  • 695
  • 1
  • 10
  • 22
  • It is a **requirement** of the Stack Overflow that the code should be in the question post itself, not linked. See [ask]. "Unfortunately, with my limited understanding of Cmake, I am still struggling to compile this project." - What exactly you cannot do and ask us to help? Please, **be specific**. Don't you know how to create an executable from sources? Or what is your **problem**? – Tsyvarev Mar 14 '20 at 21:47
  • @Tsyvarev see if updated question make sense – Brandon Lee Mar 15 '20 at 16:32
  • 3
    Well, as described in the duplicate question and its answers, as `Node` is a **template** class, its methods (including constructors) should be **implemented** in the **header** file (`node.hpp`), not in the `node.cpp` file which is compiled separately. This is a requirement of the compiler, so CMake cannot change these rules. – Tsyvarev Mar 15 '20 at 18:06
  • Sorry, now I see that you actually have an **explicit instantiation** there. You just didn’t mention that source file to CMake **at all**, so it’s as if it doesn’t exist. – Davis Herring Mar 16 '20 at 03:11
  • Does this answer your question? [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Kevin Mar 16 '20 at 11:54
  • what do you mean by `You just didn’t mention that source file to CMake at all`, I have provided it to `node_lib` defined in /src/CMakeLists.txt. Am I putting it at the wrong place? – Brandon Lee Mar 17 '20 at 01:02
  • @squareskittles not really, because I am trying to achieve that through Cmake when the code based is organized in a way that .cpp and .h are in separate directories. – Brandon Lee Mar 21 '20 at 20:58

0 Answers0