123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include "build-config.h"
- #include "jliball.hpp"
- #include "jmisc.hpp"
- #include "jstream.hpp"
- #include "hql.hpp"
- #include "hqlexpr.hpp"
- #include "hqlecl.hpp"
- #include "hqlthql.hpp"
- #include "hqlcerrors.hpp"
- #include "hqlcatom.hpp"
- #include "hqllib.ipp"
- #include "hqlutil.hpp"
- #include "hqlhtcpp.ipp"
- #include "hqlwcpp.hpp"
- #include "hqllib.ipp"
- #include "hqlttcpp.ipp"
- #include "workunit.hpp"
- #include "thorplugin.hpp"
- #ifdef _DEBUG
- #define IS_DEBUG_BUILD true
- #else
- #define IS_DEBUG_BUILD false
- #endif
- #define MAIN_MODULE_TEMPLATE "thortpl.cpp"
- #define HEADER_TEMPLATE "thortpl.hpp"
- #define CHILD_MODULE_TEMPLATE "childtpl.cpp"
- #define PROTO_TEMPLATE "prototpl.cpp"
- class NullContextCallback : implements ICodegenContextCallback, public CInterface
- {
- public:
- NullContextCallback(IWorkUnit * _wu) : workunit(_wu) {}
- IMPLEMENT_IINTERFACE
- virtual void noteCluster(const char *clusterName) override {}
- virtual void pushCluster(const char *clusterName) override {}
- virtual void popCluster() override {}
- virtual bool allowAccess(const char * category, bool isSigned) override { return true; }
- virtual IHqlExpression *lookupDFSlayout(const char *filename, IErrorReceiver &errs, const ECLlocation &location, bool isOpt) const override { return nullptr; }
- virtual unsigned lookupClusterSize() const override { return 0; }
- virtual void getTargetPlatform(StringBuffer & result) override
- {
- workunit->getDebugValue("targetClusterType", StringBufferAdaptor(result));
- }
- protected:
- Linked<IWorkUnit> workunit;
- };
- class HqlDllGenerator : implements IHqlExprDllGenerator, implements IAbortRequestCallback, public CInterface
- {
- public:
- HqlDllGenerator(IErrorReceiver * _errs, const char * _wuname, const char * _targetdir, IWorkUnit * _wu, const char * _template_dir, ClusterType _targetClusterType, ICodegenContextCallback * _ctxCallback, bool _checkForLocalFileUploads, bool _okToAbort) :
- errs(_errs), wuname(_wuname), targetDir(_targetdir), wu(_wu), template_dir(_template_dir), targetClusterType(_targetClusterType), ctxCallback(_ctxCallback), checkForLocalFileUploads(_checkForLocalFileUploads), okToAbort(_okToAbort)
- {
- if (!ctxCallback)
- ctxCallback.setown(new NullContextCallback(_wu));
- noOutput = true;
- defaultMaxCompileThreads = 1;
- generateTarget = EclGenerateNone;
- code.setown(createCppInstance(wu, wuname));
- deleteGenerated = false;
- totalGeneratedSize = 0;
- }
- IMPLEMENT_IINTERFACE
- virtual void addLibrary(const char * name);
- virtual bool processQuery(OwnedHqlExpr & parsedQuery, EclGenerateTarget _generateTarget);
- virtual bool generateDll(ICppCompiler * compiler);
- virtual bool generateExe(ICppCompiler * compiler);
- virtual bool generatePackage(const char * packageName);
- virtual void setMaxCompileThreads(unsigned value) { defaultMaxCompileThreads = value; }
- virtual void addManifest(const char *filename) { code->addManifest(filename); }
- virtual void addManifestFromArchive(IPropertyTree *archive) { code->addManifestFromArchive(archive); }
- virtual void addWebServiceInfo(IPropertyTree *wsinfo){ code->addWebServiceInfo(wsinfo); }
- virtual double getECLcomplexity(IHqlExpression * exprs);
- virtual void setSaveGeneratedFiles(bool value) { deleteGenerated = !value; }
- protected:
- void addCppName(const char * filename, unsigned minActivity, unsigned maxActivity);
- void addLibrariesToCompiler();
- void addWorkUnitAsResource();
- void calculateHash(IHqlExpression * expr);
- bool doCompile(ICppCompiler * compiler);
- void doExpand(HqlCppTranslator & translator);
- void expandCode(StringBuffer & filename, const char * templateName, bool isHeader, IHqlCppInstance * code, bool multiFile, unsigned pass, CompilerType compiler);
- void flushResources();
- bool generateCode(HqlQueryContext & query);
- bool generateFullFieldUsageStatistics(HqlCppTranslator & translator, IHqlExpression * query);
- IPropertyTree * generateSingleFieldUsageStatistics(IHqlExpression * expr, const char * variety, const IPropertyTree * exclude);
- offset_t getGeneratedSize() const;
- void insertStandAloneCode();
- void setWuState(bool ok);
- inline bool abortRequested();
- protected:
- Linked<IErrorReceiver> errs;
- const char * wuname;
- StringAttr targetDir;
- Linked<IWorkUnit> wu;
- Owned<IHqlCppInstance> code;
- const char * template_dir;
- ClusterType targetClusterType;
- Linked<ICodegenContextCallback> ctxCallback;
- unsigned defaultMaxCompileThreads;
- StringArray sourceFiles;
- StringArray libraries;
- StringArray objects;
- offset_t totalGeneratedSize;
- bool checkForLocalFileUploads;
- bool noOutput;
- EclGenerateTarget generateTarget;
- bool deleteGenerated;
- bool okToAbort;
- };
- //---------------------------------------------------------------------------
- static void processMetaCommands(HqlCppTranslator & translator, IWorkUnit * wu, HqlQueryContext & query, ICodegenContextCallback *ctxCallback);
- void HqlDllGenerator::addCppName(const char * filename, unsigned minActivity, unsigned maxActivity)
- {
- if (wu)
- {
- Owned<IWUQuery> query = wu->updateQuery();
- associateLocalFile(query, FileTypeCpp, filename, pathTail(filename), 0, minActivity, maxActivity);
- }
- }
- void HqlDllGenerator::addLibrary(const char * name)
- {
- libraries.append(name);
- }
- void HqlDllGenerator::addLibrariesToCompiler()
- {
- unsigned idx=0;
- for (;;)
- {
- const char * lib = code->queryLibrary(idx);
- if (!lib)
- break;
- PrintLog("Adding library: %s", lib);
- addLibrary(lib);
- idx++;
- }
- idx=0;
- for (;;)
- {
- const char * obj = code->queryObjectFile(idx);
- if (!obj)
- break;
- PrintLog("Adding object file: %s", obj);
- objects.append(obj);
- idx++;
- }
- idx=0;
- for (;;)
- {
- const char * src = code->querySourceFile(idx);
- if (!src)
- break;
- PrintLog("Adding source file: %s", src);
- sourceFiles.append(src);
- idx++;
- }
- }
- void HqlDllGenerator::expandCode(StringBuffer & filename, const char * templateName, bool isHeader, IHqlCppInstance * code, bool multiFile, unsigned pass, CompilerType compiler)
- {
- filename.clear().append(wuname);
- if (pass != 0)
- filename.append("_").append(pass);
- const char * ext = isHeader ? ".hpp" : ".cpp";
- filename.append(ext);
- StringBuffer fullname;
- addDirectoryPrefix(fullname, targetDir).append(filename);
- Owned<IFile> out = createIFile(fullname.str());
- Owned<ITemplateExpander> expander = createTemplateExpander(out, templateName, template_dir);
- if (!expander)
- throwError2(HQLERR_CouldNotOpenTemplateXatY, templateName, template_dir ? template_dir : ".");
- Owned<ISectionWriter> writer = createCppWriter(*code, compiler);
- Owned<IProperties> props = createProperties(true);
- if (multiFile)
- {
- props->setProp("multiFile", true);
- props->setProp("pass", pass);
- }
- StringBuffer headerName;
- headerName.append(wuname).append(".hpp");
- props->setProp("headerName", headerName.str());
- props->setProp("outputName", fullname.str());
- expander->generate(*writer, pass, props);
- totalGeneratedSize += out->size();
- if (!deleteGenerated)
- {
- unsigned minActivity, maxActivity;
- code->getActivityRange(pass, minActivity, maxActivity);
- addCppName(fullname, minActivity, maxActivity);
- }
- }
- //---------------------------------------------------------------------------
- bool HqlDllGenerator::processQuery(OwnedHqlExpr & parsedQuery, EclGenerateTarget _generateTarget)
- {
- generateTarget = _generateTarget;
- assertex(wu->getHash());
- unsigned prevCount = errs->errCount();
- HqlQueryContext query;
- query.expr.setown(parsedQuery.getClear());
- bool ok = generateCode(query);
- code->flushHints();
- wu->commit();
- if (!ok)
- return false;
- if (errs->errCount() != prevCount)
- return false;
- switch (generateTarget)
- {
- case EclGenerateNone:
- case EclGenerateCpp:
- return true;
- }
-
- flushResources();
- addLibrariesToCompiler();
- // Free up memory before the c++ compile occurs
- code.clear();
- return true;
- }
- bool HqlDllGenerator::generateDll(ICppCompiler * compiler)
- {
- if (noOutput || !compiler)
- return true;
- bool ok = doCompile(compiler);
- setWuState(ok);
- return ok;
- }
- bool HqlDllGenerator::generateExe(ICppCompiler * compiler)
- {
- if (noOutput || !compiler)
- return true;
- compiler->setCreateExe(true);
- bool ok = doCompile(compiler);
- setWuState(ok);
- return ok;
- }
- bool HqlDllGenerator::generatePackage(const char * packageName)
- {
- return false;
- }
- static bool isSetMeta(IHqlExpression * expr)
- {
- switch (expr->getOperator())
- {
- case no_compound:
- case no_comma:
- return isSetMeta(expr->queryChild(0)) && isSetMeta(expr->queryChild(1));
- case no_setmeta:
- return true;
- default:
- return false;
- }
- }
- IPropertyTree * HqlDllGenerator::generateSingleFieldUsageStatistics(IHqlExpression * expr, const char * variety, const IPropertyTree * exclude)
- {
- //Generate each into a new workunit
- // Owned<IWorkUnit> localWu = createLocalWorkUnit();
- IWorkUnit * localWu = wu;
- //Generate the code into a new instance each time so it doesn't hang around eating memory
- Owned<IHqlCppInstance> localCode = createCppInstance(localWu, wuname);
- HqlQueryContext query;
- query.expr.set(expr);
- resetUniqueId();
- wu->resetBeforeGeneration();
- HqlCppTranslator translator(errs, wuname, localCode, targetClusterType, ctxCallback);
- try
- {
- translator.buildCpp(*localCode, query);
- return translator.gatherFieldUsage(variety, exclude);
- }
- catch (IException * e)
- {
- if (e->errorCode() != HQLERR_ErrorAlreadyReported)
- {
- unsigned errcode = e->errorCode() ? e->errorCode() : 1;
- StringBuffer s;
- errs->reportError(errcode, e->errorMessage(s).str(), NULL, 0, 0, 1);
- }
- e->Release();
- return NULL;
- }
- catch (RELEASE_CATCH_ALL)
- {
- errs->reportError(99, "Unknown error", NULL, 0, 0, 1);
- return NULL;
- }
- }
- bool HqlDllGenerator::generateFullFieldUsageStatistics(HqlCppTranslator & translator, IHqlExpression* query)
- {
- LinkedHqlExpr savedQuery = query;
- //Strip any #options etc. and check that the query consists of a single OUTPUT() action
- while ((savedQuery->getOperator() == no_compound) && isSetMeta(savedQuery->queryChild(0)))
- savedQuery.set(savedQuery->queryChild(1));
- if (savedQuery->getOperator() != no_output)
- throw MakeStringException(0, "#option('GenerateFullFieldUsage') requires the query to be a single OUTPUT()");
- Owned<IPropertyTree> allFields = createPTree("usage");
- IHqlExpression * dataset = savedQuery->queryChild(0);
- //First calculate which files are used if no fields are extracted from the output i.e. shared by all output fields
- //Use COUNT(dataset) as the query to test that
- OwnedHqlExpr countDataset = createValue(no_count, makeIntType(8, false), LINK(dataset));
- Owned<IPropertyTree> countFilesUsed = generateSingleFieldUsageStatistics(countDataset, "__shared__", NULL);
- if (countFilesUsed)
- allFields->addPropTree(countFilesUsed->queryName(), LINK(countFilesUsed));
- //Now project the output dataset down to a single field, and generate the file/field dependencies for each of those
- OwnedHqlExpr selSeq = createUniqueSelectorSequence();
- OwnedHqlExpr left = createSelector(no_left, dataset, selSeq);
- RecordSelectIterator iter(dataset->queryRecord(), left);
- ForEach(iter)
- {
- IHqlExpression * cur = iter.query();
- IHqlExpression * field = cur->queryChild(1);
- OwnedHqlExpr record = createRecord(field);
- OwnedHqlExpr self = getSelf(record);
- OwnedHqlExpr assign = createAssign(createSelectExpr(LINK(self), LINK(field)), LINK(cur));
- OwnedHqlExpr transform = createValue(no_transform, makeTransformType(record->getType()), LINK(assign), NULL);
- HqlExprArray args;
- args.append(*LINK(dataset));
- args.append(*LINK(transform));
- args.append(*LINK(selSeq));
- OwnedHqlExpr project = createDataset(no_hqlproject,args);
- OwnedHqlExpr projectedOutput = replaceChildDataset(savedQuery, project, 0);
- StringBuffer variety;
- getExprIdentifier(variety, cur);
- //Generate each into a new property tree, and only include fields not shared by all other output fields.
- Owned<IPropertyTree> filesUsed = generateSingleFieldUsageStatistics(projectedOutput, variety.str(), countFilesUsed);
- if (filesUsed)
- allFields->addPropTree(filesUsed->queryName(), LINK(filesUsed));
- //Generate progress so far
- translator.writeFieldUsage(targetDir, allFields, NULL);
- }
- translator.writeFieldUsage(targetDir, allFields, NULL);
- return false;
- }
- bool HqlDllGenerator::generateCode(HqlQueryContext & query)
- {
- noOutput = true;
- {
- // ensure warnings/errors are available before we do the processing...
- addTimeStamp(wu, SSTcompilestage, "compile:generate", StWhenStarted);
- wu->commit();
- cycle_t startCycles = get_cycles_now();
- HqlCppTranslator translator(errs, wuname, code, targetClusterType, ctxCallback);
- processMetaCommands(translator, wu, query, ctxCallback);
- translator.exportWarningMappings();
- if (wu->getDebugValueBool("generateFullFieldUsage", false))
- {
- //Ensure file information is generated. It only partially works with field information at the moment.
- //(The merging/difference logic would need to improve, but would be relatively simple if it was useful.)
- wu->setDebugValueInt("reportFileUsage", 1, true);
- return generateFullFieldUsageStatistics(translator, query.expr);
- }
- bool ok = false;
- try
- {
- if (!translator.buildCpp(*code, query))
- {
- wu->setState(WUStateCompleted);
- return true;
- }
- translator.generateStatistics(targetDir, NULL);
- translator.finalizeResources();
- translator.expandFunctions(true);
- }
- catch (IError * e)
- {
- if (e->errorCode() != HQLERR_ErrorAlreadyReported)
- {
- StringBuffer s;
- errs->reportError(e->errorCode(), e->errorMessage(s).str(), e->getFilename(), e->getLine(), e->getColumn(), e->getPosition());
- }
- e->Release();
- return false;
- }
- catch (IException * e)
- {
- if (e->errorCode() != HQLERR_ErrorAlreadyReported)
- {
- unsigned errcode = e->errorCode() ? e->errorCode() : 1;
- StringBuffer s;
- errs->reportError(errcode, e->errorMessage(s).str(), NULL, 0, 0, 1);
- }
- e->Release();
- return false;
- }
- catch (RELEASE_CATCH_ALL)
- {
- errs->reportError(99, "Unknown error", NULL, 0, 0, 1);
- return false;
- }
- if (generateTarget == EclGenerateExe)
- insertStandAloneCode();
- wu->commit();
-
- //Commit work unit so can view graphs etc. while compiling the C++
- if ((generateTarget == EclGenerateNone) || wu->getDebugValueBool("OnlyCheckQuery", false))
- {
- wu->setState(WUStateCompleted);
- return false;
- }
- if (wu->getDebugValueBool("saveEclTempFiles", false) || wu->getDebugValueBool("saveCppTempFiles", false) || wu->getDebugValueBool("saveCpp", false))
- setSaveGeneratedFiles(true);
- doExpand(translator);
- unsigned __int64 elapsed = cycle_to_nanosec(get_cycles_now() - startCycles);
- updateWorkunitTimeStat(wu, SSTcompilestage, "compile:generate", StTimeElapsed, NULL, elapsed);
- if (wu->getDebugValueBool("addMemoryToWorkunit", true))
- {
- memsize_t peakVm, peakResident;
- getPeakMemUsage(peakVm, peakResident);
- if (peakResident)
- wu->setStatistic(queryStatisticsComponentType(), queryStatisticsComponentName(), SSTcompilestage, "compile", StSizePeakMemory, NULL, peakResident, 1, 0, StatsMergeReplace);
- }
- wu->commit();
- addWorkUnitAsResource();
- }
- noOutput = false;
- return true;
- }
- void HqlDllGenerator::addWorkUnitAsResource()
- {
- StringBuffer wuXML;
- exportWorkUnitToXML(wu, wuXML, false, false, false);
- code->addCompressResource("WORKUNIT", wuXML.length(), wuXML.str(), NULL, 1000);
- }
- void HqlDllGenerator::insertStandAloneCode()
- {
- BuildCtx ctx(static_cast<HqlCppInstance &>(*code), goAtom);
- ctx.addQuotedFunction("int main(int argc, const char *argv[])");
- ctx.addQuotedLiteral("return start_query(argc, argv);\n");
- }
- void HqlDllGenerator::doExpand(HqlCppTranslator & translator)
- {
- CCycleTimer elapsedTimer;
- addTimeStamp(wu, SSTcompilestage, "compile:write c++", StWhenStarted);
- unsigned numExtraFiles = translator.getNumExtraCppFiles();
- bool isMultiFile = translator.spanMultipleCppFiles();
- CompilerType targetCompiler = translator.queryOptions().targetCompiler;
- StringBuffer fullname;
- expandCode(fullname, MAIN_MODULE_TEMPLATE, false, code, isMultiFile, 0, targetCompiler);
- sourceFiles.append(fullname);
- if (isMultiFile)
- {
- expandCode(fullname, HEADER_TEMPLATE, true, code, true, 0, targetCompiler);
- for (unsigned i= 0; i < translator.getNumExtraCppFiles(); i++)
- {
- expandCode(fullname, CHILD_MODULE_TEMPLATE, false, code, true, i+1, targetCompiler);
- sourceFiles.append(fullname);
- }
- }
- updateWorkunitTimeStat(wu, SSTcompilestage, "compile:write c++", StTimeElapsed, NULL, elapsedTimer.elapsedNs());
- }
- bool HqlDllGenerator::abortRequested()
- {
- return (wu && wu->aborting());
- }
- bool HqlDllGenerator::doCompile(ICppCompiler * compiler)
- {
- cycle_t startCycles = get_cycles_now();
- addTimeStamp(wu, SSTcompilestage, "compile:compile c++", StWhenStarted);
- ForEachItemIn(i, sourceFiles)
- compiler->addSourceFile(sourceFiles.item(i));
- unsigned maxThreads = wu->getDebugValueInt("maxCompileThreads", defaultMaxCompileThreads);
- compiler->setMaxCompileThreads(maxThreads);
- bool debug = wu->getDebugValueBool("debugQuery", false);
- bool debugLibrary = debug; // should be wu->getDebugValueBool("debugLibrary", IS_DEBUG_BUILD); change for 3.8
- compiler->setDebug(debug);
- compiler->setDebugLibrary(debugLibrary);
- if (!debug)
- {
- int optimizeLevel = wu->getDebugValueInt("optimizeLevel", targetClusterType == RoxieCluster ? 3 : -1);
- if (optimizeLevel != -1)
- compiler->setOptimizeLevel(optimizeLevel);
- }
- #ifdef __64BIT__
- // ARMFIX: Map all the uses of this property and make sure
- // they're not used to mean x86_64 (it shouldn't, though)
- bool target64bit = wu->getDebugValueBool("target64bit", true);
- #else
- bool target64bit = wu->getDebugValueBool("target64bit", false);
- #endif
- compiler->setTargetBitLength(target64bit ? 64 : 32);
- ForEachItemIn(idx, libraries)
- compiler->addLibrary(libraries.item(idx));
- ForEachItemIn(idx2, objects)
- compiler->addObjectFile(objects.item(idx2));
- StringBuffer options;
- StringBufferAdaptor linkOptionAdaptor(options);
- wu->getDebugValue("linkOptions", linkOptionAdaptor);
- compiler->addLinkOption(options.str());
- options.clear();
- StringBufferAdaptor optionAdaptor(options);
- wu->getDebugValue("compileOptions", optionAdaptor);
- compiler->addCompileOption(options.str());
- if (okToAbort)
- compiler->setAbortChecker(this);
- PrintLog("Compiling %s", wuname);
- bool ok = compiler->compile();
- if(ok)
- PrintLog("Compiled %s", wuname);
- else
- PrintLog("Failed to compile %s", wuname);
- bool reportCppWarnings = wu->getDebugValueBool("reportCppWarnings", false);
- IArrayOf<IError> errors;
- compiler->extractErrors(errors);
- ForEachItemIn(iErr, errors)
- {
- IError & cur = errors.item(iErr);
- if (isError(&cur) || reportCppWarnings)
- errs->report(&cur);
- }
- unsigned __int64 elapsed = cycle_to_nanosec(get_cycles_now() - startCycles);
- updateWorkunitTimeStat(wu, SSTcompilestage, "compile:compile c++", StTimeElapsed, NULL, elapsed);
- //Keep the files if there was a compile error.
- if (ok && deleteGenerated)
- {
- StringBuffer temp;
- removeFileTraceIfFail(temp.clear().append(wuname).append(".hpp").str());
- ForEachItemIn(i, sourceFiles)
- {
- removeFileTraceIfFail(sourceFiles.item(i));
- }
- }
- return ok;
- }
- void HqlDllGenerator::flushResources()
- {
- if (code)
- code->flushResources(wuname, ctxCallback);
- }
- void HqlDllGenerator::setWuState(bool ok)
- {
- if(ok)
- {
- if(checkForLocalFileUploads && wu->requiresLocalFileUpload())
- wu->setState(WUStateUploadingFiles);
- else
- wu->setState(WUStateCompiled);
- }
- else
- wu->setState(WUStateFailed);
- }
- double HqlDllGenerator::getECLcomplexity(IHqlExpression * exprs)
- {
- Owned<IHqlCppInstance> code = createCppInstance(wu, NULL);
- HqlCppTranslator translator(errs, "temp", code, targetClusterType, NULL);
- HqlQueryContext query;
- query.expr.set(exprs);
- processMetaCommands(translator, wu, query, ctxCallback);
- return translator.getComplexity(*code, query.expr);
- }
- offset_t HqlDllGenerator::getGeneratedSize() const
- {
- return totalGeneratedSize;
- }
- extern HQLCPP_API double getECLcomplexity(IHqlExpression * exprs, IErrorReceiver * errs, IWorkUnit *wu, ClusterType targetClusterType)
- {
- HqlDllGenerator generator(errs, "unknown", NULL, wu, NULL, targetClusterType, NULL, false, false);
- return generator.getECLcomplexity(exprs);
- }
- extern HQLCPP_API IHqlExprDllGenerator * createDllGenerator(IErrorReceiver * errs, const char *wuname, const char * targetdir, IWorkUnit *wu, const char * template_dir, ClusterType targetClusterType, ICodegenContextCallback *ctxCallback, bool checkForLocalFileUploads, bool okToAbort)
- {
- return new HqlDllGenerator(errs, wuname, targetdir, wu, template_dir, targetClusterType, ctxCallback, checkForLocalFileUploads, okToAbort);
- }
- /*
- extern HQLCPP_API void addLibraryReference(IWorkUnit * wu, IHqlLibraryInfo * library, const char * lid)
- {
- StringBuffer libraryName;
- library->getName(libraryName);
- Owned<IWULibrary> entry = wu->updateLibraryByName(libraryName.str());
- entry->setMajorVersion(library->queryMajorVersion());
- entry->setMinorVersion(library->queryMinorVersion());
- entry->setCrc(library->queryInterfaceCrc());
- if (lid && *lid)
- entry->setLID(lid);
- }
- */
- extern HQLCPP_API ClusterType queryClusterType(IConstWorkUnit * wu, ClusterType prevType)
- {
- ClusterType targetClusterType = prevType;
- if (wu->getDebugValueBool("forceRoxie", false))
- targetClusterType = RoxieCluster;
- else if (prevType == NoCluster)
- targetClusterType = ThorLCRCluster;
- SCMStringBuffer targetText;
- wu->getDebugValue("targetClusterType", targetText);
- targetClusterType = getClusterType(targetText.s.str(), targetClusterType);
- if ((targetClusterType != RoxieCluster) && wu->getDebugValueBool("forceFakeThor", false))
- targetClusterType = HThorCluster;
- return targetClusterType;
- }
- static void processMetaCommands(HqlCppTranslator & translator, IWorkUnit * wu, HqlQueryContext & query, ICodegenContextCallback *ctxCallback)
- {
- NewThorStoredReplacer transformer(translator, wu, ctxCallback);
- translator.traceExpression("before process meta commands", query.expr);
- transformer.analyse(query.expr);
- if (transformer.needToTransform())
- query.expr.setown(transformer.transform(query.expr));
- }
- extern HQLCPP_API unsigned getLibraryCRC(IHqlExpression * library)
- {
- assertex(library->getOperator() == no_funcdef);
- return getExpressionCRC(library->queryChild(0));
- }
- void setWorkunitHash(IWorkUnit * wu, IHqlExpression * expr)
- {
- //Assuming builds come from different branches this will change the crc for each one.
- unsigned cacheCRC = crc32(BUILD_TAG, strlen(BUILD_TAG), ACTIVITY_INTERFACE_VERSION);
- cacheCRC += getExpressionCRC(expr);
- #ifdef _WIN32
- cacheCRC++; // make sure CRC is different in windows/linux
- #endif
- // make sure CRC is different for different host platform
- // shouldn't really matter if cross-compiling working properly,
- // but fairly harmless.
- #ifdef _ARCH_X86_
- cacheCRC += 1;
- #endif
- #ifdef _ARCH_X86_64_
- cacheCRC += 2;
- #endif
- // In theory, ARM and x86 workunits should be totally different, but...
- #ifdef _ARCH_ARM32_
- cacheCRC += 3;
- #endif
- #ifdef _ARCH_ARM64_
- cacheCRC += 4;
- #endif
- IExtendedWUInterface *ewu = queryExtendedWU(wu);
- cacheCRC = ewu->calculateHash(cacheCRC);
- wu->setHash(cacheCRC);
- }
|