Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel

Conflicts:
	oroshi/python/CapacitorRoutedSingle.py
        Hidden tabulations remaining
This commit is contained in:
Mariam Tlili 2020-03-06 17:53:01 +01:00
commit e2d6929fbe
1940 changed files with 389242 additions and 76916 deletions

View File

@ -25,7 +25,7 @@ Documentation
The complete documentation is available here, both in pdf & html: The complete documentation is available here, both in pdf & html:
./documentation/_build/html/index.html ./documentation/output/html
./documentation/UsersGuide/UsersGuide.pdf ./documentation/UsersGuide/UsersGuide.pdf
The documentation of the latest *stable* version is also The documentation of the latest *stable* version is also

View File

@ -25,6 +25,7 @@
#include "hurricane/BasicLayer.h" #include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.h" #include "hurricane/RegularLayer.h"
#include "hurricane/RoutingPad.h" #include "hurricane/RoutingPad.h"
#include "hurricane/Pin.h"
#include "hurricane/NetExternalComponents.h" #include "hurricane/NetExternalComponents.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "crlcore/Utilities.h" #include "crlcore/Utilities.h"
@ -55,6 +56,7 @@ namespace Anabatic {
using Hurricane::BasicLayer; using Hurricane::BasicLayer;
using Hurricane::RegularLayer; using Hurricane::RegularLayer;
using Hurricane::Segment; using Hurricane::Segment;
using Hurricane::Pin;
using Hurricane::Plug; using Hurricane::Plug;
using Hurricane::Path; using Hurricane::Path;
using Hurricane::Occurrence; using Hurricane::Occurrence;
@ -458,13 +460,18 @@ namespace Anabatic {
cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl; cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl;
for ( Component* component : masterNet->getComponents() ) { for ( Component* component : masterNet->getComponents() ) {
cdebug_log(112,0) << "@ " << component << endl; cdebug_log(112,0) << "@ " << component << endl;
if (not NetExternalComponents::isExternal(component)) continue; if (not NetExternalComponents::isExternal(component)) {
cdebug_log(112,0) << " Not an external component, skip." << endl;
continue;
}
Segment* segment = dynamic_cast<Segment*>(component); Component* candidate = dynamic_cast<Segment*>(component);
if (not segment) continue; if (not candidate
if (segment->getLayer()->getMask() != metal1->getMask()) continue; or (candidate->getLayer()->getMask() != metal1->getMask()) )
candidate = dynamic_cast<Pin*>(component);
if (not candidate) continue;
Box bb = transformation.getBox( component->getBoundingBox() ); Box bb = transformation.getBox( candidate->getBoundingBox() );
DbU::Unit trackPos = 0; DbU::Unit trackPos = 0;
DbU::Unit minPos = DbU::Max; DbU::Unit minPos = DbU::Max;
DbU::Unit maxPos = DbU::Min; DbU::Unit maxPos = DbU::Min;
@ -497,7 +504,7 @@ namespace Anabatic {
cdebug_log(112,0) << "| " << occurrence.getPath() << endl; cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
cdebug_log(112,0) << "| " << transformation << endl; cdebug_log(112,0) << "| " << transformation << endl;
cdebug_log(112,0) << "| " << bb << " of:" << segment << endl; cdebug_log(112,0) << "| " << bb << " of:" << candidate << endl;
cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl; cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {

View File

@ -401,14 +401,14 @@ namespace Anabatic {
for ( Hook* hook : fromHook->getHooks() ) { for ( Hook* hook : fromHook->getHooks() ) {
cdebug_log(145,0) << "Hook: " << hook << endl; cdebug_log(145,0) << "Hook: " << hook << endl;
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = " cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
<< "[" << (int)_connexity.fields.globals << "[" << (int)_connexity.fields.globals
<< "+" << (int)_connexity.fields.M1 << "+" << (int)_connexity.fields.M1
<< "+" << (int)_connexity.fields.M2 << "+" << (int)_connexity.fields.M2
<< "+" << (int)_connexity.fields.M3 << "+" << (int)_connexity.fields.M3
<< "+" << (int)_connexity.fields.Pin << "+" << (int)_connexity.fields.Pin
<< "+" << (int)_connexity.fields.Pad << "+" << (int)_connexity.fields.Pad
<< "] " << _gcell << "] " << _gcell
<< endl; << endl;
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() ); Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
if (toSegment) { if (toSegment) {
@ -507,6 +507,16 @@ namespace Anabatic {
if (_gcell == NULL) throw Error( missingGCell ); if (_gcell == NULL) throw Error( missingGCell );
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
<< "[" << (int)_connexity.fields.globals
<< "+" << (int)_connexity.fields.M1
<< "+" << (int)_connexity.fields.M2
<< "+" << (int)_connexity.fields.M3
<< "+" << (int)_connexity.fields.Pin
<< "+" << (int)_connexity.fields.Pad
<< "] " << _gcell
<< endl;
return *this; return *this;
} }
@ -543,6 +553,15 @@ namespace Anabatic {
void NetBuilder::construct () void NetBuilder::construct ()
{ {
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl; cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
<< "[" << (int)_connexity.fields.globals
<< "+" << (int)_connexity.fields.M1
<< "+" << (int)_connexity.fields.M2
<< "+" << (int)_connexity.fields.M3
<< "+" << (int)_connexity.fields.Pin
<< "+" << (int)_connexity.fields.Pad
<< "] " << _gcell
<< endl;
if (not isTwoMetals()) { if (not isTwoMetals()) {
_southWestContact = NULL; _southWestContact = NULL;
@ -586,6 +605,7 @@ namespace Anabatic {
case Conn_3G_2M1: case Conn_3G_2M1:
case Conn_3G_3M1: case Conn_3G_3M1:
case Conn_3G_4M1: case Conn_3G_4M1:
case Conn_3G_5M1:
case Conn_3G_2M3: case Conn_3G_2M3:
case Conn_3G_3M3: case Conn_3G_3M3:
case Conn_3G_4M3: case Conn_3G_4M3:
@ -616,17 +636,22 @@ namespace Anabatic {
case Conn_4G: _do_xG(); break; case Conn_4G: _do_xG(); break;
// End xG cascaded cases. // End xG cascaded cases.
// Optimized specific cases. // Optimized specific cases.
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break; case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break; case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break; case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
case Conn_2G_1PinM2: case Conn_2G_1PinM2:
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break; case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break; case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
case Conn_2G_1PinM3: case Conn_2G_1PinM3:
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break; case Conn_3G_1PinM3: _do_xG_1PinM3 (); break;
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break; case Conn_1G_1M1_1PinM3: _do_1G_1M1_1PinM3(); break;
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; case Conn_1G_1M1_1PinM2:
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break; case Conn_1G_2M1_1PinM2: _do_1G_xM1_1PinM2(); break;
case Conn_2G_1M1_1PinM2:
case Conn_2G_2M1_1PinM2: _do_2G_xM1_1PinM2(); break;
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2 (); break;
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
default: default:
if (not isTwoMetals()) if (not isTwoMetals())
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
@ -1069,6 +1094,27 @@ namespace Anabatic {
} }
bool NetBuilder::_do_1G_1M1_1PinM3 ()
{
throw Error ( "%s::_do_1G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_1G_xM1_1PinM2 ()
{
throw Error ( "%s::_do_1G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_2G_xM1_1PinM2 ()
{
throw Error ( "%s::_do_2G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_globalSegment () bool NetBuilder::_do_globalSegment ()
{ {
throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() ); throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() );

View File

@ -251,6 +251,45 @@ namespace Anabatic {
} }
AutoContact* NetBuilderHV::doRp_AccessNorthPin ( GCell* gcell, RoutingPad* rp )
{
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl;
AutoContact* rpSourceContact = NULL;
AutoContact* rpContactTarget = NULL;
AutoContact* turn = NULL;
doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, NoProtect );
Net* net = rp->getNet();
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
Pin::AccessDirection pinDir = pin->getAccessDirection();
if (pinDir == Pin::AccessDirection::NORTH) {
turn = AutoContactTurn::create( gcell, net, Session::getRoutingLayer(1) );
AutoSegment* segment = AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
segment->setAxis( rp->getX(), Flags::Force );
segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
rpSourceContact = turn;
turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(1) );
segment = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
rpSourceContact = turn;
DbU::Unit axis = gcell->getYMax() - Session::getDHorizontalPitch();
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
segment->setAxis( axis, Flags::Force );
//segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
cdebug_log(145,0) << segment << endl;
} else {
turn = rpSourceContact;
}
cdebug_tabw(145,-1);
return turn;
}
bool NetBuilderHV::_do_1G_1M1 () bool NetBuilderHV::_do_1G_1M1 ()
{ {
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
@ -744,9 +783,8 @@ namespace Anabatic {
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl; cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpSourceContact = NULL; AutoContact* rpSourceContact = NULL;
AutoContact* rpContactTarget = NULL;
doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoFlags ); rpSourceContact = doRp_AccessNorthPin( getGCell(), getRoutingPads()[0] );
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, turn1, Flags::Vertical ); AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
@ -804,15 +842,19 @@ namespace Anabatic {
setSouthWestContact( turn1 ); setSouthWestContact( turn1 );
setNorthEastContact( htee1 ); setNorthEastContact( htee1 );
} else { } else if (north() and south()) {
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, vtee1, Flags::Vertical );
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( vtee1, turn1, Flags::Vertical ); AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
setSouthWestContact( vtee1 ); AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
setNorthEastContact( turn1 ); AutoSegment::create( turn1, vtee1, Flags::Horizontal );
setBothCornerContacts( vtee1 );
} else { // Remaining case is East & West.
AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, htee1, Flags::Vertical );
setBothCornerContacts( htee1 );
} }
} else { } else {
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
@ -830,6 +872,144 @@ namespace Anabatic {
} }
bool NetBuilderHV::_do_1G_xM1_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
vector<RoutingPad*> rpsM1;
RoutingPad* pinM2 = NULL;
for ( RoutingPad* rp : getRoutingPads() ) {
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) pinM2 = rp;
else rpsM1.push_back( rp );
}
AutoContact* turn = NULL;
AutoContact* tee = NULL;
AutoContact* pinM2Contact = NULL;
AutoContact* rpM1Contact = NULL;
doRp_AutoContacts( getGCell(), pinM2, pinM2Contact, rpM1Contact, NoProtect );
rpM1Contact = doRp_Access( getGCell(), rpsM1[0], HAccess );
if (north() or south()) {
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpM1Contact , tee , Flags::Horizontal );
AutoSegment::create( pinM2Contact, turn, Flags::Horizontal );
AutoSegment::create( tee , turn, Flags::Vertical );
} else {
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
tee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpM1Contact , turn, Flags::Horizontal );
AutoSegment::create( pinM2Contact, tee , Flags::Horizontal );
AutoSegment::create( tee , turn, Flags::Vertical );
}
setBothCornerContacts( tee );
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHV::_do_2G_xM1_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_2G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
vector<RoutingPad*> rpsM1;
RoutingPad* pinM2 = NULL;
for ( RoutingPad* rp : getRoutingPads() ) {
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) pinM2 = rp;
else rpsM1.push_back( rp );
}
AutoContact* pinM2Contact = NULL;
AutoContact* rpM1Contact = NULL;
doRp_AutoContacts( getGCell(), pinM2, pinM2Contact, rpM1Contact, NoFlags );
rpM1Contact = doRp_Access( getGCell(), rpsM1[0], NoFlags );
if (north() and south()) {
AutoContact* htee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoContact* vtee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinM2Contact, htee, Flags::Horizontal );
AutoSegment::create( rpM1Contact , htee, Flags::Vertical );
AutoSegment::create( htee , vtee, Flags::Horizontal );
setBothCornerContacts( vtee );
} else if (east() and west()) {
AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoContact* htee2 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinM2Contact, htee1, Flags::Horizontal );
AutoSegment::create( rpM1Contact , htee1, Flags::Vertical );
AutoSegment::create( htee1 , turn , Flags::Horizontal );
AutoSegment::create( htee2 , turn , Flags::Vertical );
setBothCornerContacts( htee2 );
} else {
AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoContact* htee2 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinM2Contact, htee1, Flags::Horizontal );
AutoSegment::create( rpM1Contact , htee1, Flags::Vertical );
AutoSegment::create( htee1 , htee2, Flags::Horizontal );
AutoSegment::create( htee2 , turn , Flags::Vertical );
setNorthEastContact( htee2 );
setSouthWestContact( turn );
}
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHV::_do_1G_1M1_1PinM3 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpSourceContact = NULL;
RoutingPad* pinM3 = getRoutingPads()[0];
RoutingPad* rpM1 = getRoutingPads()[1];
if (dynamic_cast<Pin*>(rpM1->getOccurrence().getEntity())) std::swap( rpM1, pinM3 );
AutoContact* contact1 = doRp_Access( getGCell(), rpM1, HAccess );
AutoContact* htee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( contact1, htee, Flags::Horizontal );
rpSourceContact = doRp_AccessNorthPin( getGCell(), pinM3 );
if (north() or south()) {
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
AutoSegment::create( turn , htee, Flags::Horizontal );
} else {
AutoSegment::create( rpSourceContact, htee, Flags::Vertical );
}
setBothCornerContacts( htee );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHV::_do_2G_1M1 () bool NetBuilderHV::_do_2G_1M1 ()
{ {
return _do_xG_1M1(); return _do_xG_1M1();
@ -1349,6 +1529,120 @@ namespace Anabatic {
} }
void NetBuilderHV::singleGCell ( AnabaticEngine* anbt, Net* net )
{
cdebug_log(145,1) << "NetBuilderHV::singleGCell() " << net << endl;
vector<RoutingPad*> rpM1s;
Component* rpM2 = NULL;
RoutingPad* rpPin = NULL;
for ( RoutingPad* rp : net->getRoutingPads() ) {
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) {
rpPin = rp;
continue;
}
if (Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) == 1)
rpM2 = rp;
else
rpM1s.push_back( rp );
}
if ( (rpM1s.size() < 2) and not (rpM2 or rpPin) ) {
cerr << Error( "For %s, less than two Plugs/Pins (%d)."
, getString(net).c_str()
, rpM1s.size() ) << endl;
cdebug_tabw(145,-1);
return;
}
if (rpM1s.empty()) {
cerr << Error( "No METAL1 in Single GCell for Net \"%s\".", getString(net->getName()).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
sortRpByX( rpM1s, NetBuilder::NoFlags ); // increasing X.
GCell* gcell1 = anbt->getGCellUnder( (*rpM1s.begin ())->getCenter() );
GCell* gcell2 = anbt->getGCellUnder( (*rpM1s.rbegin())->getCenter() );
if (not gcell1) {
cerr << Error( "No GCell under %s.", getString(*(rpM1s.begin())).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
if (gcell1 != gcell2) {
cerr << Error( "Not under a single GCell %s.", getString(*(rpM1s.rbegin())).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
cdebug_log(145,0) << "singleGCell " << gcell1 << endl;
AutoContact* turn1 = NULL;
AutoContact* turn2 = NULL;
AutoContact* source = NULL;
AutoContact* target = NULL;
for ( size_t irp=1 ; irp<rpM1s.size() ; ++irp ) {
doRp_AutoContacts( gcell1, rpM1s[irp-1], source, turn1, DoSourceContact );
doRp_AutoContacts( gcell1, rpM1s[irp ], target, turn1, DoSourceContact );
if (source->getUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical))) {
uint64_t flags = checkRoutingPadSize( rpM1s[irp-1] );
if ((flags & VSmall) or Session::getConfiguration()->isVH()) {
if (Session::getConfiguration()->isHV()) {
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
AutoSegment::create( source, turn1, Flags::Horizontal );
source = turn1;
}
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
AutoSegment::create( source, turn1 , Flags::Vertical );
source = turn1;
}
flags = checkRoutingPadSize( rpM1s[irp] );
if ((flags & VSmall) or Session::getConfiguration()->isVH()) {
if (Session::getConfiguration()->isHV()) {
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
AutoSegment::create( target, turn1, Flags::Horizontal );
target = turn1;
}
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
AutoSegment::create( target, turn1 , Flags::Vertical );
target = turn1;
}
AutoSegment::create( source, target, Flags::Horizontal );
} else {
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
turn2 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
AutoSegment::create( source, turn1 , Flags::Horizontal );
AutoSegment::create( turn1 , turn2 , Flags::Vertical );
AutoSegment::create( turn2 , target, Flags::Horizontal );
}
}
if (rpM2) {
doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact );
doRp_AutoContacts( gcell1, rpM2 , target, turn1, DoSourceContact );
turn1 = AutoContactTurn::create( gcell1, rpM2->getNet(), Session::getContactLayer(1) );
AutoSegment::create( source, turn1 , Flags::Horizontal );
AutoSegment::create( turn1 , target, Flags::Vertical );
}
if (rpPin) {
doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact );
target = doRp_AccessNorthPin( gcell1, rpPin );
turn1 = AutoContactTurn::create( gcell1, rpPin->getNet(), Session::getContactLayer(1) );
AutoSegment::create( source, turn1 , Flags::Horizontal );
AutoSegment::create( turn1 , target, Flags::Vertical );
}
cdebug_tabw(145,-1);
}
string NetBuilderHV::getTypeName () const string NetBuilderHV::getTypeName () const
{ return "NetBuilderHV"; } { return "NetBuilderHV"; }

View File

@ -60,6 +60,7 @@ namespace Anabatic {
inline bool isHorizontal () const; inline bool isHorizontal () const;
inline bool hasNet ( const Net* ) const; inline bool hasNet ( const Net* ) const;
inline unsigned int getCapacity () const; inline unsigned int getCapacity () const;
inline unsigned int getRawCapacity () const;
inline unsigned int getReservedCapacity () const; inline unsigned int getReservedCapacity () const;
inline unsigned int getCapacity ( size_t depth ) const; inline unsigned int getCapacity ( size_t depth ) const;
inline unsigned int getRealOccupancy () const; inline unsigned int getRealOccupancy () const;
@ -137,6 +138,7 @@ namespace Anabatic {
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); }
inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; } inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; }
inline unsigned int Edge::getRawCapacity () const { return (_capacities) ? _capacities->getCapacity() : 0; }
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; } inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
inline float Edge::getEstimateOccupancy () const { return _estimateOccupancy; } inline float Edge::getEstimateOccupancy () const { return _estimateOccupancy; }

View File

@ -221,6 +221,9 @@ namespace Anabatic {
virtual bool _do_xG_xM2 (); virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 (); virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 (); virtual bool _do_xG_xM3 ();
virtual bool _do_1G_xM1_1PinM2 ();
virtual bool _do_2G_xM1_1PinM2 ();
virtual bool _do_1G_1M1_1PinM3 ();
virtual bool _do_globalSegment (); virtual bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* ); virtual void singleGCell ( AnabaticEngine*, Net* );
AutoContact* _doHChannel (); AutoContact* _doHChannel ();
@ -242,73 +245,79 @@ namespace Anabatic {
+ ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \ + ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \
+ ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize)) + ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize))
// Connexity Name | G|M1|M2|M3|Pad|Pin| // Connexity Name | G|M1|M2|M3|Pad|Pin|
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 ) enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
, Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 ) , Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 )
, Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 ) , Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 )
, Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 ) , Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 )
, Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 ) , Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 )
, Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 ) , Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 )
, Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 ) , Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 )
, Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 ) , Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 )
, Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 ) , Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 )
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 ) , Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 )
, Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 ) , Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
, Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 ) , Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 )
, Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 ) , Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 ) , Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 )
, Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 ) , Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
, Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 ) , Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 )
, Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 ) , Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 )
, Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 ) , Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 )
, Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 ) , Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 )
, Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 ) , Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 )
, Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 ) , Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 )
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 ) , Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin| // Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 ) , Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
, Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 ) , Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 )
, Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 ) , Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 ) , Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 )
, Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 ) , Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 )
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 ) , Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 )
, Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 ) , Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 ) , Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 )
, Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 ) , Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 )
, Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 ) , Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 )
, Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 ) , Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 )
, Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 ) , Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 )
, Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 ) , Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 )
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 ) , Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin| // Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 ) , Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 ) , Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 )
, Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 ) , Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 ) , Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 )
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 ) , Conn_3G_5M1 = CONNEXITY_VALUE( 3, 5, 0, 0, 0 , 0 )
, Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 ) , Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 )
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 ) , Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 )
, Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 ) , Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 )
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 ) , Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 )
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 ) , Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin| , Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 ) // Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 ) , Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
, Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 ) , Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 )
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 ) , Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
, Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 ) , Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 )
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 ) , Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 )
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 ) , Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 )
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 ) , Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 ) , Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 ) , Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
, Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 ) , Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 ) , Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 )
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 ) , Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 ) , Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
, Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 ) , Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 ) , Conn_1G_1M1_1PinM2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 1 )
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 ) , Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 )
, Conn_2G_1M1_1PinM2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 1 )
, Conn_2G_2M1_1PinM2 = CONNEXITY_VALUE( 2, 2, 1, 0, 0 , 1 )
, Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 )
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 )
, Conn_1G_1M1_1PinM3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 1 )
}; };
#undef CONNEXITY_VALUE #undef CONNEXITY_VALUE

