I've been able to pinpoint the problem.
The contents of the files A,B,Main
(as shown in the image) are as follows:
cmake_minimum_required(VERSION 3.13)
add_library(class_a ${CMAKE_SOURCE_DIR}/modules/class_a/class_a.cpp)
target_include_directories(class_a PUBLIC ${CMAKE_SOURCE_DIR}/modules/class_b)
target_link_libraries(class_a PUBLIC class_b)
cmake_minimum_required(VERSION 3.13)
add_library(class_b ${CMAKE_SOURCE_DIR}/modules/class_b/class_b.cpp)
and
cmake_minimum_required(VERSION 3.13)
add_executable(test_class_a test_class_a.cpp)
target_include_directories(test_class_a PUBLIC ${CMAKE_SOURCE_DIR}/modules/class_a/)
target_link_libraries(test_class_a PUBLIC class_a)
The classes have their own *.hpp
and *.cpp
files (the first two are the
*.cpp
-files with definitions, and the last is the test_class_a.cpp
:
#include "class_a.hpp"
#include "class_b.hpp"
template<typename t>
class_a<t>::class_a() : field(42) {}
template<typename t>
class_a<t>::~class_a() { field^= field; }
template<typename t>
void class_a<t>::do_it() {
class_b<t> b;
b.do_something();
}
#include "class_b.hpp"
template<typename t>
class_b<t>::class_b() { info= {}; };
template<typename t>
void class_b<t>::do_something() { return ; }
#include <memory>
#include "class_a.hpp"
int main() {
auto ptr= std::make_unique<class_a<int>>();
ptr->do_it();
return 0;
}
I read elsewhere that this is always the problem with templates and unique_ptr
, and one of the
solutions is to put everything into a single file, without separating the header and definitions. I wonder if this is the only way, or is there some CMake
-way of keeping the same
structure and modularity, and still being able to compile?
The above code gives the compile error:
[ 33%] Built target class_b
Scanning dependencies of target class_a
[ 50%] Building CXX object modules/class_a/CMakeFiles/class_a.dir/class_a.cpp.o
[ 66%] Linking CXX static library libclass_a.a
[ 66%] Built target class_a
Scanning dependencies of target test_class_a
[ 83%] Building CXX object modules/tests/CMakeFiles/test_class_a.dir/test_class_a.cpp.o
[100%] Linking CXX executable test_class_a
/usr/bin/ld: CMakeFiles/test_class_a.dir/test_class_a.cpp.o: in function `main':
/home/ilo/CLionProjects/mwe/modules/tests/test_class_a.cpp:6: undefined reference to `class_a<int>::do_it()'
/usr/bin/ld: CMakeFiles/test_class_a.dir/test_class_a.cpp.o: in function `std::_MakeUniq<class_a<int> >::__single_object std::make_unique<class_a<int>>()':
/usr/include/c++/8/bits/unique_ptr.h:831: undefined reference to `class_a<int>::class_a()'
collect2: error: ld returned 1 exit status
make[3]: *** [modules/tests/CMakeFiles/test_class_a.dir/build.make:86: modules/tests/test_class_a] Error 1
make[2]: *** [CMakeFiles/Makefile2:129: modules/tests/CMakeFiles/test_class_a.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:141: modules/tests/CMakeFiles/test_class_a.dir/rule] Error 2
make: *** [Makefile:131: test_class_a] Error 2