0

Trying to learn cmake with a small program. This is the directory structure:

.
├── CMakeLists.txt
├── main.cpp
├── reader.cpp
├── reader.hpp
├── stencil.cpp
├── stencil.hpp
├── task.cpp
└── task.hpp

in main.cpp i have some code that creates one reader class, one stencil class and then prints some stuff. I also need pthread to make things work, but only in main.cpp. I tried to write my CMakeLists.txt:

cmake_minimum_required(VERSION 3.26.4)

project(main)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_COMPILER     "/usr/bin/g++") # links to gnu gcc
set(CMAKE_CXX_FLAGS        "-Wall")

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)

add_library(task task.cpp task.hpp)

add_library(reader reader.cpp reader.hpp)
target_link_libraries(reader task)

add_library(stencil stencil.cpp stencil.hpp)

add_executable(main main.cpp)
target_link_libraries(main
              Threads::Threads
              task
              reader
              stencil)

Unfortunately this doesn't link correctly the two classes and i get:

...
[ 87%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable main
Undefined symbols for architecture arm64:
  "__ZN6ReaderIcE3svcEPv", referenced from:
      __ZTV6ReaderIcE in main.cpp.o
  "__ZN6ReaderIcEC1EPPcl", referenced from:
      _main in main.cpp.o
  "__ZN7StencilIcE3svcEPv", referenced from:
      __ZTV7StencilIcE in main.cpp.o
  "__ZN7StencilIcEC1Ev", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
make[2]: *** [main] Error 1
make[1]: *** [CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2

For example this it the code in stencil:

stencil.hpp

#pragma once
#ifndef STENCIL_HPP
#define STENCIL_HPP

template<class T>
class Stencil {
public:
    Stencil();
    void *svc(void * in);
};

#endif /* STENCIL_HPP */

stencil.cpp

#include "stencil.hpp"

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

template <class T> void *Stencil<T>::svc(void *in) {
    return in;
}

I think it has to do with the templates, but I'm not sure.

  • 1
    This is not CMake error, this is error in the code. You can't instance the template, which code is implemented in the .cpp (obviously, because you don't have the code at the instance moment). You should to implement Stencil class in the header or instance this for the all possible T in the .cpp. – A.N. Jul 18 '23 at 15:46
  • 1
    @A.N. Ok so i have to keep the declaration of the template in the same file. Thank you! – Rododendro Jul 18 '23 at 15:50

0 Answers0