View File

@ -28,33 +28,38 @@ namespace Anabatic {
class NetBuilderHV : public NetBuilder { class NetBuilderHV : public NetBuilder {
public: public:
NetBuilderHV (); NetBuilderHV ();
virtual ~NetBuilderHV (); virtual ~NetBuilderHV ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
private: private:
virtual bool _do_1G_1M1 (); virtual bool _do_1G_1M1 ();
virtual bool _do_1G_xM1 (); virtual bool _do_1G_xM1 ();
virtual bool _do_xG (); virtual bool _do_xG ();
virtual bool _do_2G (); virtual bool _do_2G ();
virtual bool _do_2G_1M1 (); virtual bool _do_2G_1M1 ();
virtual bool _do_xG_1Pad (); virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM1 (); virtual bool _do_1G_1PinM1 ();
virtual bool _do_2G_1PinM1 (); virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM2 (); virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 (); virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 (); virtual bool _do_1G_1PinM3 ();
virtual bool _do_xG_1PinM3 (); virtual bool _do_xG_1PinM3 ();
virtual bool _do_xG_1M1 (); virtual bool _do_xG_1M1 ();
virtual bool _do_xG_1M1_1M2 (); virtual bool _do_xG_1M1_1M2 ();
virtual bool _do_xG_xM1_xM3 (); virtual bool _do_xG_xM1_xM3 ();
virtual bool _do_4G_1M2 (); virtual bool _do_4G_1M2 ();
virtual bool _do_xG_xM2 (); virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 (); virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 (); virtual bool _do_xG_xM3 ();
virtual bool _do_globalSegment (); virtual bool _do_1G_xM1_1PinM2 ();
virtual bool _do_2G_xM1_1PinM2 ();
virtual bool _do_1G_1M1_1PinM3 ();
virtual bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* );
public: public:
virtual string getTypeName () const; virtual string getTypeName () const;
}; };

19
bootstrap/allianceInstaller.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
buildDir=${commonRoot}/build
installDir=${commonRoot}/install
export ALLIANCE_TOP=${installDir}
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
cd ${srcDir}
# Skip doc generation to avoid pulling TeXLive in docker images.
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
./autostuff clean
./autostuff
mkdir -p ${buildDir}
cd ${buildDir}
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
make -j1 install

View File

@ -187,8 +187,8 @@ class Builder:
if self._ninja: command += [ "-G", "Ninja" ] if self._ninja: command += [ "-G", "Ninja" ]
if self._macports: command += [ "-D", "WITH_MACPORTS:STRING=TRUE" ] if self._macports: command += [ "-D", "WITH_MACPORTS:STRING=TRUE" ]
if self._noSystemBoost: command += [ "-D", "Boost_NO_SYSTEM_PATHS:STRING=TRUE" if self._noSystemBoost: command += [ "-D", "Boost_NO_SYSTEM_PATHS:STRING=TRUE"
, "-D", "BOOST_INCLUDEDIR:STRING=/usr/include/boost169" #, "-D", "BOOST_INCLUDEDIR:STRING=/usr/include/boost169"
, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib64/boost169" #, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib64/boost169"
] ]
if self._qt5: command += [ "-D", "WITH_QT5:STRING=TRUE" ] if self._qt5: command += [ "-D", "WITH_QT5:STRING=TRUE" ]
if self._openmp: command += [ "-D", "WITH_OPENMP:STRING=TRUE" ] if self._openmp: command += [ "-D", "WITH_OPENMP:STRING=TRUE" ]
@ -198,6 +198,7 @@ class Builder:
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir , "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir
, "-D", "CMAKE_INSTALL_DIR:STRING=%s" % cmakeInstallDir , "-D", "CMAKE_INSTALL_DIR:STRING=%s" % cmakeInstallDir
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules #, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
#, "-D", "Boost_DEBUG:STRING=TRUE"
, toolSourceDir ] , toolSourceDir ]
if not os.path.isdir(toolBuildDir): if not os.path.isdir(toolBuildDir):

View File

@ -8,6 +8,7 @@
FindLibbfd.cmake FindLibbfd.cmake
FindQwt.cmake FindQwt.cmake
FindSphinx.cmake FindSphinx.cmake
FindPelican.cmake
GetGitRevisionDescription.cmake GetGitRevisionDescription.cmake
GetGitRevisionDescription.cmake.in GetGitRevisionDescription.cmake.in
) )

View File

@ -39,6 +39,15 @@
message("-- Distribution is ${DISTRIBUTION}") message("-- Distribution is ${DISTRIBUTION}")
endmacro(check_distribution) endmacro(check_distribution)
#
# Specific setup for MacOS X.
#
if(WITH_MACPORTS)
set(Boost_PYVER "27")
else()
set(Boost_PYVER "")
endif()
# #
# Get the svn revision version and configure a svn.h.in file based on this version # Get the svn revision version and configure a svn.h.in file based on this version
# The include directory name is passed as argument # The include directory name is passed as argument
@ -85,9 +94,11 @@
set(ADDTIONAL_FLAGS "") set(ADDTIONAL_FLAGS "")
set(CXX_STANDARD "c++11") set(CXX_STANDARD "c++11")
endif() endif()
set(CMAKE_C_FLAGS_DEBUG " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE) #set(CMAKE_C_FLAGS_DEBUG " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
set(CMAKE_C_FLAGS_DEBUG " -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
set(CMAKE_C_FLAGS_RELEASE " -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE) set(CMAKE_C_FLAGS_RELEASE " -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE) #set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE) set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
@ -175,15 +186,6 @@
endmacro(hurricane_check_libraries) endmacro(hurricane_check_libraries)
#
# Find Boost, checking different versions.
#
if(WITH_MACPORTS)
set(Boost_PYVER "27")
else()
set(Boost_PYVER "")
endif()
macro(setup_boost) macro(setup_boost)
#set(Boost_USE_STATIC_LIBS ON) #set(Boost_USE_STATIC_LIBS ON)
#message(STATUS "Always uses Boost static libraries.") #message(STATUS "Always uses Boost static libraries.")
@ -191,7 +193,7 @@
find_package(Boost 1.35.0 REQUIRED) find_package(Boost 1.35.0 REQUIRED)
else(ARGC LESS 1) else(ARGC LESS 1)
foreach(component ${ARGV}) foreach(component ${ARGV})
if(${component} EQUAL "python") if(${component} STREQUAL "python")
set(component ${component}${Boost_PYVER}) set(component ${component}${Boost_PYVER})
endif() endif()
set(components ${components} ${component}) set(components ${components} ${component})
@ -278,11 +280,13 @@
else() else()
find_path(QWT_INCLUDE_DIR NAMES qwt.h find_path(QWT_INCLUDE_DIR NAMES qwt.h
PATHS /usr/include/qwt-qt4 PATHS /usr/include/qwt-qt4
/opt/local/libexec/qt4/include
/usr/include/qt4 /usr/include/qt4
/usr/include /usr/include
PATH_SUFFIXES qwt ) PATH_SUFFIXES qwt )
find_library(QWT_LIBRARY NAMES qwt-qt4 qwt find_library(QWT_LIBRARY NAMES qwt-qt4 qwt
PATHS /usr/lib${LIB_SUFFIX} ) PATHS /opt/local/libexec/qt4/lib
/usr/lib${LIB_SUFFIX} )
endif() endif()
if( QWT_INCLUDE_DIR AND QWT_LIBRARY) if( QWT_INCLUDE_DIR AND QWT_LIBRARY)

View File

@ -0,0 +1,10 @@
find_program( PELICAN_EXECUTABLE NAMES pelican
HINTS $ENV{PELICAN_DIR}
PATH_SUFFIXES bin
DOC "Pelican blog generator"
)
include( FindPackageHandleStandardArgs )
find_package_handle_standard_args( Pelican DEFAULT_MSG PELICAN_EXECUTABLE )
mark_as_advanced( PELICAN_EXECUTABLE )

View File

@ -130,7 +130,6 @@ def guessOs ():
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1] print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
print " (using: \"%s\")" % osType print " (using: \"%s\")" % osType
ldLibraryPath = os.getenv('LD_LIBRARY_PATH') ldLibraryPath = os.getenv('LD_LIBRARY_PATH')
if ldLibraryPath and 'devtoolset' in ldLibraryPath: useDevtoolset = False if ldLibraryPath and 'devtoolset' in ldLibraryPath: useDevtoolset = False
@ -187,6 +186,7 @@ if __name__ == "__main__":
parser.add_option ( "--shared" , action="store_true" , dest="shared" ) parser.add_option ( "--shared" , action="store_true" , dest="shared" )
parser.add_option ( "--no-python" , action="store_true" , dest="nopython" ) parser.add_option ( "--no-python" , action="store_true" , dest="nopython" )
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" ) parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" )
parser.add_option ( "--remove" , action="store_true" , dest="remove" )
( options, args ) = parser.parse_args () ( options, args ) = parser.parse_args ()
if options.release: buildType = "Release" if options.release: buildType = "Release"
@ -207,6 +207,32 @@ if __name__ == "__main__":
strippedLibraryPath = scrubPath( "LD_LIBRARY_PATH" ) strippedLibraryPath = scrubPath( "LD_LIBRARY_PATH" )
strippedPythonPath = scrubPath( "PYTHONPATH" ) strippedPythonPath = scrubPath( "PYTHONPATH" )
if options.remove:
shellScript = 'echo "Removing Coriolis environment";'
if osType == "Darwin":
ldVar = 'DYLD_LIBRARY_PATH'
else:
ldVar = 'LD_LIBRARY_PATH'
if isBourneShell:
shellScript += 'export PATH={};hash -r;'.format(strippedPath)
shellScript += 'BOOTSTRAP_TOP="";CORIOLIS_TOP="";export -n BOOTSTRAP_TOP CORIOLIS_TOP;'
if strippedLibraryPath:
shellScript += 'export {}={};'.format(ldVar, strippedLibraryPath)
else:
shellScript += '{0}=""; export -n {0};'.format(ldVar)
else:
shellScript += 'setenv PATH {};rehash;'.format(strippedPath)
shellScript += 'unsetenv BOOTSTRAP_TOP CORIOLIS_TOP;'
if strippedLibraryPath:
shellScript += 'setenv {} {};'.format(ldVar, strippedLibraryPath)
else:
shellScript += 'unsetenv {};'.format(ldVar)
print(shellScript)
sys.exit(0)
shellScriptSh = \ shellScriptSh = \
'echo "%(MESSAGE)s";' \ 'echo "%(MESSAGE)s";' \
'echo "Switching to Coriolis 2.x (%(buildDir)s)";' \ 'echo "Switching to Coriolis 2.x (%(buildDir)s)";' \
@ -273,16 +299,25 @@ if __name__ == "__main__":
if not options.nopython: if not options.nopython:
pyVersion = sys.version_info pyVersion = sys.version_info
version = "%d.%d" % (pyVersion[0],pyVersion[1]) version = "%d.%d" % (pyVersion[0],pyVersion[1])
if osType.startswith("Linux.SL") \ #if osType.startswith("Linux.SL") \
or osType.startswith("Linux.sl") \ # or osType.startswith("Linux.sl") \
or osType.startswith("Linux.el") \ # or osType.startswith("Linux.el") \
or osType.startswith("Linux.fc") \ # or osType.startswith("Linux.fc") \
or osType.startswith("Cygwin"): # or osType.startswith("Cygwin"):
sitePackagesDir = "%s/python%s/site-packages" % (absLibDir,version) # sitePackagesDir = "%s/python%s/site-packages" % (absLibDir,version)
elif osType.startswith("Darwin"): #elif osType.startswith("Darwin"):
sitePackagesDir = "%s/%s/site-packages" % (absLibDir,version) # sitePackagesDir = "%s/%s/site-packages" % (absLibDir,version)
else: #else:
sitePackagesDir = "%s/python%s/dist-packages" % (absLibDir,version) # sitePackagesDir = "%s/python%s/dist-packages" % (absLibDir,version)
sitePackagesDir = "sitePackageDir_has_been_not_found"
for pyPackageDir in [ "%s/python%s/site-packages" % (absLibDir,version)
, "%s/python%s/dist-packages" % (absLibDir,version)
, "%s/%s/site-packages" % (absLibDir,version)
]:
if os.path.isdir(pyPackageDir):
sitePackagesDir = pyPackageDir
break
strippedPythonPath = "%s:" % (sitePackagesDir) + strippedPythonPath strippedPythonPath = "%s:" % (sitePackagesDir) + strippedPythonPath
strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath

