Skip to content

Commit

Permalink
Fix gh-1426 Implement -Wl, and related changes
Browse files Browse the repository at this point in the history
* -Wl was passed to the compiler instead of the linker.
* Any linker options set before setExe()/setDebug() were called were
  ignored.
* #option action was ignored in a beginc++ (bugzilla bug #84603)
* #option wasn't stripped from beginc++ that wasn't defined as a
  function (not very usual).
* Added #option library 'mylib' within a beginc++ to add a library to
  the list passed to the linker.

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
  • Loading branch information
ghalliday committed Feb 3, 2012
1 parent 45d6582 commit 540e4c5
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 52 deletions.
14 changes: 12 additions & 2 deletions ecl/eclcc/eclcc.cpp
Expand Up @@ -244,6 +244,7 @@ class EclCC
IFileArray inputFiles;
StringArray debugOptions;
StringArray compileOptions;
StringArray linkOptions;
StringArray libraryPaths;

ClusterType optTargetClusterType;
Expand Down Expand Up @@ -438,6 +439,9 @@ ICppCompiler * EclCC::createCompiler(const char * coreName)
ForEachItemIn(iComp, compileOptions)
compiler->addCompileOption(compileOptions.item(iComp));

ForEachItemIn(iLink, linkOptions)
compiler->addLinkOption(linkOptions.item(iLink));

ForEachItemIn(iLib, libraryPaths)
compiler->addLibraryPath(libraryPaths.item(iLib));

Expand Down Expand Up @@ -1357,9 +1361,14 @@ bool EclCC::parseCommandLineOptions(int argc, const char* argv[])
{
expandCommaList(compileOptions, arg+4);
}
else if (startsWith(arg, "-Wl,") || startsWith(arg, "-Wp,") || startsWith(arg, "-Wa,"))
else if (startsWith(arg, "-Wl,"))
{
//Pass these straight through to the linker - with -Wl, prefix removed
linkOptions.append(arg+4);
}
else if (startsWith(arg, "-Wp,") || startsWith(arg, "-Wa,"))
{
//Pass these straigh through to the gcc compiler
//Pass these straight through to the gcc compiler
compileOptions.append(arg);
}
else if (iter.matchFlag(optWorkUnit, "-wu"))
Expand Down Expand Up @@ -1417,6 +1426,7 @@ void EclCC::usage()
" executable, or stdout)\n"
" -P <path> Specify the path of the output files\n"
" -Wc,xx Supply option for the c++ compiler\n"
" -Wl,xx Supply option for the linker\n"
" -save-cpps Do not delete generated c++ files (implied if -g)\n"
" -save-temps Do not delete intermediate files\n"
" -manifest Specify path to manifest file listing resources to add\n"
Expand Down
17 changes: 16 additions & 1 deletion ecl/hql/hqlexpr.cpp
Expand Up @@ -3416,8 +3416,17 @@ void CHqlExpression::updateFlagsAfterOperands()
case no_call:
{
IHqlExpression * funcdef = queryBody()->queryFunctionDefinition();
if (funcdef->getOperator() == no_funcdef && funcdef->queryChild(0)->getOperator() == no_outofline)
IHqlExpression * body = funcdef->queryChild(0);
if ((funcdef->getOperator() == no_funcdef) && (body->getOperator() == no_outofline))
{
infoFlags2 |= HEF2containsCall;
IHqlExpression * bodycode = body->queryChild(0);
if (bodycode->getOperator() == no_cppbody)
{
if (bodycode->queryProperty(actionAtom))
infoFlags |= HEFvolatile;
}
}
else
infoFlags2 |= (HEF2containsCall|HEF2containsDelayedCall);
break;
Expand All @@ -3429,6 +3438,12 @@ void CHqlExpression::updateFlagsAfterOperands()
infoFlags |= HEFvolatile;
break;
}
case no_cppbody:
{
if (queryProperty(actionAtom))
infoFlags |= HEFvolatile;
break;
}
}

