I have a question about Integrating ROOT into CMake projects
, I want a simple cmake example to use ROOT and it’s dictionary mechanism. I find an very nice example wrote by Enrico: with_cmake example
It has only 5 files:
- readwrite_twoints.cpp
- twoints.cpp
- twoints.hpp
- LinkDef.h
- CMakeLists.txt
I can easily build and run it (with CMake3.24.0
and ROOT6.26/06
on Ubuntu18.04
)
git clone https://github.com/eguiraud/root_dictionaries_tutorial
mkdir root_dictionaries_tutorial/with_cmake/build
cd root_dictionaries_tutorial/with_cmake/build
cmake ../
make -j4
./readwrite_twoints
But the question is, if I add an TVector3
object to class twoints
in twoints.hpp
:
// twoints.hpp
#pragma once
#include "TVector3.h"
class TwoInts {
int _a;
int _b;
public:
TVector3 r;
TwoInts() {}
TwoInts(int a, int b) : _a(a), _b(b) {}
int GetA() const;
int GetB() const;
TwoInts& SetA(int a);
TwoInts& SetB(int b);
};
But I get this error when I make
it:
[100%] Linking CXX executable readwrite_twoints
CMakeFiles/readwrite_twoints.dir/readwrite_twoints.cpp.o: In function `TVector3::~TVector3()':
readwrite_twoints.cpp:(.text._ZN8TVector3D2Ev[_ZN8TVector3D5Ev]+0xf): undefined reference to `vtable for TVector3'
CMakeFiles/readwrite_twoints.dir/readwrite_twoints.cpp.o: In function `TVector3::TVector3()':
readwrite_twoints.cpp:(.text._ZN8TVector3C2Ev[_ZN8TVector3C5Ev]+0x1b): undefined reference to `vtable for TVector3'
collect2: error: ld returned 1 exit status
CMakeFiles/readwrite_twoints.dir/build.make:117: recipe for target 'readwrite_twoints' failed
make[2]: *** [readwrite_twoints] Error 1
CMakeFiles/Makefile2:84: recipe for target 'CMakeFiles/readwrite_twoints.dir/all' failed
make[1]: *** [CMakeFiles/readwrite_twoints.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2
I’m not familiar with root and cmake, especially the dictionary mechanism, any comment will be helpful for me, thanks!
For convenience, this is the content of the CMakeList.txt
cmake_minimum_required(VERSION 3.9)
project (readwrite_twoints CXX)
# Look for ROOT. As long as an installation is available in the environment, this should succeed.
message(STATUS "Looking for ROOT")
find_package(ROOT REQUIRED COMPONENTS RIO)
message(STATUS "ROOT ${ROOT_VERSION} found at ${ROOT_BINDIR}")
add_executable(readwrite_twoints readwrite_twoints.cpp twoints.cpp)
target_link_libraries(readwrite_twoints ROOT::RIO)
# attach dictionaries to the executable. first, tell it where to look for headers required by the dictionaries:
target_include_directories(readwrite_twoints PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
# then generate dictionaries and add them as a dependency of the executable (via the MODULE parameter):
ROOT_GENERATE_DICTIONARY(twoints_dict twoints.hpp MODULE readwrite_twoints LINKDEF LinkDef.h)