View File

@ -0,0 +1,6 @@
FROM debian9.coriolis
COPY root/dot.bashrc /root/.bashrc
CMD [ "/bin/bash", "-i" ]

View File

@ -0,0 +1,10 @@
FROM debian9.system
COPY root/socInstaller.py /root/socInstaller.py
RUN mkdir -p coriolis-2.x/src \
&& git clone https://github.com/m-labs/nmigen.git \
&& cd nmigen \
&& python3 setup.py develop \
&& /root/socInstaller.py --docker --profile=Debian9 --do-alliance --do-coriolis --benchs

View File

@ -0,0 +1,21 @@
FROM debian:stretch-slim
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get -y install build-essential binutils-dev \
git cmake bison flex gcc python-dev \
libboost-all-dev libboost-python-dev \
zlib1g-dev libxml2-dev rapidjson-dev libbz2-dev \
qt4-dev-tools libqwt-dev python-qt4 \
python3-setuptools \
\
autotools-dev automake \
libxt-dev libxpm-dev libmotif-dev \
\
yosys \
\
vim \
&& apt-get clean

View File

@ -0,0 +1,4 @@
systemImage="debian9.system"
coriolisImage="debian9.coriolis"
bashImage="debian9.bash"

View File

@ -0,0 +1,19 @@
#!/bin/bash
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
buildDir=${commonRoot}/build
installDir=${commonRoot}/install
export ALLIANCE_TOP=${installDir}
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
cd ${srcDir}
# Skip doc generation to avoid pulling TeXLive in docker images.
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
./autostuff clean
./autostuff
mkdir -p ${buildDir}
cd ${buildDir}
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
make -j1 install

View File

@ -0,0 +1,14 @@
echo "Running /root/.bashrc"
for archDir in `ls /root/coriolis-2.x/`; do
if [ "$archDir" = "src" ]; then continue; fi
break
done
echo "Found Coriolis architecture directory \"${archDir}\"."
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
. ${installDir}/etc/profile.d/alc_env.sh
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
export QT_X11_NO_MITSHM=1

View File

