I have a project tree structure that looks like:
Mu_Analysis/
—>Template_Selector/
------->Template_Selector.C
------->Template_Selector.h
—>Compute_L1XE30Efficiency/
------->test_l1xe30_efficiency.C
------->ComputeL1XE30toZBEfficiency.C
------->ComputeL1XE30toZBEfficiency.h
—>Compute_L1XE50_L1XE30_Efficiency/
------->test_l1xe50_efficiency.C
------->ComputeL1XE50toL1XE30Efficiency.C
------->ComputeL1XE50toL1XE30Efficiency.h
—>mu_analysis.root
—>totalCorrection.cpp
Inside Template_Selector and Compute_L1XE30Efficiency, I have generated two sets of TSelectors using TTree::MakeSelector from the same ROOT file. Inside Template_Selector contains the skeleton, default, TSelector generated for the ROOT file. Inside each of the latter sibling directories, I perform one piece of a larger analysis, that reads from/writes to mu_analysis.root . Each TSelector in the sibling directories are run from totalCorrection.cpp using a code block that looks like:
CorrectL1XE30toZB* correctToZB = (CorrectL1XE30toZB*) TSelector::GetSelector("CorrectL1XE30toZB/CorrectL1XE30toZB.C+");
jetm10_chain->Process(correctToZB);
I want for each TSelector class in the sibling directories to derive from the skeleton one in Template_Selector. This is so that I can create member functions in the base class and use them in the derived classes without having to define the same member functions in each TSelector class afterwords (which is currently how I’ve been doing it).
The way I tried to implement this was to add an include line inside each of the header files for the derived classes:
#include "../Template_Selector/Template_Selector.h"
And I switched each derived class definition in the header files to:
class ComputeL1XE30toZBEfficiency : public Template_Selector{...};
Instead of running from totalCorrection.cpp each time, I wrote a macro inside each of the sibling directories to test each TSelector separately. Each one of these smaller macros contain a code block like the one I listed above, but for just the TSelector in the same directory.
When I run the unit test for the ComputeL1XE30toZBEfficiency TSelector, I get a crash. Although I admittedly can’t interpret a lot of it, I received the familiar:
undefined symbol: _ZTI23Jburr_Template_Selector ;
symbol ‘_ZTV27ComputeL1XE30toZBEfficiency’ unresolved while linking symbol ; and
‘You are probably missing the definition of vtable for ComputeL1XE30toZBEfficiency
Maybe you need to load the corresponding shared library?
IncrementalExecutor::executeFunction: symbol ‘_ZTV23Jburr_Template_Selector’ unresolved while linking symbol ‘__ctor_2’!
You are probably missing the definition of vtable for Jburr_Template_Selector
Maybe you need to load the corresponding shared library?’
These error messages tell me that I didn’t specify some includes or library paths to ACLiC properly.
I am not sure if the solution would be to write a LinkDef.h file and then specify the correct path to the Template_Selector inside when listing my #pragmas. Or can I specify the pragmas with the correct path inside the header file to the derived classes as:
#ifdef __MAKECINT__ #pragma link C++ class ../Template_Selector/Template_Selector+; #endif
I’ve attached the full error output, as well as the header files, macros and source code mentioned in the question.
The output of root --version is:
ROOT Version: 6.17/01
Built for linuxx8664gcc on Dec 27 2018, 22:29:43
From heads/master@v6-13-04-2658-g795dc102cd
Thanks,
Joseph
root_question.zip (11.7 KB)