#ifdef VERIFY_EXPR_INTEGRITY
Expand Down
5 changes: 3 additions & 2 deletions ecl/hql/hqlgram2.cpp
Expand Up @@ -838,7 +838,8 @@ IHqlExpression * HqlGram::convertToOutOfLineFunction(const ECLlocation & errpos,
IHqlExpression * HqlGram::processCppBody(const attribute & errpos, IHqlExpression * cpp)
{
HqlExprArray args;
args.append(*LINK(cpp));
cpp->unwindList(args, no_comma);

Linked<ITypeInfo> type = current_type;
if (!type)
type.setown(makeVoidType());
Expand All @@ -847,7 +848,7 @@ IHqlExpression * HqlGram::processCppBody(const attribute & errpos, IHqlExpressio
OwnedHqlExpr result;
if (record)
{
args.append(*LINK(record));
args.add(*LINK(record),1);
if (hasLinkCountedModifier(type))
args.append(*getLinkCountedAttr());
if (hasStreamedModifier(type))
Expand Down
4 changes: 3 additions & 1 deletion ecl/hql/hqllex.l
Expand Up @@ -1478,7 +1478,9 @@ FUNCTIONMACRO|MACRO {
lexer->yyPosition -= delta;
lexer->yyColumn -= delta;
OwnedHqlExpr cppText = createConstant(createStringValue(lexer->yyBuffer+startpos, len));
returnToken.setExpr(createLocationAnnotation(cppText.getClear(), returnToken.pos));
OwnedHqlExpr annotated = createLocationAnnotation(cppText.getClear(), returnToken.pos);
OwnedHqlExpr options = extractCppBodyAttrs(len, lexer->yyBuffer+startpos);
returnToken.setExpr(createComma(annotated.getClear(), options.getClear()));
return CPPBODY;
}
<CPP>[^\n]+ { updatepos1; }
Expand Down
74 changes: 63 additions & 11 deletions ecl/hql/hqlutil.cpp
Expand Up @@ -4767,13 +4767,53 @@ bool isConstantDataset(IHqlExpression * expr)

inline bool iseol(char c) { return c == '\r' || c == '\n'; }

#define MATCHOPTION(len, text) (((end - start) == len) && (memicmp(buffer+start, text, len) == 0))
static unsigned skipSpace(unsigned start, unsigned len, const char * buffer)
{
while (start < len && isspace((byte)buffer[start]))
start++;
return start;
}

static unsigned trimSpace(unsigned len, const char * buffer)
{
while (len && isspace((byte)buffer[len-1]))
len--;
return len;
}

IHqlExpression * extractCppBodyAttrs(unsigned len, const char * buffer)
static void stripQuotes(unsigned & start, unsigned & end, const char * buffer)
{
if (end - start >= 2)
{
if (buffer[start] == '\'' && buffer[end-1] == '\'')
{
start++;
end--;
}
}
}

static bool matchOption(unsigned & cur, unsigned max, const char * buffer, unsigned lenMatch, const char * match)
{
if (cur + lenMatch > max)
return false;
if (memicmp(buffer+cur, match, lenMatch) != 0)
return false;
if (cur + lenMatch < max)
{
if (isalnum(buffer[cur+lenMatch]))
return false;
}
cur = skipSpace(cur+lenMatch, max, buffer);
return true;
}


IHqlExpression * extractCppBodyAttrs(unsigned lenBuffer, const char * buffer)
{
OwnedHqlExpr attrs;
unsigned prev = '\n';
for (unsigned i=0; i < len; i++)
for (unsigned i=0; i < lenBuffer; i++)
{
char next = buffer[i];
switch (next)
Expand All @@ -4784,20 +4824,32 @@ IHqlExpression * extractCppBodyAttrs(unsigned len, const char * buffer)
case '#':
if (prev == '\n')
{
if ((i + 1 + 6 < len) && memicmp(buffer+i+1, "option", 6) == 0)
if ((i + 1 + 6 < lenBuffer) && memicmp(buffer+i+1, "option", 6) == 0)
{
unsigned start = i+1+6;
while (start < len && isspace((byte)buffer[start]))
start++;
unsigned start = skipSpace(i+1+6, lenBuffer, buffer);
unsigned end = start;
while (end < len && !iseol((byte)buffer[end]))
while (end < lenBuffer && !iseol((byte)buffer[end]))
end++;
if (MATCHOPTION(4, "pure"))
end = trimSpace(end, buffer);
if (matchOption(start, lenBuffer, buffer, 4, "pure"))
attrs.setown(createComma(attrs.getClear(), createAttribute(pureAtom)));
else if (MATCHOPTION(4, "once"))
else if (matchOption(start, lenBuffer, buffer, 4, "once"))
attrs.setown(createComma(attrs.getClear(), createAttribute(onceAtom)));
else if (MATCHOPTION(6, "action"))
else if (matchOption(start, lenBuffer, buffer, 6, "action"))
attrs.setown(createComma(attrs.getClear(), createAttribute(actionAtom)));
else if (matchOption(start, lenBuffer, buffer, 7, "library"))
{
stripQuotes(start, end, buffer);
Owned<IValue> restOfLine = createUtf8Value(end-start, buffer+start, makeUtf8Type(UNKNOWN_LENGTH, NULL));
OwnedHqlExpr arg = createConstant(restOfLine.getClear());
attrs.setown(createComma(attrs.getClear(), createAttribute(libraryAtom, arg.getClear())));
}
else if (matchOption(start, lenBuffer, buffer, 4, "link"))
{
Owned<IValue> restOfLine = createUtf8Value(end-start, buffer+start, makeUtf8Type(UNKNOWN_LENGTH, NULL));
OwnedHqlExpr arg = createConstant(restOfLine.getClear());
attrs.setown(createComma(attrs.getClear(), createAttribute(linkAtom, arg.getClear())));
}
}
}
//fallthrough
Expand Down
27 changes: 26 additions & 1 deletion ecl/hqlcpp/hqlcpp.cpp
Expand Up @@ -7115,13 +7115,37 @@ void HqlCppTranslator::doBuildAssignToXml(BuildCtx & ctx, const CHqlBoundTarget

//---------------------------------------------------------------------------

void HqlCppTranslator::processCppBodyDirectives(IHqlExpression * expr)
{
ForEachChild(i, expr)
{
IHqlExpression * cur = expr->queryChild(i);
if (cur->isAttribute())
{
_ATOM name = cur->queryName();
if (name == linkAtom)
{
}
else if (name == libraryAtom)
{
StringBuffer libraryName;
getStringValue(libraryName, cur->queryChild(0));
if (libraryName.length())
useLibrary(libraryName.str());
}
}
}
}

void HqlCppTranslator::doBuildExprCppBody(BuildCtx & ctx, IHqlExpression * expr, CHqlBoundExpr * tgt)
{
if (!allowEmbeddedCpp())
throwError(HQLERR_EmbeddedCppNotAllowed);

processCppBodyDirectives(expr);
StringBuffer text;
expr->queryChild(0)->queryValue()->getStringValue(text);
text.setLength(cleanupEmbeddedCpp(text.length(), (char*)text.str()));
OwnedHqlExpr quoted = createQuoted(text.str(), expr->getType());

if (tgt)
Expand Down Expand Up @@ -11237,6 +11261,7 @@ void HqlCppTranslator::buildFunctionDefinition(IHqlExpression * funcdef)
if (!allowEmbeddedCpp())
throwError(HQLERR_EmbeddedCppNotAllowed);

processCppBodyDirectives(bodyCode);
IHqlExpression * location = queryLocation(bodyCode);
const char * locationFilename = location ? location->querySourcePath()->str() : NULL;
unsigned startLine = location ? location->getStartLine() : 0;
Expand All @@ -11246,7 +11271,7 @@ void HqlCppTranslator::buildFunctionDefinition(IHqlExpression * funcdef)

StringBuffer text;
cppBody->queryValue()->getStringValue(text);
//remove /r so we don't end up with mixed format end of lines.
//remove #option and /r so we don't end up with mixed format end of lines.
text.setLength(cleanupEmbeddedCpp(text.length(), (char*)text.str()));

const char * start = text.str();
Expand Down
1 change: 1 addition & 0 deletions ecl/hqlcpp/hqlcpp.ipp
Expand Up @@ -1748,6 +1748,7 @@ protected:
IHqlExpression * spotGlobalCSE(IHqlExpression * _expr);
void spotGlobalCSE(HqlExprArray & exprs);
IHqlExpression * extractGlobalCSE(IHqlExpression * expr);
void processCppBodyDirectives(IHqlExpression * expr);


void markThorBoundaries(WorkflowArray & array);
Expand Down
9 changes: 8 additions & 1 deletion ecl/hqlcpp/hqlecl.cpp
Expand Up @@ -37,6 +37,12 @@
#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"
Expand Down Expand Up @@ -366,8 +372,9 @@ bool HqlDllGenerator::doCompile(ICppCompiler * compiler)
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(debug);
compiler->setDebugLibrary(debugLibrary);
if (!debug)
{
int optimizeLevel = wu->getDebugValueInt("optimizeLevel", targetClusterType == RoxieCluster ? 3 : -1);
Expand Down
40 changes: 40 additions & 0 deletions ecl/regress/cppbody6.ecl
@@ -0,0 +1,40 @@
/*##############################################################################

Copyright (C) 2011 HPCC Systems.

All rights reserved. This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
############################################################################## */



integer4 add1(integer4 x, integer4 y) :=
BEGINC++
return x + y;
ENDC++;

integer4 add2(integer4 x, integer4 y) :=
BEGINC++
#option action
return x + y;
ENDC++;

integer4 add3(integer4 x, integer4 y) :=
BEGINC++
#option pure
return x + y;
ENDC++;

output(add1(10,20) * add1(10,20));
output(add2(10,20) * add2(10,20));
output(add3(10,20) * add3(10,20));
40 changes: 40 additions & 0 deletions ecl/regress/cppbody7.ecl
@@ -0,0 +1,40 @@
/*##############################################################################

Copyright (C) 2011 HPCC Systems.

All rights reserved. This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
############################################################################## */



integer4 mkRandom1 :=
BEGINC++
rtlRandom()
ENDC++;

integer4 mkRandom2 :=
BEGINC++
#option pure
rtlRandom()
ENDC++;

integer4 mkRandom3 :=
BEGINC++
#option action
rtlRandom()
ENDC++;

output(mkRandom1 * mkRandom1);
output(mkRandom2 * mkRandom2);
output(mkRandom3 * mkRandom3);
27 changes: 27 additions & 0 deletions ecl/regress/cppbody8.ecl
@@ -0,0 +1,27 @@
/*##############################################################################

Copyright (C) 2011 HPCC Systems.

All rights reserved. This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
############################################################################## */



integer4 add1(integer4 x, integer4 y) :=
BEGINC++
#option library 'MySpecialLibrary'
return x + y;
ENDC++;

output(add1(10,20) * add1(10,20));

0 comments on commit 540e4c5

Please sign in to comment.