@ -0,0 +1,627 @@
#!/usr/bin/env python
#
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2015-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s I n s t a l l e r |
# | |
# | Authors : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./socInstaller.py" |
# +-----------------------------------------------------------------+
#
# WARNING:
# This script has been designed only for internal use in the
# LIP6/CIAN department. If you want to use it you will need to
# change the hardwired configuration.
showTrace = True
try:
import sys
import os.path
import shutil
import optparse
import time
import traceback
import distutils.sysconfig
import subprocess
import socket
import re
import bz2
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
except ImportError, e:
module = str(e).split()[-1]
class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ):
self._code = code
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
text = None
if len(arguments) == 1:
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
else:
self._errors = arguments[0]
elif len(arguments) > 1:
text = list(arguments)
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
for line in text:
if line[0:lstrip ] == ' '*lstrip or \
line[0:lstrip-1] == '[ERROR]':
self._errors += [ line[lstrip:] ]
else:
self._errors += [ line.lstrip() ]
return
def __str__ ( self ):
if not isinstance(self._errors,list):
return "[ERROR] %s" % self._errors
formatted = "\n"
for i in range(len(self._errors)):
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
else: formatted += " %s" % self._errors[i]
if i+1 < len(self._errors): formatted += "\n"
return formatted
def addMessage ( self, message ):
if not isinstance(self._errors,list):
self._errors = [ self._errors ]
if isinstance(message,list):
for line in message:
self._errors += [ line ]
else:
self._errors += [ message ]
return
def terminate ( self ):
print self
sys.exit(self._code)
@property
def code ( self ): return self._code
class BadBinary ( ErrorMessage ):
def __init__ ( self, binary ):
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
return
class BadReturnCode ( ErrorMessage ):
def __init__ ( self, status ):
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
return
class Command ( object ):
def __init__ ( self, arguments, fdLog=None ):
self.arguments = arguments
self.fdLog = fdLog
if self.fdLog != None and not isinstance(self.fdLog,file):
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
return
def _argumentsToStr ( self, arguments ):
s = ''
for argument in arguments:
if argument.find(' ') >= 0: s += ' "' + argument + '"'
else: s += ' ' + argument
return s
def log ( self, text ):
print text[:-1]
sys.stdout.flush()
sys.stderr.flush()
if isinstance(self.fdLog,file):
self.fdLog.write( text )
self.fdLog.flush()
return
def execute ( self ):
global conf
sys.stdout.flush()
sys.stderr.flush()
homeDir = os.environ['HOME']
workDir = os.getcwd()
if homeDir.startswith(homeDir):
workDir = '~' + workDir[ len(homeDir) : ]
user = 'root'
if os.environ.has_key('USER'): user = os.environ['USER']
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
try:
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
print self.arguments
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
while True:
line = child.stdout.readline()
if not line: break
self.log( line )
except OSError, e:
raise BadBinary( self.arguments[0] )
(pid,status) = os.waitpid( child.pid, 0 )
status >>= 8
if status != 0:
raise BadReturnCode( status )
return
class CommandArg ( object ):
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
self.command = command
self.host = host
self.wd = wd
self.fdLog = fdLog
return
def __str__ ( self ):
s = ''
if self.wd: s = 'cd %s && ' % self.wd
for i in range(len(self.command)):
if i: s += ' '
s += self.command[i]
return s
def getArgs ( self ):
if not self.host: return self.command
return [ 'ssh', self.host, str(self) ]
def execute ( self ):
if not self.host and self.wd: os.chdir( self.wd )
Command( self.getArgs(), self.fdLog ).execute()
return
class AllianceCommand ( CommandArg ):
def __init__ ( self, alcBin, fdLog=None ):
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
return
class CoriolisCommand ( CommandArg ):
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
CommandArg.__init__ ( self, [ ccbBin
, '--root='+rootDir
, '--project=coriolis'
, '--make=-j%d install' % threads
] + otherArgs
, fdLog=fdLog )
return
class BenchsCommand ( CommandArg ):
def __init__ ( self, benchsDir, fdLog=None ):
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
return
class GitRepository ( object ):
@staticmethod
def getLocalRepository ( url ):
localRepo = url.split( '/' )[-1]
if localRepo.endswith('.git'):
localRepo = localRepo[:-4]
return localRepo
def __init__ ( self, url, cloneDir, fdLog=None ):
self.url = url
self.cloneDir = cloneDir
self.localRepo = GitRepository.getLocalRepository( url )
self.fdLog = fdLog
return
@property
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
def removeLocalRepo ( self ):
if os.path.isdir(self.localRepoDir):
print 'Removing Git local repository: <%s>' % self.localRepoDir
shutil.rmtree( self.localRepoDir )
return
def clone ( self ):
print 'Clone/pull from:', self.url
if not os.path.isdir(self.cloneDir):
os.makedirs( self.cloneDir )
if not os.path.isdir(self.localRepoDir):
os.chdir( self.cloneDir )
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
else:
os.chdir( self.localRepoDir )
Command( [ 'git', 'pull' ], self.fdLog ).execute()
return
def checkout ( self, branch ):
os.chdir( self.localRepoDir )
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
return
class Configuration ( object ):
PrimaryNames = \
[ 'sender' , 'receivers'
, 'coriolisRepo', 'benchsRepo' , 'supportRepos'
, 'homeDir' , 'masterHost'
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
, 'rmSource' , 'rmBuild'
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
, 'success' , 'rcode'
]
SecondaryNames = \
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'alcBin', 'ccbBin', 'benchsDir'
]
def __init__ ( self ):
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
self._homeDir = os.environ['HOME']
self._debugArg = ''
self._rmSource = False
self._rmBuild = False
self._doGit = True
self._doCoriolis = False
self._doAlliance = False
self._doBenchs = False
self._doSendReport = False
self._nightlyMode = False
self._dockerMode = False
self._chrootMode = False
self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._ccbBin = None
self._benchsDir = None
self._masterHost = self._detectMasterHost()
self._success = False
self._rcode = 0
self._updateSecondaries()
return
def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames:
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
return
if attribute == 'masterHost' or attribute == '_masterHost':
if value == 'lepka':
print 'Never touch the Git tree when running on <lepka>.'
self._rmSource = False
self._rmBuild = False
self._doGit = False
self._doSendReport = False
if attribute[0] == '_':
self.__dict__[attribute] = value
return
if attribute == 'homeDir': value = os.path.expanduser(value)
self.__dict__['_'+attribute] = value
self._updateSecondaries()
return
def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute
if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
def _updateSecondaries ( self ):
if self._nightlyMode:
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
else:
self._rootDir = self._homeDir + '/coriolis-2.x'
self._srcDir = self._rootDir + '/src'
self._logDir = self._srcDir + '/logs'
self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
return
def _detectMasterHost ( self ):
if self._chrootMode: return 'chrooted-host'
masterHost = 'unknown'
hostname = socket.gethostname()
hostAddr = socket.gethostbyname(hostname)
if hostname == 'lepka' and hostAddr == '127.0.0.1':
masterHost = 'lepka'
else:
masterHost = hostname.split('.')[0]
return masterHost
def openLog ( self, stem ):
if not os.path.isdir(self._logDir):
os.makedirs( self._logDir )
index = 0
timeTag = time.strftime( "%Y.%m.%d" )
while True:
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
if not os.path.isfile(logFile):
print "Report log: <%s>" % logFile
break
index += 1
fd = open( logFile, "w" )
self._logs[stem] = logFile
self._fds [stem] = fd
return
def closeLogs ( self ):
for fd in self._fds.values():
if fd: fd.close()
return
def compressLogs ( self ):
for log in self._logs.values():
if not log: continue
fd = open( log, 'r' )
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
for line in fd.readlines(): bzfd.write( line )
bzfd.close()
fd.close()
os.unlink( log )
return
def getCommands ( self, target ):
commands = []
if self.doAlliance:
if not os.path.isfile( self.alcBin ):
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
, ' <%s>' % self.alcBin
] )
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
if self.doCoriolis:
if not os.path.isfile( self.ccbBin ):
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
, ' <%s>' % self.ccbBin
] )
otherArgs = []
if self.debugArg: otherArgs.append( self.debugArg )
if target == 'SL7_64':
otherArgs.append( '--project=support' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'SL6_64' or target == 'SL6':
otherArgs.append( '--project=support' )
otherArgs.append( '--devtoolset=8' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'Ubuntu18' or target == 'Debian9':
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
if self.doBenchs:
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
return commands
class Report ( object ):
def __init__ ( self, conf ):
self.conf = conf
commaspace = ', '
date = time.strftime( "%A %d %B %Y" )
stateText = 'FAILED'
modeText = 'SoC installation'
if self.conf.success: stateText = 'SUCCESS'
if self.conf.nightlyMode: modeText = 'Nightly build'
self.message = MIMEMultipart()
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
self.message['From' ] = self.conf.sender
self.message['To' ] = commaspace.join( self.conf.receivers )
self.attachements = []
self.mainText = '\n'
self.mainText += 'Salut le Crevard,\n'
self.mainText += '\n'
if self.conf.nightlyMode:
self.mainText += 'This is the nightly build report of Coriolis.\n'
else:
self.mainText += 'SoC installer report of Coriolis.\n'
self.mainText += '%s\n' % date
self.mainText += '\n'
if self.conf.success:
self.mainText += 'Build was SUCCESSFUL\n'
else:
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
self.mainText += '\n'
self.mainText += 'Complete log file(s) can be found here:\n'
return
def attachLog ( self, logFile ):
if not logFile: return
fd = open( logFile, 'rb' )
try:
fd.seek( -1024*100, os.SEEK_END )
except IOError, e:
pass
tailLines = ''
for line in fd.readlines()[1:]:
tailLines += line
fd.close()
self.mainText += ' <%s>\n' % logFile
attachement = MIMEApplication(tailLines)
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
self.attachements.append( attachement )
return
def send ( self ):
self.message.attach( MIMEText(self.mainText) )
for attachement in self.attachements:
self.message.attach( attachement )
print "Sending mail report to:"
for receiver in self.conf.receivers: print ' <%s>' % receiver
session = smtplib.SMTP( 'localhost' )
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
session.quit()
return
# -------------------------------------------------------------------
# <socInstaller> Main Part.
parser = optparse.OptionParser ()
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
(options, args) = parser.parse_args ()
conf = Configuration()
try:
if options.debug: conf.debugArg = '--debug'
if options.nightly: conf.nightlyMode = True
if options.docker: conf.dockerMode = True
if options.chroot: conf.chrootMode = True
if options.noGit: conf.doGit = False
if options.doCoriolis: conf.doCoriolis = True
if options.doAlliance: conf.doAlliance = True
if options.benchs: conf.doBenchs = True
if options.doReport: conf.doSendReport = True
if options.rmSource or options.rmAll: conf.rmSource = True
if options.rmBuild or options.rmAll: conf.rmBuild = True
if conf.doAlliance: conf.openLog( 'alliance' )
if conf.doCoriolis: conf.openLog( 'coriolis' )
if conf.doBenchs: conf.openLog( 'benchs' )
if conf.dockerMode: os.environ['USER'] = 'root'
gitSupports = []
for supportRepo in conf.supportRepos:
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
if conf.doAlliance:
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
if conf.doGit:
for gitSupport in gitSupports:
if conf.rmSource: gitSupport.removeLocalRepo()
gitSupport.clone()
#if gitSupport.url.endswith('rapidjson'):
# gitSupport.checkout( 'a1c4f32' )
if conf.doCoriolis:
if conf.rmSource: gitCoriolis.removeLocalRepo()
gitCoriolis.clone ()
gitCoriolis.checkout( 'devel' )
if conf.doAlliance:
if conf.rmSource: gitAlliance.removeLocalRepo()
gitAlliance.clone ()
#gitAlliance.checkout( 'devel' )
if conf.rmSource: gitBenchs.removeLocalRepo()
gitBenchs.clone()
if conf.rmBuild:
for entry in os.listdir(conf.rootDir):
if entry.startswith('Linux.'):
buildDir = conf.rootDir+'/'+entry
print 'Removing OS build directory: <%s>' % buildDir
shutil.rmtree( buildDir )
commands = conf.getCommands( options.profile )
for command in commands:
if command.host:
print 'Executing command on remote host <%s>:' % host
else:
print 'Executing command on *local* host:'
print ' %s' % str(command)
command.execute()
conf.closeLogs()
conf.success = True
except ErrorMessage, e:
print e
conf.closeLogs()
conf.success = False
if showTrace:
print '\nPython stack trace:'
traceback.print_tb( sys.exc_info()[2] )
conf.rcode = e.code
if conf.doSendReport:
report = Report( conf )
report.attachLog( conf.logs['coriolis' ] )
report.attachLog( conf.logs['benchs' ] )
report.send()
conf.compressLogs()
sys.exit( conf.rcode )

View File

@ -0,0 +1,6 @@
FROM sl7.coriolis
COPY root/dot.bashrc /root/.bashrc
CMD [ "/bin/bash", "-i" ]

View File

@ -0,0 +1,6 @@
FROM sl7.system
COPY root/socInstaller.py /root/socInstaller.py
RUN /root/socInstaller.py --docker --profile=SL7_64 --do-alliance --do-coriolis --benchs

View File

@ -0,0 +1,25 @@
FROM scientificlinux/sl:latest
RUN yum -y update \
&& yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
&& yum -y install git cmake bison flex gcc-c++ libstdc++-devel \
make binutils-devel \
boost-devel boost-python boost-filesystem \
boost-regex boost-wave \
python-devel libxml2-devel bzip2-devel \
qt-devel PyQt4 \
\
autoconf automake libtool \
libX11-devel libXt-devel libXpm-devel \
motif motif-devel \
\
python36-six \
vim-x11 \
&& yum -y install http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/qwt-6.1.2-4.fc23.x86_64.rpm \
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/qwt-devel-6.1.2-4.fc23.x86_64.rpm \
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/yosys-0.9-1.el7.soc.x86_64.rpm \
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/python3-pyvcd-0.1.7-git2302c99.1.el7.soc.x86_64.rpm \
http://ftp.lip6.fr/pub/linux/distributions/slsoc/soc/7/addons/x86_64/RPMS/python3-nmigen-0.1-git57d95b7.1.el7.soc.x86_64.rpm \
&& yum clean all

View File

@ -0,0 +1,4 @@
systemImage="sl7.system"
coriolisImage="sl7.coriolis"
bashImage="sl7.bash"

View File

@ -0,0 +1,18 @@
#!/bin/bash
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
buildDir=${commonRoot}/build
installDir=${commonRoot}/install
export ALLIANCE_TOP=${installDir}
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
cd ${srcDir}
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
./autostuff clean
./autostuff
mkdir -p ${buildDir}
cd ${buildDir}
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
make -j1 install

View File

@ -0,0 +1,14 @@
echo "Running /root/.bashrc"
for archDir in `ls /root/coriolis-2.x/`; do
if [ "$archDir" = "src" ]; then continue; fi
break
done
echo "Found Coriolis architecture directory \"${archDir}\"."
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
. ${installDir}/etc/profile.d/alc_env.sh
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
export QT_X11_NO_MITSHM=1

View File

@ -0,0 +1,631 @@
#!/usr/bin/env python
#
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2015-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s I n s t a l l e r |
# | |
# | Authors : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./socInstaller.py" |
# +-----------------------------------------------------------------+
#
# WARNING:
# This script has been designed only for internal use in the
# LIP6/CIAN department. If you want to use it you will need to
# change the hardwired configuration.
showTrace = True
try:
import sys
import os.path
import shutil
import optparse
import time
import traceback
import distutils.sysconfig
import subprocess
import socket
import re
import bz2
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
except ImportError, e:
module = str(e).split()[-1]
class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ):
self._code = code
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
text = None
if len(arguments) == 1:
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
else:
self._errors = arguments[0]
elif len(arguments) > 1:
text = list(arguments)
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
for line in text:
if line[0:lstrip ] == ' '*lstrip or \
line[0:lstrip-1] == '[ERROR]':
self._errors += [ line[lstrip:] ]
else:
self._errors += [ line.lstrip() ]
return
def __str__ ( self ):
if not isinstance(self._errors,list):
return "[ERROR] %s" % self._errors
formatted = "\n"
for i in range(len(self._errors)):
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
else: formatted += " %s" % self._errors[i]
if i+1 < len(self._errors): formatted += "\n"
return formatted
def addMessage ( self, message ):
if not isinstance(self._errors,list):
self._errors = [ self._errors ]
if isinstance(message,list):
for line in message:
self._errors += [ line ]
else:
self._errors += [ message ]
return
def terminate ( self ):
print self
sys.exit(self._code)
@property
def code ( self ): return self._code
class BadBinary ( ErrorMessage ):
def __init__ ( self, binary ):
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
return
class BadReturnCode ( ErrorMessage ):
def __init__ ( self, status ):
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
return
class Command ( object ):
def __init__ ( self, arguments, fdLog=None ):
self.arguments = arguments
self.fdLog = fdLog
if self.fdLog != None and not isinstance(self.fdLog,file):
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
return
def _argumentsToStr ( self, arguments ):
s = ''
for argument in arguments:
if argument.find(' ') >= 0: s += ' "' + argument + '"'
else: s += ' ' + argument
return s
def log ( self, text ):
print text[:-1]
sys.stdout.flush()
sys.stderr.flush()
if isinstance(self.fdLog,file):
self.fdLog.write( text )
self.fdLog.flush()
return
def execute ( self ):
global conf
sys.stdout.flush()
sys.stderr.flush()
homeDir = os.environ['HOME']
workDir = os.getcwd()
if homeDir.startswith(homeDir):
workDir = '~' + workDir[ len(homeDir) : ]
user = 'root'
if os.environ.has_key('USER'): user = os.environ['USER']
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
try:
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
print self.arguments
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
while True:
line = child.stdout.readline()
if not line: break
self.log( line )
except OSError, e:
raise BadBinary( self.arguments[0] )
(pid,status) = os.waitpid( child.pid, 0 )
status >>= 8
if status != 0:
raise BadReturnCode( status )
return
class CommandArg ( object ):
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
self.command = command
self.host = host
self.wd = wd
self.fdLog = fdLog
return
def __str__ ( self ):
s = ''
if self.wd: s = 'cd %s && ' % self.wd
for i in range(len(self.command)):
if i: s += ' '
s += self.command[i]
return s
def getArgs ( self ):
if not self.host: return self.command
return [ 'ssh', self.host, str(self) ]
def execute ( self ):
if not self.host and self.wd: os.chdir( self.wd )
Command( self.getArgs(), self.fdLog ).execute()
return
class AllianceCommand ( CommandArg ):
def __init__ ( self, alcBin, fdLog=None ):
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
return
class CoriolisCommand ( CommandArg ):
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
CommandArg.__init__ ( self, [ ccbBin
, '--root='+rootDir
, '--project=coriolis'
, '--make=-j%d install' % threads
] + otherArgs
, fdLog=fdLog )
return
class BenchsCommand ( CommandArg ):
def __init__ ( self, benchsDir, fdLog=None ):
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
return
class GitRepository ( object ):
@staticmethod
def getLocalRepository ( url ):
localRepo = url.split( '/' )[-1]
if localRepo.endswith('.git'):
localRepo = localRepo[:-4]
return localRepo
def __init__ ( self, url, cloneDir, fdLog=None ):
self.url = url
self.cloneDir = cloneDir
self.localRepo = GitRepository.getLocalRepository( url )
self.fdLog = fdLog
return
@property
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
def removeLocalRepo ( self ):
if os.path.isdir(self.localRepoDir):
print 'Removing Git local repository: <%s>' % self.localRepoDir
shutil.rmtree( self.localRepoDir )
return
def clone ( self ):
print 'Clone/pull from:', self.url
if not os.path.isdir(self.cloneDir):
os.makedirs( self.cloneDir )
if not os.path.isdir(self.localRepoDir):
os.chdir( self.cloneDir )
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
else:
os.chdir( self.localRepoDir )
Command( [ 'git', 'pull' ], self.fdLog ).execute()
return
def checkout ( self, branch ):
os.chdir( self.localRepoDir )
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
return
class Configuration ( object ):
PrimaryNames = \
[ 'sender' , 'receivers'
, 'coriolisRepo', 'benchsRepo' , 'supportRepos'
, 'homeDir' , 'masterHost'
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
, 'rmSource' , 'rmBuild'
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
, 'success' , 'rcode'
]
SecondaryNames = \
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'alcBin', 'ccbBin', 'benchsDir'
]
def __init__ ( self ):
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
self._homeDir = os.environ['HOME']
self._debugArg = ''
self._rmSource = False
self._rmBuild = False
self._doGit = True
self._doCoriolis = False
self._doAlliance = False
self._doBenchs = False
self._doSendReport = False
self._nightlyMode = False
self._dockerMode = False
self._chrootMode = None
self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._ccbBin = None
self._benchsDir = None
self._masterHost = self._detectMasterHost()
self._success = False
self._rcode = 0
self._updateSecondaries()
return
def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames:
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
return
if attribute == 'masterHost' or attribute == '_masterHost':
if value == 'lepka':
print 'Never touch the Git tree when running on <lepka>.'
self._rmSource = False
self._rmBuild = False
self._doGit = False
self._doSendReport = False
if attribute[0] == '_':
self.__dict__[attribute] = value
return
if attribute == 'homeDir': value = os.path.expanduser(value)
self.__dict__['_'+attribute] = value
self._updateSecondaries()
return
def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute
if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
def _updateSecondaries ( self ):
if self._nightlyMode:
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
else:
self._rootDir = self._homeDir + '/coriolis-2.x'
self._srcDir = self._rootDir + '/src'
self._logDir = self._srcDir + '/logs'
self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
self._masterHost = self._detectMasterHost()
return
def _detectMasterHost ( self ):
if self._chrootMode is None: return 'unknown'
if self._chrootMode: return 'chrooted-host'
masterHost = 'unknown'
hostname = socket.gethostname()
hostAddr = socket.gethostbyname(hostname)
if hostname == 'lepka' and hostAddr == '127.0.0.1':
masterHost = 'lepka'
else:
masterHost = hostname.split('.')[0]
return masterHost
def openLog ( self, stem ):
if not os.path.isdir(self._logDir):
os.makedirs( self._logDir )
index = 0
timeTag = time.strftime( "%Y.%m.%d" )
while True:
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
if not os.path.isfile(logFile):
print "Report log: <%s>" % logFile
break
index += 1
fd = open( logFile, "w" )
self._logs[stem] = logFile
self._fds [stem] = fd
return
def closeLogs ( self ):
for fd in self._fds.values():
if fd: fd.close()
return
def compressLogs ( self ):
for log in self._logs.values():
if not log: continue
fd = open( log, 'r' )
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
for line in fd.readlines(): bzfd.write( line )
bzfd.close()
fd.close()
os.unlink( log )
return
def getCommands ( self, target ):
commands = []
if self.doAlliance:
if not os.path.isfile( self.alcBin ):
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
, ' <%s>' % self.alcBin
] )
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
if self.doCoriolis:
if not os.path.isfile( self.ccbBin ):
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
, ' <%s>' % self.ccbBin
] )
otherArgs = []
if self.debugArg: otherArgs.append( self.debugArg )
if target == 'SL7_64':
otherArgs.append( '--project=support' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'SL6_64' or target == 'SL6':
otherArgs.append( '--project=support' )
otherArgs.append( '--devtoolset=8' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'Ubuntu18' or target == 'Debian9':
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
if self.doBenchs:
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
return commands
class Report ( object ):
def __init__ ( self, conf ):
self.conf = conf
commaspace = ', '
date = time.strftime( "%A %d %B %Y" )
stateText = 'FAILED'
modeText = 'SoC installation'
if self.conf.success: stateText = 'SUCCESS'
if self.conf.nightlyMode: modeText = 'Nightly build'
self.message = MIMEMultipart()
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
self.message['From' ] = self.conf.sender
self.message['To' ] = commaspace.join( self.conf.receivers )
self.attachements = []
self.mainText = '\n'
self.mainText += 'Salut le Crevard,\n'
self.mainText += '\n'
if self.conf.nightlyMode:
self.mainText += 'This is the nightly build report of Coriolis.\n'
else:
self.mainText += 'SoC installer report of Coriolis.\n'
self.mainText += '%s\n' % date
self.mainText += '\n'
if self.conf.success:
self.mainText += 'Build was SUCCESSFUL\n'
else:
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
self.mainText += '\n'
self.mainText += 'Complete log file(s) can be found here:\n'
return
def attachLog ( self, logFile ):
if not logFile: return
fd = open( logFile, 'rb' )
try:
fd.seek( -1024*100, os.SEEK_END )
except IOError, e:
pass
tailLines = ''
for line in fd.readlines()[1:]:
tailLines += line
fd.close()
self.mainText += ' <%s>\n' % logFile
attachement = MIMEApplication(tailLines)
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
self.attachements.append( attachement )
return
def send ( self ):
self.message.attach( MIMEText(self.mainText) )
for attachement in self.attachements:
self.message.attach( attachement )
print "Sending mail report to:"
for receiver in self.conf.receivers: print ' <%s>' % receiver
session = smtplib.SMTP( 'localhost' )
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
session.quit()
return
# -------------------------------------------------------------------
# <socInstaller> Main Part.
parser = optparse.OptionParser ()
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
(options, args) = parser.parse_args ()
conf = Configuration()
try:
if options.debug: conf.debugArg = '--debug'
if options.nightly: conf.nightlyMode = True
if options.docker: conf.dockerMode = True
if options.chroot: conf.chrootMode = True
if options.noGit: conf.doGit = False
if options.doCoriolis: conf.doCoriolis = True
if options.doAlliance: conf.doAlliance = True
if options.benchs: conf.doBenchs = True
if options.doReport: conf.doSendReport = True
if options.rmSource or options.rmAll: conf.rmSource = True
if options.rmBuild or options.rmAll: conf.rmBuild = True
if conf.doAlliance: conf.openLog( 'alliance' )
if conf.doCoriolis: conf.openLog( 'coriolis' )
if conf.doBenchs: conf.openLog( 'benchs' )
if conf.dockerMode: os.environ['USER'] = 'root'
gitSupports = []
for supportRepo in conf.supportRepos:
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
if conf.doAlliance:
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
if conf.doGit:
for gitSupport in gitSupports:
if conf.rmSource: gitSupport.removeLocalRepo()
gitSupport.clone()
#if gitSupport.url.endswith('rapidjson'):
# gitSupport.checkout( 'a1c4f32' )
if conf.doCoriolis:
if conf.rmSource: gitCoriolis.removeLocalRepo()
gitCoriolis.clone ()
gitCoriolis.checkout( 'devel' )
if conf.doAlliance:
if conf.rmSource: gitAlliance.removeLocalRepo()
gitAlliance.clone ()
#gitAlliance.checkout( 'devel' )
if conf.rmSource: gitBenchs.removeLocalRepo()
gitBenchs.clone()
if conf.rmBuild:
for entry in os.listdir(conf.rootDir):
if entry.startswith('Linux.'):
buildDir = conf.rootDir+'/'+entry
print 'Removing OS build directory: <%s>' % buildDir
shutil.rmtree( buildDir )
commands = conf.getCommands( options.profile )
for command in commands:
if command.host:
print 'Executing command on remote host <%s>:' % host
else:
print 'Executing command on *local* host:'
print ' %s' % str(command)
command.execute()
conf.closeLogs()
conf.success = True
except ErrorMessage, e:
print e
conf.closeLogs()
conf.success = False
if showTrace:
print '\nPython stack trace:'
traceback.print_tb( sys.exc_info()[2] )
conf.rcode = e.code
if conf.doSendReport:
report = Report( conf )
report.attachLog( conf.logs['coriolis' ] )
report.attachLog( conf.logs['benchs' ] )
report.send()
conf.compressLogs()
sys.exit( conf.rcode )

View File

@ -0,0 +1,6 @@
FROM ununtu18.coriolis
COPY root/dot.bashrc /root/.bashrc
CMD [ "/bin/bash", "-i" ]

View File

@ -0,0 +1,10 @@
FROM ubuntu18.system
COPY root/socInstaller.py /root/socInstaller.py
RUN mkdir -p coriolis-2.x/src \
&& git clone https://github.com/m-labs/nmigen.git \
&& cd nmigen \
&& python3 setup.py develop \
&& /root/socInstaller.py --docker --profile=Ubuntu18 --do-alliance --do-coriolis --benchs

View File

@ -0,0 +1,26 @@
FROM ubuntu:bionic
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get -y install build-essential binutils-dev \
git cmake bison flex gcc python-dev \
libboost-all-dev libboost-python-dev \
zlib1g-dev libxml2-dev rapidjson-dev libbz2-dev \
qtbase5-dev libqt5svg5-dev libqwt-qt5-dev \
python-pyqt5 \
\
autotools-dev automake \
libxt-dev libxpm-dev libmotif-dev \
\
yosys \
python3-setuptools python3-pip python3-six \
python3-wheel \
\
vim \
&& apt-get clean \
&& pip3 install git+https://github.com/m-labs/nmigen.git
# For building with Qt 4 instead of Qt 5.
# qt4-dev-tools libqwt-dev python-qt4 \

View File

@ -0,0 +1,4 @@
systemImage="ubuntu18.system"
coriolisImage="ubuntu18.coriolis"
bashImage="ubuntu18.bash"

View File

@ -0,0 +1,19 @@
#!/bin/bash
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
buildDir=${commonRoot}/build
installDir=${commonRoot}/install
export ALLIANCE_TOP=${installDir}
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
cd ${srcDir}
# Skip doc generation to avoid pulling TeXLive in docker images.
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
./autostuff clean
./autostuff
mkdir -p ${buildDir}
cd ${buildDir}
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
make -j1 install

View File

@ -0,0 +1,14 @@
echo "Running /root/.bashrc"
for archDir in `ls /root/coriolis-2.x/`; do
if [ "$archDir" = "src" ]; then continue; fi
break
done
echo "Found Coriolis architecture directory \"${archDir}\"."
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
. ${installDir}/etc/profile.d/alc_env.sh
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
export QT_X11_NO_MITSHM=1

View File

@ -0,0 +1,631 @@
#!/usr/bin/env python
#
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2015-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s I n s t a l l e r |
# | |
# | Authors : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./socInstaller.py" |
# +-----------------------------------------------------------------+
#
# WARNING:
# This script has been designed only for internal use in the
# LIP6/CIAN department. If you want to use it you will need to
# change the hardwired configuration.
showTrace = True
try:
import sys
import os.path
import shutil
import optparse
import time
import traceback
import distutils.sysconfig
import subprocess
import socket
import re
import bz2
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
except ImportError, e:
module = str(e).split()[-1]
class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ):
self._code = code
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
text = None
if len(arguments) == 1:
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
else:
self._errors = arguments[0]
elif len(arguments) > 1:
text = list(arguments)
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
for line in text:
if line[0:lstrip ] == ' '*lstrip or \
line[0:lstrip-1] == '[ERROR]':
self._errors += [ line[lstrip:] ]
else:
self._errors += [ line.lstrip() ]
return
def __str__ ( self ):
if not isinstance(self._errors,list):
return "[ERROR] %s" % self._errors
formatted = "\n"
for i in range(len(self._errors)):
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
else: formatted += " %s" % self._errors[i]
if i+1 < len(self._errors): formatted += "\n"
return formatted
def addMessage ( self, message ):
if not isinstance(self._errors,list):
self._errors = [ self._errors ]
if isinstance(message,list):
for line in message:
self._errors += [ line ]
else:
self._errors += [ message ]
return
def terminate ( self ):
print self
sys.exit(self._code)
@property
def code ( self ): return self._code
class BadBinary ( ErrorMessage ):
def __init__ ( self, binary ):
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
return
class BadReturnCode ( ErrorMessage ):
def __init__ ( self, status ):
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
return
class Command ( object ):
def __init__ ( self, arguments, fdLog=None ):
self.arguments = arguments
self.fdLog = fdLog
if self.fdLog != None and not isinstance(self.fdLog,file):
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
return
def _argumentsToStr ( self, arguments ):
s = ''
for argument in arguments:
if argument.find(' ') >= 0: s += ' "' + argument + '"'
else: s += ' ' + argument
return s
def log ( self, text ):
print text[:-1]
sys.stdout.flush()
sys.stderr.flush()
if isinstance(self.fdLog,file):
self.fdLog.write( text )
self.fdLog.flush()
return
def execute ( self ):
global conf
sys.stdout.flush()
sys.stderr.flush()
homeDir = os.environ['HOME']
workDir = os.getcwd()
if homeDir.startswith(homeDir):
workDir = '~' + workDir[ len(homeDir) : ]
user = 'root'
if os.environ.has_key('USER'): user = os.environ['USER']
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
try:
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
print self.arguments
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
while True:
line = child.stdout.readline()
if not line: break
self.log( line )
except OSError, e:
raise BadBinary( self.arguments[0] )
(pid,status) = os.waitpid( child.pid, 0 )
status >>= 8
if status != 0:
raise BadReturnCode( status )
return
class CommandArg ( object ):
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
self.command = command
self.host = host
self.wd = wd
self.fdLog = fdLog
return
def __str__ ( self ):
s = ''
if self.wd: s = 'cd %s && ' % self.wd
for i in range(len(self.command)):
if i: s += ' '
s += self.command[i]
return s
def getArgs ( self ):
if not self.host: return self.command
return [ 'ssh', self.host, str(self) ]
def execute ( self ):
if not self.host and self.wd: os.chdir( self.wd )
Command( self.getArgs(), self.fdLog ).execute()
return
class AllianceCommand ( CommandArg ):
def __init__ ( self, alcBin, fdLog=None ):
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
return
class CoriolisCommand ( CommandArg ):
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
CommandArg.__init__ ( self, [ ccbBin
, '--root='+rootDir
, '--project=coriolis'
, '--make=-j%d install' % threads
] + otherArgs
, fdLog=fdLog )
return
class BenchsCommand ( CommandArg ):
def __init__ ( self, benchsDir, fdLog=None ):
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
return
class GitRepository ( object ):
@staticmethod
def getLocalRepository ( url ):
localRepo = url.split( '/' )[-1]
if localRepo.endswith('.git'):
localRepo = localRepo[:-4]
return localRepo
def __init__ ( self, url, cloneDir, fdLog=None ):
self.url = url
self.cloneDir = cloneDir
self.localRepo = GitRepository.getLocalRepository( url )
self.fdLog = fdLog
return
@property
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
def removeLocalRepo ( self ):
if os.path.isdir(self.localRepoDir):
print 'Removing Git local repository: <%s>' % self.localRepoDir
shutil.rmtree( self.localRepoDir )
return
def clone ( self ):
print 'Clone/pull from:', self.url
if not os.path.isdir(self.cloneDir):
os.makedirs( self.cloneDir )
if not os.path.isdir(self.localRepoDir):
os.chdir( self.cloneDir )
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
else:
os.chdir( self.localRepoDir )
Command( [ 'git', 'pull' ], self.fdLog ).execute()
return
def checkout ( self, branch ):
os.chdir( self.localRepoDir )
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
return
class Configuration ( object ):
PrimaryNames = \
[ 'sender' , 'receivers'
, 'coriolisRepo', 'benchsRepo' , 'supportRepos'
, 'homeDir' , 'masterHost'
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
, 'rmSource' , 'rmBuild'
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
, 'success' , 'rcode'
]
SecondaryNames = \
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'alcBin', 'ccbBin', 'benchsDir'
]
def __init__ ( self ):
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
self._homeDir = os.environ['HOME']
self._debugArg = ''
self._rmSource = False
self._rmBuild = False
self._doGit = True
self._doCoriolis = False
self._doAlliance = False
self._doBenchs = False
self._doSendReport = False
self._nightlyMode = False
self._dockerMode = False
self._chrootMode = None
self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._ccbBin = None
self._benchsDir = None
self._masterHost = self._detectMasterHost()
self._success = False
self._rcode = 0
self._updateSecondaries()
return
def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames:
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
return
if attribute == 'masterHost' or attribute == '_masterHost':
if value == 'lepka':
print 'Never touch the Git tree when running on <lepka>.'
self._rmSource = False
self._rmBuild = False
self._doGit = False
self._doSendReport = False
if attribute[0] == '_':
self.__dict__[attribute] = value
return
if attribute == 'homeDir': value = os.path.expanduser(value)
self.__dict__['_'+attribute] = value
self._updateSecondaries()
return
def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute
if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
def _updateSecondaries ( self ):
if self._nightlyMode:
self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
else:
self._rootDir = self._homeDir + '/coriolis-2.x'
self._srcDir = self._rootDir + '/src'
self._logDir = self._srcDir + '/logs'
self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
self._masterHost = self._detectMasterHost()
return
def _detectMasterHost ( self ):
if self._chrootMode is None: return 'unknown'
if self._chrootMode: return 'chrooted-host'
masterHost = 'unknown'
hostname = socket.gethostname()
hostAddr = socket.gethostbyname(hostname)
if hostname == 'lepka' and hostAddr == '127.0.0.1':
masterHost = 'lepka'
else:
masterHost = hostname.split('.')[0]
return masterHost
def openLog ( self, stem ):
if not os.path.isdir(self._logDir):
os.makedirs( self._logDir )
index = 0
timeTag = time.strftime( "%Y.%m.%d" )
while True:
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
if not os.path.isfile(logFile):
print "Report log: <%s>" % logFile
break
index += 1
fd = open( logFile, "w" )
self._logs[stem] = logFile
self._fds [stem] = fd
return
def closeLogs ( self ):
for fd in self._fds.values():
if fd: fd.close()
return
def compressLogs ( self ):
for log in self._logs.values():
if not log: continue
fd = open( log, 'r' )
bzfd = bz2.BZ2File( log+'.bz2', 'w' )
for line in fd.readlines(): bzfd.write( line )
bzfd.close()
fd.close()
os.unlink( log )
return
def getCommands ( self, target ):
commands = []
if self.doAlliance:
if not os.path.isfile( self.alcBin ):
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
, ' <%s>' % self.alcBin
] )
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
if self.doCoriolis:
if not os.path.isfile( self.ccbBin ):
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
, ' <%s>' % self.ccbBin
] )
otherArgs = []
if self.debugArg: otherArgs.append( self.debugArg )
if target == 'SL7_64':
otherArgs.append( '--project=support' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'SL6_64' or target == 'SL6':
otherArgs.append( '--project=support' )
otherArgs.append( '--devtoolset=8' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'Ubuntu18' or target == 'Debian9':
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
if self.doBenchs:
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
return commands
class Report ( object ):
def __init__ ( self, conf ):
self.conf = conf
commaspace = ', '
date = time.strftime( "%A %d %B %Y" )
stateText = 'FAILED'
modeText = 'SoC installation'
if self.conf.success: stateText = 'SUCCESS'
if self.conf.nightlyMode: modeText = 'Nightly build'
self.message = MIMEMultipart()
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
self.message['From' ] = self.conf.sender
self.message['To' ] = commaspace.join( self.conf.receivers )
self.attachements = []
self.mainText = '\n'
self.mainText += 'Salut le Crevard,\n'
self.mainText += '\n'
if self.conf.nightlyMode:
self.mainText += 'This is the nightly build report of Coriolis.\n'
else:
self.mainText += 'SoC installer report of Coriolis.\n'
self.mainText += '%s\n' % date
self.mainText += '\n'
if self.conf.success:
self.mainText += 'Build was SUCCESSFUL\n'
else:
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
self.mainText += '\n'
self.mainText += 'Complete log file(s) can be found here:\n'
return
def attachLog ( self, logFile ):
if not logFile: return
fd = open( logFile, 'rb' )
try:
fd.seek( -1024*100, os.SEEK_END )
except IOError, e:
pass
tailLines = ''
for line in fd.readlines()[1:]:
tailLines += line
fd.close()
self.mainText += ' <%s>\n' % logFile
attachement = MIMEApplication(tailLines)
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
self.attachements.append( attachement )
return
def send ( self ):
self.message.attach( MIMEText(self.mainText) )
for attachement in self.attachements:
self.message.attach( attachement )
print "Sending mail report to:"
for receiver in self.conf.receivers: print ' <%s>' % receiver
session = smtplib.SMTP( 'localhost' )
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
session.quit()
return
# -------------------------------------------------------------------
# <socInstaller> Main Part.
parser = optparse.OptionParser ()
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
(options, args) = parser.parse_args ()
conf = Configuration()
try:
if options.debug: conf.debugArg = '--debug'
if options.nightly: conf.nightlyMode = True
if options.docker: conf.dockerMode = True
if options.chroot: conf.chrootMode = True
if options.noGit: conf.doGit = False
if options.doCoriolis: conf.doCoriolis = True
if options.doAlliance: conf.doAlliance = True
if options.benchs: conf.doBenchs = True
if options.doReport: conf.doSendReport = True
if options.rmSource or options.rmAll: conf.rmSource = True
if options.rmBuild or options.rmAll: conf.rmBuild = True
if conf.doAlliance: conf.openLog( 'alliance' )
if conf.doCoriolis: conf.openLog( 'coriolis' )
if conf.doBenchs: conf.openLog( 'benchs' )
if conf.dockerMode: os.environ['USER'] = 'root'
gitSupports = []
for supportRepo in conf.supportRepos:
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
if conf.doAlliance:
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
if conf.doGit:
for gitSupport in gitSupports:
if conf.rmSource: gitSupport.removeLocalRepo()
gitSupport.clone()
#if gitSupport.url.endswith('rapidjson'):
# gitSupport.checkout( 'a1c4f32' )
if conf.doCoriolis:
if conf.rmSource: gitCoriolis.removeLocalRepo()
gitCoriolis.clone ()
gitCoriolis.checkout( 'devel' )
if conf.doAlliance:
if conf.rmSource: gitAlliance.removeLocalRepo()
gitAlliance.clone ()
#gitAlliance.checkout( 'devel' )
if conf.rmSource: gitBenchs.removeLocalRepo()
gitBenchs.clone()
if conf.rmBuild:
for entry in os.listdir(conf.rootDir):
if entry.startswith('Linux.'):
buildDir = conf.rootDir+'/'+entry
print 'Removing OS build directory: <%s>' % buildDir
shutil.rmtree( buildDir )
commands = conf.getCommands( options.profile )
for command in commands:
if command.host:
print 'Executing command on remote host <%s>:' % host
else:
print 'Executing command on *local* host:'
print ' %s' % str(command)
command.execute()
conf.closeLogs()
conf.success = True
except ErrorMessage, e:
print e
conf.closeLogs()
conf.success = False
if showTrace:
print '\nPython stack trace:'
traceback.print_tb( sys.exc_info()[2] )
conf.rcode = e.code
if conf.doSendReport:
report = Report( conf )
report.attachLog( conf.logs['coriolis' ] )
report.attachLog( conf.logs['benchs' ] )
report.send()
conf.compressLogs()
sys.exit( conf.rcode )

133
bootstrap/dockerManager.sh Executable file
View File

@ -0,0 +1,133 @@
#!/bin/bash
showHelp=0
showError=0
doBuildSystem=0
doBuildCoriolis=0
doBuildBash=0
doBuild=0
doRun=0
doRemove=0
if [ ! -f "./docker-conf.sh" ]; then
echo "[ERROR] Missing \"./docker-conf.sh\"."
echo " (wd:\"`pwd`\")"
exit 1
fi
. "./docker-conf.sh"
dockerImages="${systemImage},${coriolisImage},${bashImage}"
while [ $# -gt 0 ]; do
case $1 in
--help) showHelp=1;;
--build-system) doBuildSystem=1;;
--build-coriolis) doBuildCoriolis=1;;
--build-bash) doBuildBash=1;;
--run) doRun=1;;
--remove) doRemove=1;;
-*) NB=2; CH=`echo $1 | cut -c$NB`
while [ "$CH" != "" ]; do
case $CH in
h) showHelp=1;;
s) doBuildSystem=1;;
c) doBuildCoriolis=1;;
b) doBuildBash=1;;
r) doRun=1;;
*) showError=1; badOption="$1";;
esac
NB=`expr $NB + 1`
CH=`echo $1 | cut -c$NB`
done;;
*) showError=1; badOption="$1";;
esac
shift
done
if [ ${showError} -ne 0 ]; then
echo "[ERROR] Unknown argument \"${badOption}\"."
exit 1
fi
if [ ${showHelp} -ne 0 ]; then
echo "Usage: ./manager.sh [options]"
echo "Options:"
echo " * [-h|--help]: Print this help."
echo " * [-s|--build-system]: Rebuild the whole OS image."
echo " * [-c|--build-coriolis]: Rebuild the Coriolis image. It will remove the previous"
echo " images (${dockerImages})."
echo " * [-b|--build-bash]: Rebuild the Bash (shell) image. It will remove the previous"
echo " image (${bashImage})."
echo " * [-r|--run]: Recompile Alliance, Coriolis & perform benchs."
echo " * [--remove]: Remove container(s) & image(s)."
exit 0
fi
if [ ${doBuildSystem} -ne 0 ]; then
doBuildBash=1
doBuildCoriolis=1
doBuild=1
doRemove=1
fi
if [ ${doBuildCoriolis} -ne 0 ]; then
doBuildBash=1
doBuild=1
doRemove=1
fi
if [ ${doBuildBash} -ne 0 ]; then
doBuild=1
doRemove=1
fi
if [ ${doRemove} -ne 0 ]; then
if [ ${doBuildBash} -ne 0 ]; then
echo "Removing \"${bashImage}\" docker container."
docker rm ${bashImage}
docker rmi ${bashImage}
fi
if [ ${doBuildCoriolis} -ne 0 ]; then
echo "Removing \"${coriolisImage}\" docker image."
docker rm ${coriolisImage}
docker rmi ${coriolisImage}
fi
if [ ${doBuildSystem} -ne 0 ]; then
echo "Removing \"${systemImage}\" docker image."
docker rm ${systemImage}
docker rmi ${systemImage}
fi
fi
if [ ${doBuild} -ne 0 ]; then
echo "Synching Alliance & Coriolis builder scripts."
cp ../../socInstaller.py ./root
cp ../../dot.bashrc ./root
if [ ${doBuildSystem} -ne 0 ]; then
echo "Build \"${systemImage}\" docker image."
docker build -f Dockerfile.system -t ${systemImage} .
fi
if [ ${doBuildCoriolis} -ne 0 ]; then
echo "Build \"${coriolisImage}\" docker image."
docker build -f Dockerfile.coriolis -t ${coriolisImage} .
fi
if [ ${doBuildCoriolis} -ne 0 ]; then
echo "Build \"${bashImage}\" docker image."
docker build -f Dockerfile.bash -t ${bashImage} .
fi
fi
if [ ${doRun} -ne 0 ]; then
docker run --rm --net=host -e DISPLAY=:0 -ti --name ${bashImage} ${bashImage}
fi

