]>
Commit | Line | Data |
---|---|---|
fdfd93b4 | 1 | /** |
2 | * @file ParUtilities.C | |
3 | * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk> | |
4 | * @date Tue Oct 16 17:51:10 2012 | |
5 | * | |
6 | * @brief PAR file utilities | |
7 | * | |
8 | * @ingroup pwglf_forward_trains_util | |
9 | * | |
10 | */ | |
11 | #ifndef PARHELPER_C | |
12 | #define PARHELPER_C | |
13 | #ifndef __CINT__ | |
14 | # include <TString.h> | |
15 | # include <TProof.h> | |
16 | # include <TSystem.h> | |
17 | # include <TError.h> | |
18 | # include <TFile.h> | |
19 | # include <TSystem.h> | |
20 | # include <TROOT.h> | |
21 | # include <fstream> | |
22 | # include <cstdlib> | |
024ec5ac | 23 | # include "Helper.C" |
fdfd93b4 | 24 | #else |
25 | class TString; | |
024ec5ac | 26 | class Helper; |
fdfd93b4 | 27 | #endif |
28 | ||
29 | // =================================================================== | |
30 | /** | |
31 | * Helper to set-up and load PARs | |
32 | * | |
33 | * @ingroup pwglf_forward_trains_util | |
34 | */ | |
35 | struct ParUtilities | |
36 | { | |
37 | /** | |
38 | * Find PAR file (either in current or parent directory or directly | |
46b25775 | 39 | * in $ALICE_ROOT), and link it here |
fdfd93b4 | 40 | * |
41 | * @param what PAR file name (sans .par) | |
42 | * | |
43 | * @return true on success | |
44 | */ | |
45 | static Bool_t Find(const TString& what) | |
46 | { | |
47 | if (what.IsNull()) return false; | |
48 | ||
49 | TString parFile(what); | |
50 | if (!parFile.EndsWith(".par")) parFile.Append(".par"); | |
51 | if (gSystem->AccessPathName(parFile.Data())) { | |
52 | // If not found | |
46b25775 | 53 | TString src; |
c9238874 | 54 | if (gSystem->AccessPathName(Form("../%s", parFile.Data())) == 0) |
46b25775 | 55 | src.Form("../%s", parFile.Data()); |
56 | else { | |
fdfd93b4 | 57 | // If not found |
58 | TString aliParFile = | |
59 | gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s", parFile.Data())); | |
46b25775 | 60 | if (gSystem->AccessPathName(aliParFile.Data()) == 0) |
61 | src = aliParFile; | |
62 | } | |
63 | if (src.IsNull()) { | |
8449e3e0 | 64 | Error("ParUtilities::Find", |
65 | "PAR file %s not found in current or parent " | |
66 | "directory nor in $(ALICE_ROOT)", parFile.Data()); | |
67 | return false; | |
fdfd93b4 | 68 | } |
46b25775 | 69 | // Copy to current directory |
70 | // TFile::Copy(aliParFile, parFile); | |
c9238874 | 71 | Info("", "Found PAR %s at %s", what.Data(), src.Data()); |
46b25775 | 72 | if (gSystem->Exec(Form("ln -s %s %s", src.Data(), parFile.Data())) != 0){ |
73 | Error("ParUtilities::Find", "Failed to symlink %s to %s", | |
74 | src.Data(), parFile.Data()); | |
75 | return false; | |
76 | } | |
fdfd93b4 | 77 | } |
78 | return true; | |
79 | } | |
46b25775 | 80 | /** |
81 | * Unpack and load a PAR file previously found with Find. | |
82 | * | |
83 | * @param name PAR file name | |
84 | * @deprecated Use Find and Build instead | |
85 | * @return true on success | |
86 | */ | |
fdfd93b4 | 87 | static Bool_t Load(const TString& name) |
88 | { | |
89 | if (name.IsNull()) return true; | |
90 | if (!gProof) { | |
91 | Error("ParUtilities::Load", "No connection to a Proof cluster"); | |
92 | return false; | |
93 | } | |
94 | ||
95 | // Load par library | |
96 | TString fn(name); | |
97 | Info("ParUtilities::LoadLibrary", "Uploading %s", name.Data()); | |
98 | ||
99 | // First check in current directory | |
100 | Int_t ret = gProof->UploadPackage(fn, TProof::kRemoveOld); | |
101 | ||
102 | if (ret < 0) { | |
103 | // IF not found there, then check parent directory | |
104 | fn.Prepend("../"); | |
105 | gSystem->ExpandPathName(fn); | |
106 | ret = gProof->UploadPackage(fn); | |
107 | } | |
108 | ||
109 | if (ret < 0) { | |
110 | // If not found in current or parent directory, try the | |
111 | // the ALICE_ROOT directory | |
112 | fn = Form("$ALICE_ROOT/%s.par", name.Data()); | |
113 | gSystem->ExpandPathName(fn); | |
114 | ret = gProof->UploadPackage(fn); | |
115 | } | |
116 | ||
117 | if (ret < 0) { | |
118 | // IF not found, bark | |
119 | Error("ParUtilities::Load", | |
120 | "Could not find module %s.par in current or parent directory " | |
121 | "nor in $ALICE_ROOT", name.Data()); | |
122 | return false; | |
123 | } | |
124 | ||
125 | ret = gProof->EnablePackage(name); | |
126 | Info("ParUtilities::Load", "Enabled package %s (from %s)", | |
127 | name.Data(), fn.Data()); | |
128 | ||
129 | return true; | |
130 | } | |
131 | /** | |
132 | * Unpack, build, and load a PAR file. | |
133 | * | |
134 | * @param what Which PAR file | |
135 | * | |
136 | * @return | |
137 | */ | |
138 | static Bool_t Build(const TString& what) | |
139 | { | |
140 | if (what.IsNull()) return false; | |
141 | ||
142 | TString parFile(what); | |
143 | if (!parFile.EndsWith(".par")) parFile.Append(".par"); | |
144 | ||
145 | // Extract archive | |
146 | gSystem->Exec(Form("tar xzf %s", parFile.Data())); | |
147 | ||
148 | // Change directory into par archive | |
149 | TString cwd = gSystem->WorkingDirectory(); | |
150 | ||
151 | TString dir(what); | |
152 | if (dir.EndsWith(".par")) dir.ReplaceAll(".par", ""); | |
153 | if (!gSystem->ChangeDirectory(dir)) { | |
154 | Error("ParUtilities::Setup", "Failed to change directory to %s", | |
155 | dir.Data()); | |
156 | return false; | |
157 | } | |
158 | ||
159 | // Test the build | |
160 | if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) { | |
161 | Info("ParUtilities::Setup", "Building in PAR archive %s", parFile.Data()); | |
162 | if (gSystem->Exec("PROOF-INF/BUILD.sh")) { | |
163 | Error("ParUtilities::Setup", "Failed to build in PAR directory %s", | |
164 | dir.Data()); | |
165 | gSystem->ChangeDirectory(cwd.Data()); | |
166 | return false; | |
167 | } | |
168 | } | |
c9238874 | 169 | |
170 | // We need to make sure the current directory is in the load path | |
171 | gSystem->SetDynamicPath(Form("%s:%s", gSystem->WorkingDirectory(), | |
172 | gSystem->GetDynamicPath())); | |
fdfd93b4 | 173 | // Check for setup script |
174 | if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) { | |
175 | // Info("ParUtilities::SetupPAR", "Setting up for PAR %s", what); | |
176 | gROOT->Macro("PROOF-INF/SETUP.C"); | |
177 | } | |
178 | if (!gSystem->ChangeDirectory(cwd.Data())) return false; | |
179 | ||
180 | return true; | |
181 | } | |
182 | //__________________________________________________________________ | |
183 | /** | |
184 | * @{ | |
185 | * @name PAR generation from script | |
186 | */ | |
187 | /** | |
188 | * Service function to make a PAR out of a script. | |
189 | * | |
190 | * The script should contain can contain a sub-class of AliAnalysisTask. | |
191 | * The script will be compiled on the slaves before loading the | |
192 | * AliAnalysisManager. Parts to (not) be compiled can be protected like | |
193 | * | |
194 | * @code | |
195 | * #ifdef BUILD_PAR | |
196 | * // This will _only_ be compiled in the servers | |
197 | * #endif | |
198 | * #ifndef BUILD_PAR | |
199 | * // This will not be compiled in the servers | |
200 | * #endif | |
201 | * @endcode | |
202 | * | |
1de8812e | 203 | * @param script Script to upload and compile in the PAR |
204 | * @param deps Dependency pars | |
33438b4c | 205 | * @param isLocal Local build |
1de8812e | 206 | * @param helper Helper |
fdfd93b4 | 207 | * |
208 | * @return true on success. | |
209 | */ | |
1de8812e | 210 | static Bool_t MakeScriptPAR(Bool_t isLocal, |
fdfd93b4 | 211 | const TString& script, |
024ec5ac | 212 | const TString& deps, |
213 | Helper* helper) | |
fdfd93b4 | 214 | { |
024ec5ac | 215 | TObjArray* depList = deps.Tokenize(", "); |
216 | ||
fdfd93b4 | 217 | // --- In local mode, just AcLic and load ------------------------ |
218 | if (isLocal) { | |
024ec5ac | 219 | // Load dependencies |
220 | TIter next(depList); | |
221 | TObject* dep = 0; | |
222 | while ((dep = next())) | |
223 | helper->LoadLibrary(dep->GetName()); | |
224 | ||
225 | // AcLic and load | |
1de8812e | 226 | Info("ParUtilities::MakeScriptPAR", "Loading macro %s", script.Data()); |
024ec5ac | 227 | if (gROOT->LoadMacro(Form("%s++g", script.Data())) < 0) { |
228 | Error("ParUtilities::MakeScriptPAR", | |
229 | "Failed to build local library %s", script.Data()); | |
fdfd93b4 | 230 | return false; |
024ec5ac | 231 | } |
fdfd93b4 | 232 | return true; |
233 | } | |
234 | ||
235 | // --- Get the base name ----------------------------------------- | |
236 | Info("ParUtilities::MakeScriptPAR", "Making par file for %s", | |
237 | script.Data()); | |
238 | TString base(gSystem->BaseName(script)); | |
239 | Int_t idx = base.Last('.'); | |
240 | if (idx != kNPOS) base.Remove(idx); | |
241 | ||
242 | // --- Check name of script file --------------------------------- | |
243 | TString scr(script); | |
244 | TString ext; | |
245 | if (script.EndsWith(".C")) ext = "C"; | |
246 | else if (script.EndsWith(".cxx")) ext = "cxx"; | |
247 | else { ext = "C"; scr.Append(".C"); } | |
248 | ||
249 | // --- Check if we can access the file --------------------------- | |
250 | TString path = TString::Format(".:%s", TROOT::GetMacroPath()); | |
251 | char* loc = gSystem->Which(path, scr); | |
252 | if (!loc) { | |
253 | Error("ParUtilities::MakeScriptPAR", | |
254 | "Script %s not found in %s", scr.Data(), path.Data()); | |
255 | return false; | |
256 | } | |
257 | TString full(loc); | |
258 | ||
259 | // --- Create our temporary directory ---------------------------- | |
260 | TString tmpdir(gSystem->TempDirectory()); | |
261 | int ltempl = tmpdir.Length() + 1 + 5 + 6 + 1; | |
262 | char* templ = new char[ltempl]; | |
263 | snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data()); | |
264 | if (!mkdtemp(templ)) { | |
265 | Error("ParUtilities::MakeScriptPAR", | |
266 | "Failed to generate temporary directory from template %s", | |
267 | templ); | |
268 | return false; | |
269 | } | |
bfab35d9 | 270 | Info("", "Building PAR in %s", templ); |
fdfd93b4 | 271 | |
272 | Bool_t retVal = false; | |
273 | try { | |
274 | // --- Make directories for package ------------------------------ | |
275 | TString dir = TString::Format("%s/%s", templ, base.Data()); | |
276 | // Set-up directories | |
277 | if (gSystem->MakeDirectory(dir) < 0) | |
278 | throw TString::Format("Could not make directory '%s'", base.Data()); | |
279 | if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) | |
280 | throw TString::Format("Could not make directory %s/PROOF-INF", | |
281 | base.Data()); | |
bfab35d9 | 282 | Info("", "Made directory %s", dir.Data()); |
283 | ||
fdfd93b4 | 284 | // --- Copy the script to the setup directory -------------------- |
285 | TString dest = TString::Format("%s/%s.%s", dir.Data(), | |
286 | base.Data(), ext.Data()); | |
287 | Int_t ret = gSystem->CopyFile(full, dest, true); | |
288 | switch (ret) { | |
289 | case -1: throw TString::Format("Couldn't open %s for copy", scr.Data()); | |
290 | case -2: throw TString::Format("File %s exists", dest.Data()); | |
291 | case -3: throw TString::Format("Error while copying %s", scr.Data()); | |
292 | } | |
293 | ||
294 | // --- Make scripts, etc. ---------------------------------------- | |
8449e3e0 | 295 | if (!MakeScriptBuildScript(dir, base)) |
fdfd93b4 | 296 | throw TString::Format("Failed to make build script"); |
8449e3e0 | 297 | if (!MakeScriptUtilityScript(dir)) |
fdfd93b4 | 298 | throw TString::Format("Failed to make utility script"); |
8449e3e0 | 299 | if (!MakeScriptBuildMacro(dir, base, ext, depList)) |
fdfd93b4 | 300 | throw TString::Format("Failed to make build macro"); |
8449e3e0 | 301 | if (!MakeScriptSetupMacro(dir, base, ext, depList)) |
fdfd93b4 | 302 | throw TString::Format("Failed to setup macro"); |
303 | ||
304 | // --- Pack up the archive --------------------------------------- | |
305 | ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)", | |
306 | templ, base.Data(),base.Data())); | |
307 | if (ret != 0) | |
308 | throw TString::Format("Failed to create PAR file %s.PAR from %s", | |
309 | base.Data(), dir.Data()); | |
bfab35d9 | 310 | |
311 | Info("", "Made par archive %s/%s.par - moving here", | |
312 | templ, base.Data()); | |
fdfd93b4 | 313 | // --- Move PAR file to here ------------------------------------- |
314 | ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(), | |
315 | base.Data())); | |
316 | if (ret != 0) | |
317 | throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", | |
318 | templ, base.Data(), base.Data(), | |
319 | gSystem->GetError()); | |
320 | retVal = true; | |
321 | } | |
322 | catch (TString& e) { | |
9c686cb4 | 323 | Error("ParUtilities::MakeScriptPAR", "%s", e.Data()); |
fdfd93b4 | 324 | retVal = false; |
325 | } | |
326 | ||
327 | // --- Remove temporary directory -------------------------------- | |
328 | gSystem->Exec(Form("rm -rf %s", templ)); | |
329 | ||
330 | return retVal; | |
331 | } | |
332 | /** | |
333 | * Write a build script | |
334 | * | |
335 | * @param dir Directory to put it in | |
33438b4c | 336 | * @param base Base name |
fdfd93b4 | 337 | * |
338 | * @return true on success | |
339 | */ | |
8449e3e0 | 340 | static Bool_t MakeScriptBuildScript(const TString& dir, |
341 | const TString& base) | |
fdfd93b4 | 342 | { |
343 | // Make our build file | |
344 | std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data())); | |
345 | if (!out) { | |
8449e3e0 | 346 | Error("ParUtilities::MakeScriptBuildScript", |
347 | "Failed to open out shell script"); | |
fdfd93b4 | 348 | return false; |
349 | } | |
350 | out << "#!/bin/sh\n" | |
351 | << "if test x$ALICE_ROOT != x ; then\n" | |
352 | << " if test x$ALICE_TARGET = x ; then\n" | |
353 | << " export ALICE_TARGET=`$ROOTSYS/bin/root-config --arch`\n" | |
354 | << " fi\n" | |
355 | << " export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:" | |
356 | << "${ALICE_ROOT}/lib/tgt_${ALICE_TARGET}\n" | |
357 | << "fi\n" | |
871d7b56 | 358 | << "# printenv | sort -u\n" |
fdfd93b4 | 359 | << "echo BUILD.sh@`hostname`: Building " << base << "\n" |
360 | << "root.exe -l -out -q PROOF-INF/BUILD.C 2>&1 | tee " | |
361 | << base << ".log\n" | |
362 | << "echo BUILD.sh@`hostname`: done: $?\n" | |
363 | << std::endl; | |
364 | out.close(); | |
365 | if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) { | |
8449e3e0 | 366 | Error("ParUtilities::MakeScriptBuildScript", |
fdfd93b4 | 367 | "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", |
368 | dir.Data()); | |
369 | return false; | |
370 | } | |
371 | return true; | |
372 | } | |
373 | /** | |
374 | * Write a build macro | |
375 | * | |
376 | * @param dir Directory to put macro in | |
377 | * @param deps Dependencies | |
378 | * @param base Base name of script to compile | |
33438b4c | 379 | * @param ext `extension' - last part of file name |
fdfd93b4 | 380 | * |
381 | * @return true on success | |
382 | */ | |
8449e3e0 | 383 | static Bool_t MakeScriptBuildMacro(const TString& dir, |
384 | const TString& base, | |
385 | const TString& ext, | |
386 | const TCollection* deps) { | |
fdfd93b4 | 387 | std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data())); |
388 | if (!out) { | |
8449e3e0 | 389 | Error("ParUtilities::MakeScriptBuildMacro","Failed to open build script"); |
fdfd93b4 | 390 | return false; |
391 | } | |
392 | out << "void BUILD() {\n" | |
393 | << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n" | |
394 | << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n" | |
395 | << " LoadROOTLibs();\n" | |
396 | << " AddAliROOT();\n"; | |
397 | if (deps) { | |
398 | TIter next(deps); | |
399 | TObject* dep = 0; | |
400 | while ((dep = next())) { | |
401 | out << " AddDep(\"" << dep->GetName() << "\");\t" | |
402 | << " LoadDep(\"" << dep->GetName() << "\");\n"; | |
403 | } | |
404 | } | |
405 | out << " // gDebug = 5;\n" | |
871d7b56 | 406 | << " // gSystem->ListLibraries();\n" |
fdfd93b4 | 407 | << " int ret = gROOT->LoadMacro(\"" |
408 | << base << "." << ext << "++g\");\n" | |
409 | << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n" | |
410 | << " // else Info(\"BUILD\", \"Made " << base << "\");\n" | |
411 | << "}\n" | |
412 | << std::endl; | |
413 | out.close(); | |
414 | ||
415 | return true; | |
416 | } | |
417 | /** | |
418 | * Make a utility macro | |
419 | * | |
420 | * @param dir Directory to put the macro in | |
421 | * | |
422 | * @return true on success | |
423 | */ | |
8449e3e0 | 424 | static Bool_t MakeScriptUtilityScript(const TString& dir) |
fdfd93b4 | 425 | { |
426 | std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data())); | |
427 | if (!out) { | |
8449e3e0 | 428 | Error("ParUtilities::MakeScriptUtilityScript", |
429 | "Failed to open utility script"); | |
fdfd93b4 | 430 | return false; |
431 | } | |
432 | out << "void LoadROOTLibs() {\n" | |
433 | << " gSystem->Load(\"libVMC\");\n" | |
434 | << " gSystem->Load(\"libNet\");\n" | |
435 | << " gSystem->Load(\"libTree\");\n" | |
436 | << " gSystem->Load(\"libPhysics\");\n" | |
437 | << " gSystem->Load(\"libMinuit\");\n" | |
438 | << "}\n\n" | |
439 | << "void AddAliROOT() {\n" | |
440 | << " TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n" | |
441 | << " if (val.IsNull())\n" | |
442 | << " Warning(\"Add\",\"ALICE_ROOT not defined\");\n" | |
443 | << " else\n" | |
444 | << " gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n" | |
445 | << "}\n\n" | |
446 | << "void AddDep(const char* env) {\n" | |
447 | << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n" | |
448 | << " if (val.IsNull())\n" | |
449 | << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n" | |
450 | << " else {\n" | |
871d7b56 CHC |
451 | << " // gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n" |
452 | << " // Prepend to include path\n" | |
453 | << " TString incPath(gSystem->GetIncludePath());\n" | |
454 | << " incPath.Prepend(Form(\"-I../%s \",val.Data()));\n" | |
455 | << " gSystem->SetIncludePath(incPath);\n" | |
456 | << " // Printf(\"Include path: %s\",incPath.Data());\n" | |
fdfd93b4 | 457 | << " }\n" |
458 | << "}\n\n" | |
459 | << "void LoadDep(const char* name) {\n" | |
871d7b56 CHC |
460 | << " // Printf(\"Loading dependency \\\"%s\\\" ...\",name);\n" |
461 | << " // gSystem->AddDynamicPath(Form(\"../%s\",name));\n" | |
462 | << " // Prepend to dynamic path\n" | |
463 | << " TString dynPath(gSystem->GetDynamicPath());\n" | |
464 | << " dynPath.Prepend(Form(\"../%s:\",name));\n" | |
465 | << " gSystem->SetDynamicPath(dynPath);\n" | |
466 | << " // Printf(\"Dynamic path: %s\",dynPath.Data());\n" | |
fdfd93b4 | 467 | << " char* full = gSystem->DynamicPathName(name,true);\n" |
468 | << " if (!full) \n" | |
469 | << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n" | |
470 | << " if (!full) \n" | |
471 | << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n" | |
871d7b56 CHC |
472 | << " if (!full) \n" |
473 | << " full = gSystem->DynamicPathName(Form(\"%s_C.so\",name),true);\n" | |
474 | << " if (!full) \n" | |
475 | << " full = gSystem->DynamicPathName(Form(\"%s_h.so\",name),true);\n" | |
fdfd93b4 | 476 | << " if (!full) {\n" |
477 | << " Warning(\"LoadDep\",\"Module %s not found\", name);\n" | |
478 | << " return;\n" | |
479 | << " }\n" | |
871d7b56 | 480 | << " Printf(\"Loading \\\"%s\\\" for \\\"%s\\\"\",full,name);\n" |
fdfd93b4 | 481 | << " gSystem->Load(full);\n" |
482 | << "}\n" | |
483 | << std::endl; | |
484 | out.close(); | |
485 | return true; | |
486 | } | |
487 | /** | |
488 | * Make a setup script | |
489 | * | |
490 | * @param dir Directory to put it in | |
491 | * @param base Base name of target script | |
492 | * @param ext Extension of target script | |
493 | * @param deps Dependencies | |
494 | * | |
495 | * @return true on success | |
496 | */ | |
8449e3e0 | 497 | static Bool_t MakeScriptSetupMacro(const TString& dir, |
498 | const TString& base, | |
499 | const TString& ext, | |
500 | const TCollection* deps) | |
fdfd93b4 | 501 | { |
502 | // Make our set-up script | |
503 | std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data())); | |
504 | if (!out) { | |
8449e3e0 | 505 | Error("ParUtilities::MakeScriptSetupMacro", |
506 | "Failed to open setup script"); | |
fdfd93b4 | 507 | return false; |
508 | } | |
509 | out << "void SETUP() {\n" | |
510 | << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n" | |
871d7b56 | 511 | << " Printf(\"Loading \\\"" << base << "\\\" ...\");\n" |
fdfd93b4 | 512 | << " LoadROOTLibs();\n" |
513 | << " // Info(\"SETUP\",\"Loading libraries\");\n"; | |
514 | if (deps) { | |
515 | TIter next(deps); | |
516 | TObject* dep = 0; | |
517 | while ((dep = next())) | |
518 | out << " LoadDep(\"" << dep->GetName() << "\");\n"; | |
519 | } | |
520 | out << " // gDebug = 5;\n" | |
521 | << " // Info(\"SETUP\",\"Loading " << base <<"_"<< ext << ".so\");\n" | |
522 | << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n" | |
523 | << " // gDebug = 0;\n" | |
524 | << " gROOT->ProcessLine(\".include " << base << "\");\n" | |
525 | << " gSystem->Setenv(\"" << base << "_INCLUDE\",\"" | |
526 | << base << "\");\n" | |
527 | << " // Info(\"SETUP\", \"Done\");\n" | |
528 | << "}\n" | |
529 | << std::endl; | |
530 | out.close(); | |
531 | return true; | |
532 | } | |
533 | /* @} */ | |
8449e3e0 | 534 | //__________________________________________________________________ |
535 | /** | |
536 | * @{ | |
537 | * @name PAR generation from aux file list | |
538 | */ | |
539 | static Bool_t MakeAuxFilePAR(const TList& files, | |
540 | const TString& name, | |
541 | Bool_t verbose=false) | |
542 | { | |
543 | // --- Check input ----------------------------------------------- | |
544 | if (files.GetEntries() <= 0) return true; | |
545 | ||
546 | // --- Create our temporary directory ---------------------------- | |
547 | Bool_t retval = true; | |
548 | TString tmpdir(gSystem->TempDirectory()); | |
549 | int ltempl = tmpdir.Length() + 1 + 5 + 6 + 1; | |
550 | char* templ = new char[ltempl]; | |
551 | snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data()); | |
552 | if (!mkdtemp(templ)) { | |
553 | Error("ParUtilities::MakeAuxFilePAR", | |
554 | "Failed to generate temporary directory from template %s", | |
555 | templ); | |
556 | return false; | |
557 | } | |
558 | if (verbose) Printf("Preparing PAR file in %s", templ); | |
559 | ||
560 | try { | |
561 | // --- Make directories for package ------------------------------ | |
562 | TString dir = TString::Format("%s/%s", templ, name.Data()); | |
563 | // Set-up directories | |
564 | if (gSystem->MakeDirectory(dir) < 0) | |
565 | throw TString::Format("Could not make directory '%s'", name.Data()); | |
566 | if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) | |
567 | throw TString::Format("Could not make directory %s/PROOF-INF", | |
568 | name.Data()); | |
569 | ||
570 | TIter next(&files); | |
571 | TObject* o = 0; | |
572 | while ((o = next())) { | |
573 | TString fn(o->GetName()); | |
574 | if (verbose) Printf("Got %s", fn.Data()); | |
575 | if (fn.BeginsWith("/")) { | |
576 | Warning("MakeAuxFilePAR", "Will not include absolute path %s", | |
577 | fn.Data()); | |
578 | continue; // absolute path | |
579 | } | |
580 | ||
581 | if (gSystem->AccessPathName(fn.Data())) { | |
582 | Warning("MakeAuxFilePAR", "Cannot access %s", fn.Data()); | |
583 | continue; // non-exist | |
584 | } | |
585 | // Loop over path components and make directories as needed | |
586 | TObjArray* comps = fn.Tokenize("/"); | |
587 | TString cur = dir; | |
588 | Int_t n = comps->GetEntriesFast(); | |
589 | if (verbose) Printf("Got %d path components in %s", n-1, fn.Data()); | |
590 | Int_t lvl = 0; | |
591 | for (Int_t i = 0; i < n-1; i++) { | |
592 | TObjString* comp = static_cast<TObjString*>(comps->At(i)); | |
593 | TString& c = comp->String(); | |
594 | if (c.IsNull()) continue; | |
595 | if (c.EqualTo(".")) continue; | |
596 | ||
597 | Bool_t doMake = true; | |
598 | if (c.EqualTo("..")) { doMake = false; lvl--; } | |
599 | ||
600 | cur = gSystem->ConcatFileName(cur, c); | |
601 | if (lvl < 0) { | |
602 | Warning("MakeAuxFilePAR", "Path %s points outside archive, ignored", | |
603 | cur.Data()); | |
604 | break; | |
605 | } | |
606 | ||
607 | if (doMake) { | |
608 | lvl++; | |
609 | if (!gSystem->AccessPathName(cur)) continue; | |
610 | if (verbose) Printf("Making directory %s", cur.Data()); | |
611 | gSystem->MakeDirectory(cur); | |
612 | } | |
613 | } // for(i) | |
614 | if (verbose) Printf("cur=%s for %s lvl=%d", cur.Data(), fn.Data(), lvl); | |
615 | comps->Delete(); | |
616 | if (lvl < 0) continue; | |
617 | ||
618 | TString dest = TString::Format("%s/%s", cur.Data(), | |
619 | gSystem->BaseName(fn.Data())); | |
620 | if (verbose) Printf("%s -> %s", fn.Data(), dest.Data()); | |
621 | Int_t ret = gSystem->CopyFile(fn, dest, true); | |
622 | switch (ret) { | |
623 | case -1: throw TString::Format("Couldn't open %s for copy", fn.Data()); | |
624 | case -2: throw TString::Format("File %s exists", dest.Data()); | |
625 | case -3: throw TString::Format("Error while copying %s", fn.Data()); | |
626 | } | |
627 | } | |
628 | ||
629 | { | |
630 | // Make our build file | |
631 | if (verbose) Printf("Making build script"); | |
632 | std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data())); | |
633 | if (!out) { | |
634 | Error("ParUtilities::MakeAuxFilePAR", | |
635 | "Failed to open out shell script"); | |
636 | return false; | |
637 | } | |
638 | out << "#!/bin/sh\n\n" | |
639 | << "echo \"Nothing to be done\"\n\n" | |
640 | << "# EOF" << std::endl; | |
641 | out.close(); | |
642 | if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755)) { | |
643 | Error("ParUtilities::MakeAuxFilePAR", | |
644 | "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", | |
645 | dir.Data()); | |
646 | return false; | |
647 | } | |
648 | } | |
649 | { | |
650 | if (verbose) Printf("Making setup script"); | |
651 | // Make our setup file | |
652 | std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data())); | |
653 | if (!out) { | |
654 | Error("ParUtilities::MakeAuxFilePAR", | |
655 | "Failed to open out ROOT script"); | |
656 | return false; | |
657 | } | |
bfab35d9 | 658 | // The SETUP script is executed in the package's directory in |
659 | // the package cache - not in the session directory. Hence, | |
660 | // we take special care to get a link to the session directory | |
661 | // from the package cache directory | |
8449e3e0 | 662 | out << "void SETUP()\n" |
663 | << "{\n" | |
664 | << " TString oldDir(gSystem->WorkingDirectory());\n" | |
bfab35d9 | 665 | << " TSystemDirectory* dir = new TSystemDirectory(\".\",\".\");\n" |
8449e3e0 | 666 | << " TList* files = dir->GetListOfFiles();\n" |
667 | << " if (!gSystem->ChangeDirectory(oldDir)) {\n" | |
668 | << " Error(\"SETUP\", \"Failed to go back to %s\",\n" | |
669 | << " oldDir.Data());\n" | |
670 | << " return;\n" | |
671 | << " }\n" | |
672 | << " if (!files) {\n" | |
673 | << " Warning(\"SETUP\", \"No files\");\n" | |
674 | << " gSystem->Exec(\"pwd; ls -al\");\n" | |
675 | << " return;\n" | |
676 | << " }\n" | |
677 | << " files->Sort();\n" | |
bfab35d9 | 678 | << " TString pkgDir = gSystem->WorkingDirectory();\n" |
679 | << " TString sesDir = gProofServ->GetSessionDir();\n" | |
680 | << " Info(\"\",\"Session dir: %s\",sesDir);\n" | |
8449e3e0 | 681 | << " TIter next(files);\n" |
682 | << " TSystemFile* file = 0;\n" | |
683 | << " while ((file = static_cast<TSystemFile*>(next()))) {\n" | |
684 | << " TString name(file->GetName());\n" | |
685 | << " if (name == \".\" || name == \"..\") continue;\n" | |
686 | << " TString title(file->GetTitle());\n" | |
bfab35d9 | 687 | << " TString full(gSystem->ConcatFileName(pkgDir.Data(),\n" |
8449e3e0 | 688 | << " name.Data()));\n" |
bfab35d9 | 689 | << " TString tgt(gSystem->ConcatFileName(sesDir.Data(),\n" |
690 | << " name.Data()));\n" | |
691 | << " if (file->IsA()->InheritsFrom(TSystemDirectory::Class())){\n" | |
692 | << " gSystem->mkdir(tgt.Data(), true);\n" | |
693 | << " continue;\n" | |
694 | << " }\n" | |
695 | << " Info(\"\",\"Linking %s to %s\",full.Data(),tgt.Data());\n" | |
696 | << " gSystem->Symlink(full, tgt);\n" | |
8449e3e0 | 697 | << " }\n" |
698 | << "}\n" | |
699 | << "// EOF " << std::endl; | |
700 | out.close(); | |
701 | } | |
702 | if (verbose) Printf("Packing up"); | |
703 | Int_t ret = 0; | |
704 | ret = gSystem->Exec(Form("(cd %s && tar -c%szf %s.par %s)", | |
705 | templ, (verbose ? "v" : ""), | |
706 | name.Data(),name.Data())); | |
707 | if (ret != 0) | |
708 | throw TString::Format("Failed to create PAR file %s.PAR from %s", | |
709 | name.Data(), name.Data()); | |
710 | ||
711 | // --- Move PAR file to here ------------------------------------- | |
712 | if (verbose) Printf("Move here"); | |
713 | ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, name.Data(), | |
714 | name.Data())); | |
715 | if (ret != 0) | |
716 | throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", | |
717 | templ, name.Data(), name.Data(), | |
718 | gSystem->GetError()); | |
719 | ||
720 | ||
721 | if (verbose) { | |
722 | Printf("List content"); | |
723 | gSystem->Exec(Form("tar tzf %s.par", name.Data())); | |
724 | } | |
725 | retval = true; | |
726 | } | |
727 | catch (TString& e) { | |
728 | Error("ParUtilities::MakeAuxFilePAR", "%s", e.Data()); | |
729 | retval = false; | |
730 | } | |
731 | ||
732 | // --- Remove temporary directory -------------------------------- | |
733 | gSystem->Exec(Form("rm -rf %s", templ)); | |
734 | ||
735 | return retval; | |
736 | } | |
fdfd93b4 | 737 | }; |
738 | #endif | |
739 | // | |
740 | // EOF | |
741 | // |