/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
CommonTools/Utils/src/ExpressionEvaluator.cc
151 строка
5 KB
David Lange
Clean up unneeded header includes and corresponding build file update
02 сен 2020, 10:35
Не верифицирован
02 сен 2020, 10:35
a5c777c
Код
Авторство
О чём код?
#include "CommonTools/Utils/interface/ExpressionEvaluator.h" #include "FWCore/Utilities/interface/GetEnvironmentVariable.h" #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "popenCPP.h" #include <fstream> #include <regex> #include <dlfcn.h> // #define VI_DEBUG #ifdef VI_DEBUG #include <iostream> #define COUT std::cout #else #define COUT LogDebug("ExpressionEvaluator") #endif using namespace reco::exprEvalDetails; namespace { std::string generateName() { auto n1 = execSysCommand("uuidgen | sed 's/-//g'"); n1.pop_back(); return n1; } void remove(std::string const& name, std::string const& tmpDir = "/tmp") { std::string sfile = tmpDir + "/" + name + ".cc"; std::string ofile = tmpDir + "/" + name + ".so"; std::string rm = "rm -f "; rm += sfile + ' ' + ofile; system(rm.c_str()); } } // namespace namespace reco { ExpressionEvaluator::ExpressionEvaluator(const char* pkg, const char* iname, std::string const& iexpr) : m_name("VI_" + generateName()) { std::string pch = pkg; pch += "/src/precompile.h"; std::string quote("\""); auto arch = edm::getEnvironmentVariable("SCRAM_ARCH"); auto baseDir = edm::getEnvironmentVariable("CMSSW_BASE"); auto relDir = edm::getEnvironmentVariable("CMSSW_RELEASE_BASE"); std::string sfile = baseDir + "/tmp/" + m_name + ".cc"; std::string ofile = baseDir + "/tmp/" + m_name + ".so"; std::string incDir = "/include/" + arch + "/"; std::string cxxf; { // look in local dir std::string file = baseDir + incDir + pch + ".cxxflags"; std::ifstream ss(file.c_str()); COUT << "local file: " << file << std::endl; if (ss) { std::getline(ss, cxxf); incDir = baseDir + incDir; } else { // look in release area std::string file = relDir + incDir + pch + ".cxxflags"; COUT << "file in release area: " << file << std::endl; std::ifstream ss(file.c_str()); if (ss) { std::getline(ss, cxxf); incDir = relDir + incDir; } else { // look in release is a patch area auto paDir = edm::getEnvironmentVariable("CMSSW_FULL_RELEASE_BASE"); if (paDir.empty()) throw cms::Exception("ExpressionEvaluator", "error in opening patch area for " + baseDir); std::string file = paDir + incDir + pch + ".cxxflags"; COUT << "file in base release area: " << file << std::endl; std::ifstream ss(file.c_str()); if (!ss) throw cms::Exception( "ExpressionEvaluator", pch + " file not found neither in " + baseDir + " nor in " + relDir + " nor in " + paDir); std::getline(ss, cxxf); incDir = paDir + incDir; } } { std::regex rq("-I[^ ]+"); cxxf = std::regex_replace(cxxf, rq, std::string("")); } { std::regex rq("=\""); cxxf = std::regex_replace(cxxf, rq, std::string("='\"")); } { std::regex rq("\" "); cxxf = std::regex_replace(cxxf, rq, std::string("\"' ")); } COUT << '|' << cxxf << "|\n" << std::endl; } std::string cpp = "c++ -H -Wall -shared -Winvalid-pch "; cpp += cxxf; cpp += " -I" + incDir; cpp += " -o " + ofile + ' ' + sfile + " 2>&1\n"; COUT << cpp << std::endl; // prepare the file to compile std::string factory = "factory" + m_name; std::string source = std::string("#include ") + quote + pch + quote + "\n"; source += "struct " + m_name + " final : public " + iname + "{\n"; source += iexpr; source += "\n};\n"; source += "extern " + quote + 'C' + quote + ' ' + std::string(iname) + "* " + factory + "() {\n"; source += "static " + m_name + " local;\n"; source += "return &local;\n}\n"; COUT << source << std::endl; { std::ofstream tmp(sfile.c_str()); tmp << source << std::endl; } // compile auto ss = execSysCommand(cpp); COUT << ss << std::endl; void* dl = dlopen(ofile.c_str(), RTLD_LAZY); if (!dl) { remove(m_name, baseDir + "/tmp"); throw cms::Exception("ExpressionEvaluator", std::string("compilation/linking failed\n") + cpp + ss + "dlerror " + dlerror()); return; } m_expr = dlsym(dl, factory.c_str()); remove(m_name, baseDir + "/tmp"); } ExpressionEvaluator::~ExpressionEvaluator() { remove(m_name, edm::getEnvironmentVariable("CMSSW_BASE") + "/tmp"); } } // namespace reco