14
bootstrap/dot.bashrc Normal file
View File

@ -0,0 +1,14 @@
echo "Running /root/.bashrc"
for archDir in `ls /root/coriolis-2.x/`; do
if [ "$archDir" = "src" ]; then continue; fi
break
done
echo "Found Coriolis architecture directory \"${archDir}\"."
installDir="/root/coriolis-2.x/${archDir}/Release.Shared/install"
. ${installDir}/etc/profile.d/alc_env.sh
eval `${installDir}/etc/coriolis2/coriolisEnv.py`
export QT_X11_NO_MITSHM=1

View File

@ -46,31 +46,31 @@ except ImportError, e:
class ErrorMessage ( Exception ): class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ): def __init__ ( self, code, *arguments ):
self._code = code self._code = code
self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ] self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
text = None text = None
if len(arguments) == 1: if len(arguments) == 1:
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n') if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
else:
self._errors = arguments[0]
elif len(arguments) > 1:
text = list(arguments)
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
for line in text:
if line[0:lstrip ] == ' '*lstrip or \
line[0:lstrip-1] == '[ERROR]':
self._errors += [ line[lstrip:] ]
else: else:
self._errors += [ line.lstrip() ] self._errors = arguments[0]
return elif len(arguments) > 1:
text = list(arguments)
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
for line in text:
if line[0:lstrip ] == ' '*lstrip or \
line[0:lstrip-1] == '[ERROR]':
self._errors += [ line[lstrip:] ]
else:
self._errors += [ line.lstrip() ]
return
def __str__ ( self ): def __str__ ( self ):
if not isinstance(self._errors,list): if not isinstance(self._errors,list):
@ -104,321 +104,417 @@ class ErrorMessage ( Exception ):
class BadBinary ( ErrorMessage ): class BadBinary ( ErrorMessage ):
def __init__ ( self, binary ): def __init__ ( self, binary ):
ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary ) ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
return return
class BadReturnCode ( ErrorMessage ): class BadReturnCode ( ErrorMessage ):
def __init__ ( self, status ): def __init__ ( self, status ):
ErrorMessage.__init__( self, 1, "Command returned status:%d." % status ) ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
return return
class Command ( object ): class Command ( object ):
def __init__ ( self, arguments, fdLog=None ): def __init__ ( self, arguments, fdLog=None ):
self.arguments = arguments self.arguments = arguments
self.fdLog = fdLog self.fdLog = fdLog
if self.fdLog != None and not isinstance(self.fdLog,file): if self.fdLog != None and not isinstance(self.fdLog,file):
print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.' print '[WARNING] Command.__init__(): <fdLog> is neither None or a file.'
return return
def _argumentsToStr ( self, arguments ): def _argumentsToStr ( self, arguments ):
s = '' s = ''
for argument in arguments: for argument in arguments:
if argument.find(' ') >= 0: s += ' "' + argument + '"' if argument.find(' ') >= 0: s += ' "' + argument + '"'
else: s += ' ' + argument else: s += ' ' + argument
return s return s
def log ( self, text ): def log ( self, text ):
print text[:-1] print text[:-1]
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
if isinstance(self.fdLog,file): if isinstance(self.fdLog,file):
self.fdLog.write( text ) self.fdLog.write( text )
self.fdLog.flush() self.fdLog.flush()
return return
def execute ( self ): def execute ( self ):
global conf global conf
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
homeDir = os.environ['HOME'] homeDir = os.environ['HOME']
workDir = os.getcwd() workDir = os.getcwd()
if homeDir.startswith(homeDir): if homeDir.startswith(homeDir):
workDir = '~' + workDir[ len(homeDir) : ] workDir = '~' + workDir[ len(homeDir) : ]
prompt = '%s@%s:%s$' % (os.environ['USER'],conf.masterHost,workDir) user = 'root'
if os.environ.has_key('USER'): user = os.environ['USER']
prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
try: try:
self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) ) self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) print self.arguments
child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
while True: while True:
line = child.stdout.readline() line = child.stdout.readline()
if not line: break if not line: break
self.log( line ) self.log( line )
except OSError, e: except OSError, e:
raise BadBinary( self.arguments[0] ) raise BadBinary( self.arguments[0] )
(pid,status) = os.waitpid( child.pid, 0 ) (pid,status) = os.waitpid( child.pid, 0 )
status >>= 8 status >>= 8
if status != 0: if status != 0:
raise BadReturnCode( status ) raise BadReturnCode( status )
return
class CommandArg ( object ):
def __init__ ( self, command, wd=None, host=None, fdLog=None ):
self.command = command
self.host = host
self.wd = wd
self.fdLog = fdLog
return
def __str__ ( self ):
s = ''
if self.wd: s = 'cd %s && ' % self.wd
for i in range(len(self.command)):
if i: s += ' '
s += self.command[i]
return s
def getArgs ( self ):
if not self.host: return self.command
return [ 'ssh', self.host, str(self) ]
def execute ( self ):
if not self.host and self.wd: os.chdir( self.wd )
Command( self.getArgs(), self.fdLog ).execute()
return
class AllianceCommand ( CommandArg ):
def __init__ ( self, alcBin, fdLog=None ):
CommandArg.__init__ ( self, [ alcBin ], fdLog=fdLog )
return
class CoriolisCommand ( CommandArg ):
def __init__ ( self, ccbBin, rootDir, threads=1, otherArgs=[], fdLog=None ):
CommandArg.__init__ ( self, [ ccbBin
, '--root='+rootDir
, '--project=coriolis'
, '--make=-j%d install' % threads
] + otherArgs
, fdLog=fdLog )
return
class BenchsCommand ( CommandArg ):
def __init__ ( self, benchsDir, fdLog=None ):
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
return
return
class GitRepository ( object ): class GitRepository ( object ):
@staticmethod @staticmethod
def getLocalRepository ( url ): def getLocalRepository ( url ):
localRepo = url.split( '/' )[-1] localRepo = url.split( '/' )[-1]
if localRepo.endswith('.git'): if localRepo.endswith('.git'):
localRepo = localRepo[:-4] localRepo = localRepo[:-4]
return localRepo return localRepo
def __init__ ( self, url, cloneDir, fdLog=None ): def __init__ ( self, url, cloneDir, fdLog=None ):
self.url = url self.url = url
self.cloneDir = cloneDir self.cloneDir = cloneDir
self.localRepo = GitRepository.getLocalRepository( url ) self.localRepo = GitRepository.getLocalRepository( url )
self.fdLog = fdLog self.fdLog = fdLog
return return
@property @property
def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo def localRepoDir ( self ): return self.cloneDir+'/'+self.localRepo
def removeLocalRepo ( self ): def removeLocalRepo ( self ):
if os.path.isdir(self.localRepoDir): if os.path.isdir(self.localRepoDir):
print 'Removing Git local repository: <%s>' % self.localRepoDir print 'Removing Git local repository: <%s>' % self.localRepoDir
shutil.rmtree( self.localRepoDir ) shutil.rmtree( self.localRepoDir )
return return
def clone ( self ): def clone ( self ):
print 'Clone/pull from:', self.url print 'Clone/pull from:', self.url
if not os.path.isdir(self.cloneDir): if not os.path.isdir(self.cloneDir):
os.makedirs( self.cloneDir ) os.makedirs( self.cloneDir )
if not os.path.isdir(self.localRepoDir): if not os.path.isdir(self.localRepoDir):
os.chdir( self.cloneDir ) os.chdir( self.cloneDir )
Command( [ 'git', 'clone', self.url ], self.fdLog ).execute() Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
else: else:
os.chdir( self.localRepoDir ) os.chdir( self.localRepoDir )
Command( [ 'git', 'pull' ], self.fdLog ).execute() Command( [ 'git', 'pull' ], self.fdLog ).execute()
return return
def checkout ( self, branch ): def checkout ( self, branch ):
os.chdir( self.localRepoDir ) os.chdir( self.localRepoDir )
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute() Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
return return
class Configuration ( object ): class Configuration ( object ):
PrimaryNames = \ PrimaryNames = \
[ 'sender' , 'receivers' [ 'sender' , 'receivers'
, 'coriolisRepo', 'benchsRepo', 'supportRepos' , 'coriolisRepo', 'benchsRepo' , 'supportRepos'
, 'homeDir' , 'masterHost' , 'homeDir' , 'masterHost'
, 'debugArg' , 'nightlyMode' , 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
, 'rmSource' , 'rmBuild', 'doGit', 'doBuild', 'doBenchs', 'doSendReport' , 'rmSource' , 'rmBuild'
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
, 'success' , 'rcode' , 'success' , 'rcode'
] ]
SecondaryNames = \ SecondaryNames = \
[ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds' [ 'rootDir', 'srcDir', 'logDir', 'logs', 'fds', 'alcBin', 'ccbBin', 'benchsDir'
] ]
def __init__ ( self ): def __init__ ( self ):
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr' self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ] self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ] self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
self._coriolisRepo = 'https://www-soc.lip6.fr/git/coriolis.git' self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
self._benchsRepo = 'https://www-soc.lip6.fr/git/alliance-check-toolkit.git' self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
self._homeDir = os.environ['HOME'] self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
self._debugArg = '' self._homeDir = os.environ['HOME']
self._rmSource = False self._debugArg = ''
self._rmBuild = False self._rmSource = False
self._doGit = True self._rmBuild = False
self._doBuild = True self._doGit = True
self._doBenchs = False self._doCoriolis = False
self._doSendReport = True self._doAlliance = False
self._nightlyMode = False self._doBenchs = False
self._logs = { 'build':None, 'benchs':None } self._doSendReport = False
self._fds = { 'build':None, 'benchs':None } self._nightlyMode = False
self._masterHost = self._detectMasterHost() self._dockerMode = False
self._success = False self._chrootMode = None
self._rcode = 0 self._logs = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._fds = { 'alliance':None, 'coriolis':None, 'benchs':None }
self._ccbBin = None
self._benchsDir = None
self._masterHost = self._detectMasterHost()
self._success = False
self._rcode = 0
self._updateSecondaries() self._updateSecondaries()
return return
def __setattr__ ( self, attribute, value ): def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames: if attribute in Configuration.SecondaryNames:
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute ) print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
return
if attribute == 'masterHost' or attribute == '_masterHost':
if value == 'lepka':
print 'Never touch the Git tree when running on <lepka>.'
self._rmSource = False
self._rmBuild = False
self._doGit = False
self._doSendReport = False
if attribute[0] == '_':
self.__dict__[attribute] = value
return
if attribute == 'homeDir': value = os.path.expanduser(value)
self.__dict__['_'+attribute] = value
self._updateSecondaries()
return return
if attribute == 'masterHost' or attribute == '_masterHost':
if value == 'lepka':
print 'Never touch the Git tree when running on <lepka>.'
self._rmSource = False
self._rmBuild = False
self._doGit = False
self._doSendReport = False
self._targets = { 'SL6' :None
, 'SL6_64':None
, 'SL7_64':'lepka'
}
else:
self._targets = { 'SL6' :None
, 'SL6_64':None
, 'SL7_64':'bop'
}
if attribute[0] == '_':
self.__dict__[attribute] = value
return
if attribute == 'homeDir': value = os.path.expanduser(value)
self.__dict__['_'+attribute] = value
self._updateSecondaries()
return
def __getattr__ ( self, attribute ): def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute if attribute[0] != '_': attribute = '_'+attribute
if not self.__dict__.has_key(attribute): if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute ) raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
return self.__dict__[attribute] return self.__dict__[attribute]
def _updateSecondaries ( self ): def _updateSecondaries ( self ):
if self._nightlyMode: if self._nightlyMode:
self._targets['SL6'] = None self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
self._rootDir = self._homeDir + '/nightly/coriolis-2.x' else:
else: self._rootDir = self._homeDir + '/coriolis-2.x'
if self._masterHost != 'lepka': self._srcDir = self._rootDir + '/src'
self._targets['SL6'] = None self._logDir = self._srcDir + '/logs'
self._rootDir = self._homeDir + '/coriolis-2.x' self._alcBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/allianceInstaller.sh'
self._srcDir = self._rootDir + '/src' self._ccbBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/ccb.py'
self._logDir = self._srcDir + '/logs' self._benchsDir = self._srcDir + '/' + GitRepository.getLocalRepository(self._benchsRepo ) + '/benchs'
return self._masterHost = self._detectMasterHost()
return
def _detectMasterHost ( self ): def _detectMasterHost ( self ):
masterHost = 'unknown' if self._chrootMode is None: return 'unknown'
hostname = socket.gethostname() if self._chrootMode: return 'chrooted-host'
hostAddr = socket.gethostbyname(hostname)
if hostname == 'lepka' and hostAddr == '127.0.0.1': masterHost = 'unknown'
masterHost = 'lepka' hostname = socket.gethostname()
else: hostAddr = socket.gethostbyname(hostname)
masterHost = hostname.split('.')[0]
return masterHost if hostname == 'lepka' and hostAddr == '127.0.0.1':
masterHost = 'lepka'
else:
masterHost = hostname.split('.')[0]
return masterHost
def openLog ( self, stem ): def openLog ( self, stem ):
if not os.path.isdir(self._logDir): if not os.path.isdir(self._logDir):
os.makedirs( self._logDir ) os.makedirs( self._logDir )
index = 0 index = 0
timeTag = time.strftime( "%Y.%m.%d" ) timeTag = time.strftime( "%Y.%m.%d" )
while True: while True:
logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index)) logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
if not os.path.isfile(logFile): if not os.path.isfile(logFile):
print "Report log: <%s>" % logFile print "Report log: <%s>" % logFile
break break
index += 1 index += 1
fd = open( logFile, "w" ) fd = open( logFile, "w" )
self._logs[stem] = logFile self._logs[stem] = logFile
self._fds [stem] = fd self._fds [stem] = fd
return return
def closeLogs ( self ): def closeLogs ( self ):
for fd in self._fds.values(): for fd in self._fds.values():
if fd: fd.close() if fd: fd.close()
return return
def compressLogs ( self ): def compressLogs ( self ):
for log in self._logs.values(): for log in self._logs.values():
if not log: continue if not log: continue
fd = open( log, 'r' ) fd = open( log, 'r' )
bzfd = bz2.BZ2File( log+'.bz2', 'w' ) bzfd = bz2.BZ2File( log+'.bz2', 'w' )
for line in fd.readlines(): bzfd.write( line ) for line in fd.readlines(): bzfd.write( line )
bzfd.close() bzfd.close()
fd.close() fd.close()
os.unlink( log ) os.unlink( log )
return return
def getCommands ( self, target ):
commands = []
if self.doAlliance:
if not os.path.isfile( self.alcBin ):
raise ErrorMessage( 1, [ 'Cannot find <allianceInstaller.sh>, should be here:'
, ' <%s>' % self.alcBin
] )
commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
if self.doCoriolis:
if not os.path.isfile( self.ccbBin ):
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:'
, ' <%s>' % self.ccbBin
] )
otherArgs = []
if self.debugArg: otherArgs.append( self.debugArg )
if target == 'SL7_64':
otherArgs.append( '--project=support' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'SL6_64' or target == 'SL6':
otherArgs.append( '--project=support' )
otherArgs.append( '--devtoolset=8' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'Ubuntu18' or target == 'Debian9':
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
if self.doBenchs:
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
return commands
class Report ( object ): class Report ( object ):
def __init__ ( self, conf ): def __init__ ( self, conf ):
self.conf = conf self.conf = conf
commaspace = ', ' commaspace = ', '
date = time.strftime( "%A %d %B %Y" ) date = time.strftime( "%A %d %B %Y" )
stateText = 'FAILED' stateText = 'FAILED'
modeText = 'SoC installation' modeText = 'SoC installation'
if self.conf.success: stateText = 'SUCCESS' if self.conf.success: stateText = 'SUCCESS'
if self.conf.nightlyMode: modeText = 'Nightly build' if self.conf.nightlyMode: modeText = 'Nightly build'
self.message = MIMEMultipart() self.message = MIMEMultipart()
self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date) self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
self.message['From' ] = self.conf.sender self.message['From' ] = self.conf.sender
self.message['To' ] = commaspace.join( self.conf.receivers ) self.message['To' ] = commaspace.join( self.conf.receivers )
self.attachements = [] self.attachements = []
self.mainText = '\n' self.mainText = '\n'
self.mainText += 'Salut le Crevard,\n' self.mainText += 'Salut le Crevard,\n'
self.mainText += '\n' self.mainText += '\n'
if self.conf.nightlyMode: if self.conf.nightlyMode:
self.mainText += 'This is the nightly build report of Coriolis.\n' self.mainText += 'This is the nightly build report of Coriolis.\n'
else: else:
self.mainText += 'SoC installer report of Coriolis.\n' self.mainText += 'SoC installer report of Coriolis.\n'
self.mainText += '%s\n' % date self.mainText += '%s\n' % date
self.mainText += '\n' self.mainText += '\n'
if self.conf.success: if self.conf.success:
self.mainText += 'Build was SUCCESSFUL\n' self.mainText += 'Build was SUCCESSFUL\n'
else: else:
self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n' self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
self.mainText += '\n' self.mainText += '\n'
self.mainText += 'Complete log file(s) can be found here:\n' self.mainText += 'Complete log file(s) can be found here:\n'
return return
def attachLog ( self, logFile ): def attachLog ( self, logFile ):
if not logFile: return if not logFile: return
fd = open( logFile, 'rb' ) fd = open( logFile, 'rb' )
try: try:
fd.seek( -1024*100, os.SEEK_END ) fd.seek( -1024*100, os.SEEK_END )
except IOError, e: except IOError, e:
pass pass
tailLines = '' tailLines = ''
for line in fd.readlines()[1:]: for line in fd.readlines()[1:]:
tailLines += line tailLines += line
fd.close() fd.close()
self.mainText += ' <%s>\n' % logFile self.mainText += ' <%s>\n' % logFile
attachement = MIMEApplication(tailLines) attachement = MIMEApplication(tailLines)
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) ) attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
self.attachements.append( attachement ) self.attachements.append( attachement )
return return
def send ( self ): def send ( self ):
self.message.attach( MIMEText(self.mainText) ) self.message.attach( MIMEText(self.mainText) )
for attachement in self.attachements: for attachement in self.attachements:
self.message.attach( attachement ) self.message.attach( attachement )
print "Sending mail report to:" print "Sending mail report to:"
for receiver in self.conf.receivers: print ' <%s>' % receiver for receiver in self.conf.receivers: print ' <%s>' % receiver
session = smtplib.SMTP( 'localhost' ) session = smtplib.SMTP( 'localhost' )
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() ) session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
session.quit() session.quit()
return return
# ------------------------------------------------------------------- # -------------------------------------------------------------------
@ -428,36 +524,51 @@ class Report ( object ):
parser = optparse.OptionParser () parser = optparse.OptionParser ()
parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." ) parser.add_option ( "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." ) parser.add_option ( "--no-git" , action="store_true" , dest="noGit" , help="Do not pull/update Git repositories before building." )
parser.add_option ( "--no-build" , action="store_true" , dest="noBuild" , help="Do not rebuild the tools, must have already be done." ) parser.add_option ( "--do-alliance" , action="store_true" , dest="doAlliance" , help="Rebuild the Alliance tools." )
parser.add_option ( "--no-report" , action="store_true" , dest="noReport" , help="Do not send a final report." ) parser.add_option ( "--do-coriolis" , action="store_true" , dest="doCoriolis" , help="Rebuild the Coriolis tools." )
parser.add_option ( "--do-report" , action="store_true" , dest="doReport" , help="Send a final report." )
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." ) parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." ) parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." ) parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." ) parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." ) parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." ) parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
parser.add_option ( "--profile" , action="store" , type="string", dest="profile" , help="The targeted OS for the build." )
(options, args) = parser.parse_args () (options, args) = parser.parse_args ()
conf = Configuration() conf = Configuration()
try: try:
if options.debug: conf.debugArg = '--debug' if options.debug: conf.debugArg = '--debug'
if options.nightly: conf.nightlyMode = True if options.nightly: conf.nightlyMode = True
if options.docker: conf.dockerMode = True
if options.chroot: conf.chrootMode = True
if options.noGit: conf.doGit = False if options.noGit: conf.doGit = False
if options.noBuild: conf.doBuild = False if options.doCoriolis: conf.doCoriolis = True
if options.doAlliance: conf.doAlliance = True
if options.benchs: conf.doBenchs = True if options.benchs: conf.doBenchs = True
if options.noReport: conf.doSendReport = False if options.doReport: conf.doSendReport = True
if options.rmSource or options.rmAll: conf.rmSource = True if options.rmSource or options.rmAll: conf.rmSource = True
if options.rmBuild or options.rmAll: conf.rmBuild = True if options.rmBuild or options.rmAll: conf.rmBuild = True
if conf.doBuild: conf.openLog( 'build' )
if conf.doBenchs: conf.openLog( 'benchs' ) if conf.doAlliance: conf.openLog( 'alliance' )
if conf.doCoriolis: conf.openLog( 'coriolis' )
if conf.doBenchs: conf.openLog( 'benchs' )
if conf.dockerMode: os.environ['USER'] = 'root'
gitSupports = [] gitSupports = []
for supportRepo in conf.supportRepos: for supportRepo in conf.supportRepos:
gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) ) gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) )
gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['build'] ) gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['coriolis'] )
gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['build'] ) gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['coriolis'] )
if conf.doAlliance:
gitAlliance = GitRepository( conf.allianceRepo, conf.srcDir, conf.fds['alliance'] )
if conf.doGit: if conf.doGit:
for gitSupport in gitSupports: for gitSupport in gitSupports:
@ -466,9 +577,15 @@ try:
#if gitSupport.url.endswith('rapidjson'): #if gitSupport.url.endswith('rapidjson'):
# gitSupport.checkout( 'a1c4f32' ) # gitSupport.checkout( 'a1c4f32' )
if conf.rmSource: gitCoriolis.removeLocalRepo() if conf.doCoriolis:
gitCoriolis.clone () if conf.rmSource: gitCoriolis.removeLocalRepo()
gitCoriolis.checkout( 'devel_anabatic' ) gitCoriolis.clone ()
gitCoriolis.checkout( 'devel' )
if conf.doAlliance:
if conf.rmSource: gitAlliance.removeLocalRepo()
gitAlliance.clone ()
#gitAlliance.checkout( 'devel' )
if conf.rmSource: gitBenchs.removeLocalRepo() if conf.rmSource: gitBenchs.removeLocalRepo()
gitBenchs.clone() gitBenchs.clone()
@ -480,33 +597,14 @@ try:
print 'Removing OS build directory: <%s>' % buildDir print 'Removing OS build directory: <%s>' % buildDir
shutil.rmtree( buildDir ) shutil.rmtree( buildDir )
ccbBin = gitCoriolis.localRepoDir+'/bootstrap/ccb.py' commands = conf.getCommands( options.profile )
if not os.path.isfile( ccbBin ): for command in commands:
raise ErrorMessage( 1, [ 'Cannot find <ccb.py>, should be here:' if command.host:
, ' <%s>' % ccbBin print 'Executing command on remote host <%s>:' % host
] ) else:
print 'Executing command on *local* host:'
buildCommand = '%s --root=%s --project=support --project=coriolis --make="-j%%d install" %%s' \ print ' %s' % str(command)
% (ccbBin,conf.rootDir) command.execute()
benchsCommand = 'cd %s/benchs && ../bin/go.sh' % (gitBenchs.localRepoDir)
commands = \
[ ( conf.targets['SL7_64'], buildCommand % (3,conf.debugArg) , conf.fds['build' ] )
, ( conf.targets['SL7_64'], buildCommand % (1,conf.debugArg+' --doc') , conf.fds['build' ] )
, ( conf.targets['SL7_64'], benchsCommand , conf.fds['benchs'] )
#, ( conf.targets['SL6_64'], buildCommand % (6,conf.debugArg+' --devtoolset-8') , conf.fds['build' ] )
#, ( conf.targets['SL6_64'], buildCommand % (1,conf.debugArg+' --devtoolset-8 --doc'), conf.fds['build' ] )
#, ( conf.targets['SL6_64'], benchsCommand , conf.fds['benchs'] )
#, ( conf.targets['SL6'] , buildCommand % (2,conf.debugArg+' --devtoolset-8') , conf.fds['build' ] )
#, ( conf.targets['SL6'] , buildCommand % (1,conf.debugArg+' --devtoolset-8 --doc'), conf.fds['build' ] )
#, ( conf.targets['SL6'] , benchsCommand , conf.fds['benchs'] )
]
for host,command,fd in commands:
if host and fd:
print 'Executing command on <%s>:' % host
print ' %s' % command
Command( [ 'ssh', host, command ], fd ).execute()
conf.closeLogs() conf.closeLogs()
@ -524,8 +622,8 @@ except ErrorMessage, e:
if conf.doSendReport: if conf.doSendReport:
report = Report( conf ) report = Report( conf )
report.attachLog( conf.logs['build' ] ) report.attachLog( conf.logs['coriolis' ] )
report.attachLog( conf.logs['benchs'] ) report.attachLog( conf.logs['benchs' ] )
report.send() report.send()
conf.compressLogs() conf.compressLogs()

