]>
Commit | Line | Data |
---|---|---|
04a0c008 | 1 | //-*- Mode: C++ -*- |
2 | // $Id$ | |
3 | ||
4 | /// @file run-macro.C | |
5 | /// @author Matthias.Richter@ift.uib.no | |
6 | /// @date 2012-04-06 | |
7 | /// @brief Compile and run a macro | |
8 | /// | |
9 | /// Dependency header files and classes are automatically searched in the | |
10 | /// current directory and in all AliRoot libraries | |
11 | ||
12 | #if defined(__CINT__) && !defined(__MAKECINT__) | |
13 | TString GetIncludeHeaders(const char* filename, TString& headers, TString& libs, bool loadClass=true); | |
14 | ||
15 | void run_macro(const char* macro, bool bExecute=true, const char* includePath=NULL, const char* libraries=NULL) | |
16 | { | |
17 | gSystem->AddIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT -I$ALICE_ROOT/include "); | |
18 | if (includePath) gSystem->AddIncludePath(includePath); | |
19 | ||
20 | TString strLibraries(libraries); | |
21 | TObjArray* tokens=strLibraries.Tokenize(" "); | |
22 | if (tokens) { | |
23 | TIter next(tokens); | |
24 | TObject* object=NULL; | |
25 | while ((object=next())!=NULL) { | |
26 | gSystem->Load(object->GetName()); | |
27 | } | |
28 | delete tokens; | |
29 | } | |
30 | ||
31 | TString dependencyHeader; | |
32 | TString dependencyLibraries; | |
33 | GetIncludeHeaders(macro, dependencyHeader, dependencyLibraries, true); | |
34 | ||
35 | TString command(macro); | |
36 | Int_t error=0; | |
37 | command+="+g"; | |
38 | if (bExecute) { | |
39 | gROOT->Macro(command); | |
40 | } else { | |
41 | gROOT->LoadMacro(command); | |
42 | } | |
43 | } | |
44 | ||
45 | TString GetIncludeHeaders(const char* filename, TString& headers, TString& libs, bool loadClass) | |
46 | { | |
47 | // scan the file and add all include headers found by path | |
48 | // to the parameter headers | |
49 | ifstream input(filename); | |
50 | ||
51 | if (input.bad()) { | |
52 | cerr << "failed to open file " << filename << endl; | |
53 | return headers; | |
54 | } | |
55 | TString line; | |
56 | while (!line.ReadLine(input).eof()) { | |
57 | if (!line.Contains("#include") || !line.Contains(".h")) continue; | |
58 | line=line(0, line.Index(".h"));line+=".h"; | |
59 | line.Replace(0, line.Index("#include"), ""); | |
60 | line.ReplaceAll("#include", ""); | |
61 | line.ReplaceAll(" ", ""); | |
62 | line.ReplaceAll("\"", ""); | |
63 | if (!line.BeginsWith("Ali") && !line.BeginsWith("T")) continue; | |
64 | if (gSystem->AccessPathName(line)!=0) { | |
65 | // not an include file in the current directory, check if class | |
66 | // is available or find library | |
67 | line.ReplaceAll(".h",""); | |
68 | //cout << "checking class " << line << endl; | |
69 | if (TClass::GetClass(line)==NULL) { | |
70 | TString command; | |
71 | TString resfilename(gSystem->TempDirectory()); resfilename+="/findlib.txt"; | |
72 | command.Form("for lib in $ALICE_ROOT/lib/*/lib*.so; do (nm $lib | grep %s | grep ' T ' | grep Class_Name > /dev/null) && echo $lib > %s; done", line.Data(), resfilename.Data()); | |
73 | gSystem->Exec(command); | |
74 | ifstream resfile(resfilename.Data()); | |
75 | if (resfile.good()) { | |
76 | TString result; | |
77 | if (!result.ReadLine(resfile).eof()) { | |
78 | Ssiz_t haveSlash=-1; | |
79 | while ((haveSlash=result.First('/'))>=0) result.Replace(0, haveSlash+1, ""); | |
80 | if (!libs.Contains(result)) { | |
81 | cout << "loading dependency library '" << result << "' for class '" << line << "'" << endl; | |
82 | gSystem->Load(result); | |
83 | if (!libs.IsNull()) libs+=" "; | |
84 | libs+=result; | |
85 | } | |
86 | } | |
87 | command="rm "; command+=resfilename; | |
88 | gSystem->Exec(command); | |
89 | } | |
90 | } | |
91 | } else { | |
92 | if (headers.Contains(line)) { | |
93 | if (!headers.BeginsWith(line)) { | |
94 | headers.ReplaceAll(line, ""); | |
95 | if (!headers.IsNull()) headers.Insert(0, " "); | |
96 | headers.Insert(0, line); | |
97 | } | |
98 | continue; | |
99 | } | |
100 | if (!headers.IsNull()) headers.Insert(0, " "); | |
101 | headers.Insert(0, line); | |
102 | TString source=line; source.ReplaceAll(".h", ".cxx"); | |
103 | if (gSystem->AccessPathName(source)==0) { | |
104 | GetIncludeHeaders(source, headers, libs); | |
105 | } | |
106 | GetIncludeHeaders(line, headers, libs); | |
107 | if (loadClass && gSystem->AccessPathName(source)==0) { | |
108 | line.ReplaceAll(".h", ""); | |
109 | if (TClass::GetClass(line)==NULL) { | |
110 | source+="+g"; | |
111 | gROOT->LoadMacro(source); | |
112 | } | |
113 | } | |
114 | } | |
115 | } | |
116 | return headers; | |
117 | } | |
118 | ||
119 | void run_macro() | |
120 | { | |
121 | cout << endl; | |
122 | cout << "run-macro.C" << endl; | |
123 | cout << "Compile and run a macro, include header dependencies are searched in all" << endl; | |
124 | cout << "AliRoot libraries and the local directory." << endl; | |
125 | cout << endl; | |
126 | cout << "Usage:" << endl; | |
127 | cout << " aliroot -l run-macro.C'(\"macro.C\, execute, \"include\", \"libraries\")'" << endl; | |
128 | cout << endl; | |
129 | cout << "Parameters:" << endl; | |
130 | cout << " macro path (mandatory)" << endl; | |
131 | cout << " execute (optional, default 'true')" << endl; | |
132 | cout << " include (optional, e.g. -I$ALICE_ROOT/TPC)" << endl; | |
133 | cout << " libraries (optional, e.g. libTPCbase.so)" << endl; | |
134 | cout << endl; | |
135 | } | |
136 | ||
137 | #elif | |
138 | { | |
139 | cerr << "this macro can not be compiled, remove option '+'" << endl; | |
140 | } | |
141 | #endif |