View File

@ -102,7 +102,7 @@
${PYTHON_LIBRARIES} -lutil ${PYTHON_LIBRARIES} -lutil
) )
add_library( bora ${cpps} ${mocCpps} ) add_library( bora ${cpps} ${mocCpps} ${pyCpps} )
set_target_properties( bora PROPERTIES VERSION 1.0 SOVERSION 1 ) set_target_properties( bora PROPERTIES VERSION 1.0 SOVERSION 1 )
target_link_libraries( bora ${depLibs} ) target_link_libraries( bora ${depLibs} )

View File

@ -189,7 +189,10 @@ namespace Bora {
{ {
cdebug_log(535,1) << "HSlicingNode::updateGlobalsize() - " << this << endl; cdebug_log(535,1) << "HSlicingNode::updateGlobalsize() - " << this << endl;
for ( SlicingNode* child : _children ) child->updateGlobalSize(); for ( SlicingNode* child : _children ) {
cdebug_log(535,0) << "child: " << child << endl;
child->updateGlobalSize();
}
if (not getMaster()) { if (not getMaster()) {
if (getNbChild() == 1) { if (getNbChild() == 1) {

View File

@ -70,7 +70,8 @@ namespace Bora {
TransistorFamily* device = dynamic_cast<TransistorFamily *>( cell ); TransistorFamily* device = dynamic_cast<TransistorFamily *>( cell );
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() ); StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
if (device) { if (device) {
//cdebug_log(536,0) << "createNodeSets for an Analog Device" << endl; cdebug_log(535,0) << "NodeSets:create(): for a Transistor Analog Device" << endl;
if (not stepRange) { if (not stepRange) {
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s." throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
, getString(device->getName()).c_str() , getString(device->getName()).c_str()
@ -94,30 +95,36 @@ namespace Bora {
MatrixParameterRange* matrixRange = dynamic_cast<MatrixParameterRange*>( nodeset->getRange() ); MatrixParameterRange* matrixRange = dynamic_cast<MatrixParameterRange*>( nodeset->getRange() );
if (mcapacitor) { if (mcapacitor) {
cdebug_log(535,0) << "NodeSets::create(): for a Capacitor Analog Device" << endl;
if (not matrixRange) { if (not matrixRange) {
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a MatrixParameterRange argument instead of %s." throw Error( "NodeSets::create(): Device \"%s\" must be associated with a MatrixParameterRange argument instead of %s."
, getString(mcapacitor->getName()).c_str() , getString(mcapacitor->getName()).c_str()
, getString(stepRange).c_str() , getString(stepRange).c_str()
); );
matrixRange->reset();
do {
MatrixParameter* mp = NULL;
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("matrix"))) != NULL )
mp->setMatrix( &matrixRange->getValue() );
layoutGenerator->setDevice( mcapacitor );
layoutGenerator->drawLayout();
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
matrixRange->progress();
} while ( matrixRange->isValid() );
} }
matrixRange->reset();
do {
MatrixParameter* mp = NULL;
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("matrix"))) != NULL )
mp->setMatrix( &matrixRange->getValue() );
layoutGenerator->setDevice( mcapacitor );
layoutGenerator->drawLayout();
//cerr << " Create BoxSet for Capacitor " << matrixRange->getValue() << endl;
cerr << " Create BoxSet for Capacitor " << endl;
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
matrixRange->progress();
} while ( matrixRange->isValid() );
} else { } else {
ResistorFamily* device = dynamic_cast<ResistorFamily *>( cell ); ResistorFamily* device = dynamic_cast<ResistorFamily *>( cell );
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() ); StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
if (device) { if (device) {
cdebug_log(535,0) << "NodeSets::create(): for a Resistor Analog Device" << endl;
if (not stepRange) { if (not stepRange) {
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s." throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
, getString(device->getName()).c_str() , getString(device->getName()).c_str()

View File

@ -18,6 +18,7 @@
#include "crlcore/PyRoutingGauge.h" #include "crlcore/PyRoutingGauge.h"
#include "bora/PyDSlicingNode.h" #include "bora/PyDSlicingNode.h"
#include "bora/PyStepParameterRange.h" #include "bora/PyStepParameterRange.h"
#include "bora/PyMatrixParameterRange.h"
namespace Bora { namespace Bora {
@ -73,8 +74,9 @@ extern "C" {
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Second argument *must* be of type Cell." ); PyErr_SetString( ConstructorError, "DSlicingNode.create(): Second argument *must* be of type Cell." );
return NULL; return NULL;
} }
if (not IsPyStepParameterRange(pyParameterRange)) { if ( not IsPyStepParameterRange(pyParameterRange)
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange." ); and not IsPyMatrixParameterRange(pyParameterRange)) {
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange or MatrixParameterRange." );
return NULL; return NULL;
} }
if (pyRoutingGauge and not IsPyRoutingGauge(pyRoutingGauge)) { if (pyRoutingGauge and not IsPyRoutingGauge(pyRoutingGauge)) {
@ -82,10 +84,18 @@ extern "C" {
return NULL; return NULL;
} }
Cell* cell = PYCELL_O( pyCell ); Cell* cell = PYCELL_O( pyCell );
Instance* instance = cell->getInstance( PyString_AsString(pyInstance) ); Instance* instance = cell->getInstance( PyString_AsString(pyInstance) );
ParameterRange* range = ParameterRangeCast( pyParameterRange ); if (not instance) {
RoutingGauge* rg = (pyRoutingGauge) ? PYROUTINGGAUGE_O(pyRoutingGauge) : NULL; ostringstream message;
message << "DSlicingNode.create(): Cell \"" << cell->getName()
<< "\" has no instance named \"" << PyString_AsString(pyInstance) << "\".";
PyErr_SetString( ConstructorError, message.str().c_str() );
return NULL;
}
ParameterRange* range = ParameterRangeCast( pyParameterRange );
RoutingGauge* rg = (pyRoutingGauge) ? PYROUTINGGAUGE_O(pyRoutingGauge) : NULL;
node = DSlicingNode::create( NodeSets::create( instance->getMasterCell(), range, rg ) node = DSlicingNode::create( NodeSets::create( instance->getMasterCell(), range, rg )
, UnknownAlignment , UnknownAlignment

View File

@ -16,6 +16,7 @@
#include "bora/PyParameterRange.h" #include "bora/PyParameterRange.h"
#include "bora/PyStepParameterRange.h" #include "bora/PyStepParameterRange.h"
#include "bora/PyMatrixParameterRange.h"
namespace Bora { namespace Bora {
@ -112,7 +113,8 @@ extern "C" {
# if !defined(__PYTHON_MODULE__) # if !defined(__PYTHON_MODULE__)
ParameterRange* ParameterRangeCast ( PyObject* derivedObject ) { ParameterRange* ParameterRangeCast ( PyObject* derivedObject ) {
if (IsPyStepParameterRange(derivedObject)) return PYSTEPPARAMETERRANGE_O(derivedObject); if (IsPyStepParameterRange (derivedObject)) return PYSTEPPARAMETERRANGE_O (derivedObject);
if (IsPyMatrixParameterRange(derivedObject)) return PYMATRIXPARAMETERRANGE_O(derivedObject);
return NULL; return NULL;
} }

View File

@ -396,12 +396,16 @@ namespace Bora {
for( Instance* iInstance : instances ) { for( Instance* iInstance : instances ) {
Cell* model = iInstance->getMasterCell(); Cell* model = iInstance->getMasterCell();
Device* device = dynamic_cast<Device*>(model); Device* device = dynamic_cast<Device*>(model);
cerr << "device:" << device << endl;
if (device) { if (device) {
TransistorFamily* tf = dynamic_cast<TransistorFamily*>( device ); TransistorFamily* tf = dynamic_cast<TransistorFamily*>( device );
if (tf) _gridLabel[i+5]->setDynamicText ( QString("%1" ).arg( tf->getNfing() ) ); cerr << "tf:" << tf << endl;
if (tf) {
_gridLabel[i+5]->setDynamicText ( QString("%1" ).arg( tf->getNfing() ) );
i++;
}
} }
i++;
} }
} }

View File

@ -1,6 +1,6 @@
# -*- mode: CMAKE; explicit-buffer-name: # "CMakeLists.txt<crlcore/doc/crlcore>" -*- # -*- mode: CMAKE; explicit-buffer-name: # "CMakeLists.txt<crlcore/doc/crlcore>" -*-
set ( htmlInstallDir share/doc/coriolis2/en/html/crlcore ) set ( htmlInstallDir share/doc/coriolis2/en/html/doc/crlcore )
set ( latexInstallDir share/doc/coriolis2/en/latex/crlcore ) set ( latexInstallDir share/doc/coriolis2/en/latex/crlcore )
set ( doxExtras closed.png set ( doxExtras closed.png
open.png open.png

View File

@ -54,7 +54,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -92,7 +92,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -59,7 +59,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -66,7 +66,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -123,7 +123,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -98,7 +98,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -60,7 +60,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -80,7 +80,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -93,7 +93,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -68,7 +68,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -64,7 +64,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -53,7 +53,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -118,7 +118,7 @@ Static Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -87,7 +87,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -923,7 +923,7 @@ Static Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -56,7 +56,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -175,7 +175,7 @@ Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -67,7 +67,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -495,7 +495,7 @@ Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -60,7 +60,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -292,7 +292,7 @@ Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -71,7 +71,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -763,7 +763,7 @@ Static Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -86,7 +86,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -846,7 +846,7 @@ Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -96,7 +96,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -1136,7 +1136,7 @@ Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -54,7 +54,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -127,7 +127,7 @@ Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -68,7 +68,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -451,7 +451,7 @@ Static Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -70,7 +70,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -682,7 +682,7 @@ Static Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -64,7 +64,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -452,7 +452,7 @@ Static Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -56,7 +56,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -190,7 +190,7 @@ Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -64,7 +64,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -198,7 +198,7 @@ Static Public Member Functions</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -73,7 +73,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -53,7 +53,7 @@ Directories</h2></td></tr>
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -49,7 +49,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -49,7 +49,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -61,7 +61,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -72,7 +72,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -54,7 +54,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -48,7 +48,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -68,7 +68,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -62,7 +62,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -57,7 +57,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -55,7 +55,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -91,7 +91,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -54,7 +54,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

View File

@ -588,7 +588,7 @@ $(function() {
<hr> <hr>
<table class="footer1"> <table class="footer1">
<tr> <tr>
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Oct 28 2019</small></td> <td class="LFooter"><small>Generated by doxygen 1.8.14 on Mon Feb 3 2020</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td> <td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr> </tr>
</table> </table>

Some files were not shown because too many files have changed in this diff Show More