From: Konrad Rosenbaum Date: Fri, 8 Feb 2013 14:44:32 +0000 (+0100) Subject: enable proper symbol export X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=0a683074184e5382d187651c1972712491326161;p=web%2Fkonrad%2Fpack.git enable proper symbol export --- diff --git a/Makefile b/Makefile index 4540e33..bda871d 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ woc: vinfo/staticVersion.h cd woc && $(QMAKE) CONFIG+=woc $(MAKE) -C woc -qtbase: +qtbase: woc cd qtbase && $(QMAKE) $(MAKE) -C qtbase diff --git a/doc/wolf.html b/doc/wolf.html index 7d60e50..efad70d 100644 --- a/doc/wolf.html +++ b/doc/wolf.html @@ -78,6 +78,8 @@ The QtServerOutput tag tells woc to create a generator for a Qt based server, th With both Qt bases outputs you can optionally specify a shareObjects attribute - if present it contains the class prefix for communication objects. If that prefix is different from the one given as classPrefix woc will assume that some other output will create those objects and not create them in this output. This feature is meant for the case in which client and server reside in the same translation unit and share the same objects (transactions and interfaces can unfortunately not be shared).

+Another optional attribute is enableExport - set it to "yes" to enable export of the generated symbols in case you compile them into a DLL and want users of that DLL to be able to use the generated classes in their code. Set it to "no" to hide those symbols ("no" is the default).

+ The PHPServerOutput tag tells woc to create a generator for a PHP based server. The "extension" attribute tells woc which file extension to use for the generated files (default is .php). Woc will automatically create a "autoload" (plus extension) file that should be included from the main body of the PHP project to load the automatically generated classes. The transactionBase attribute allows to chose an extended class as base class of generated transactions - it is recommended to overwrite some protected functions in order to be able to get more information inside transactions.

The HtmlOutput tag tells woc where to generate API documentation. This target generates generic high level documentation for all configured tables, classes, and transactions. Use doxygen or a similar tool to generate language target specific documentation.

diff --git a/qtbase/include/exception.h b/qtbase/include/exception.h index 172ec11..76b72b0 100644 --- a/qtbase/include/exception.h +++ b/qtbase/include/exception.h @@ -9,7 +9,11 @@ #include -class WException +#ifndef WOLF_BASE_EXPORT +#define WOLF_BASE_EXPORT Q_DECL_IMPORT +#endif + +class WOLF_BASE_EXPORT WException { protected: WException(QString e,QString c){err=e;comp=c;} diff --git a/qtbase/include/helper.h b/qtbase/include/helper.h index ed6d8bf..df24b21 100644 --- a/qtbase/include/helper.h +++ b/qtbase/include/helper.h @@ -13,7 +13,11 @@ class QDomElement; class QDomNode; -class WHelper:public QObject +#ifndef WOLF_BASE_EXPORT +#define WOLF_BASE_EXPORT Q_DECL_IMPORT +#endif + +class WOLF_BASE_EXPORT WHelper:public QObject { protected: /**helper for de-serializers: returns direct child elements with given tag name (necessary because QDomElement::elementsByTagName traverses all children)*/ diff --git a/qtbase/include/interface.h b/qtbase/include/interface.h index 8085a1f..daf4503 100644 --- a/qtbase/include/interface.h +++ b/qtbase/include/interface.h @@ -20,8 +20,12 @@ class QNetworkReply; class WServerRequest; class WServerReply; +#ifndef WOLF_BASE_EXPORT +#define WOLF_BASE_EXPORT Q_DECL_IMPORT +#endif + /// base class of all interfaces -class WInterface:public QObject +class WOLF_BASE_EXPORT WInterface:public QObject { Q_OBJECT Q_PROPERTY(QUrl url READ url) diff --git a/qtbase/include/nullable.h b/qtbase/include/nullable.h index c447f2f..3927476 100644 --- a/qtbase/include/nullable.h +++ b/qtbase/include/nullable.h @@ -7,8 +7,12 @@ #ifndef WOLF_NULLABLE_H #define WOLF_NULLABLE_H +#ifndef WOLF_BASE_EXPORT +#define WOLF_BASE_EXPORT Q_DECL_IMPORT +#endif + ///special class for Null values -class NullValue +class WOLF_BASE_EXPORT NullValue { public: NullValue(){} @@ -28,7 +32,7 @@ class NullValue const NullValue nullval; /**wrapper around scalar values that makes them NULL-able, i.e. the virtual value NULL is added to the range of the wrapped value; wrapped classes must have a default constructor and =, == and != operators*/ -templateclass Nullable +templateclass WOLF_BASE_EXPORT Nullable { public: /**creates a NULL value*/ @@ -93,9 +97,9 @@ Q_DECLARE_METATYPE(Nullable) Q_DECLARE_METATYPE(Nullable) Q_DECLARE_METATYPE(Nullable) -inline bool operator==(Nullable i1,int i2){return i1.operator==(i2);} -inline bool operator==(Nullable i1,int i2){return i1.operator==(i2);} -inline bool operator==(Nullable i1,int i2){return i1.operator==(i2);} -inline bool operator==(Nullable i1,unsigned int i2){return i1.operator==(i2);} +inline WOLF_BASE_EXPORT bool operator==(Nullable i1,int i2){return i1.operator==(i2);} +inline WOLF_BASE_EXPORT bool operator==(Nullable i1,int i2){return i1.operator==(i2);} +inline WOLF_BASE_EXPORT bool operator==(Nullable i1,int i2){return i1.operator==(i2);} +inline WOLF_BASE_EXPORT bool operator==(Nullable i1,unsigned int i2){return i1.operator==(i2);} #endif diff --git a/qtbase/include/object.h b/qtbase/include/object.h index 37de42c..391baee 100644 --- a/qtbase/include/object.h +++ b/qtbase/include/object.h @@ -19,7 +19,7 @@ class QScriptValue; class QScriptEngine; /**base class of all web based objects*/ -class WObject:public WHelper +class WOLF_BASE_EXPORT WObject:public WHelper { protected: WObject(){} @@ -32,7 +32,7 @@ class WObject:public WHelper }; /**this exception is thrown if the deserialization of an object fails on the XML parser level*/ -class WDeserializerException:public WException +class WOLF_BASE_EXPORT WDeserializerException:public WException { public: WDeserializerException(QString e):WException(e,"Deserializer"){} diff --git a/qtbase/include/server.h b/qtbase/include/server.h index 2e69b67..6921a17 100644 --- a/qtbase/include/server.h +++ b/qtbase/include/server.h @@ -15,8 +15,12 @@ class QTcpServer; class QLocalServer; class WInterface; +#ifndef WOLF_BASE_EXPORT +#define WOLF_BASE_EXPORT Q_DECL_IMPORT +#endif + ///Encapsulates the request as it comes in via (S)CGI -class WServerRequest +class WOLF_BASE_EXPORT WServerRequest { public: ///instantiates an empty request @@ -63,7 +67,7 @@ class WServerRequest Q_DECLARE_METATYPE(WServerRequest); ///reply object for the server side: contains the data sent back to the client -class WServerReply +class WOLF_BASE_EXPORT WServerReply { public: ///creates an invalid reply (500 Server Error) @@ -96,7 +100,7 @@ class WServerReply * * Use the cgi2scgi helper to translate between CGI and SCGI. */ -class WServer:public QObject +class WOLF_BASE_EXPORT WServer:public QObject { Q_OBJECT public: diff --git a/qtbase/include/transaction.h b/qtbase/include/transaction.h index d0d51f1..e4f902f 100644 --- a/qtbase/include/transaction.h +++ b/qtbase/include/transaction.h @@ -17,7 +17,7 @@ class WTransaction_Private; /**base class of all transactions*/ -class WTransaction:public WHelper +class WOLF_BASE_EXPORT WTransaction:public WHelper { Q_OBJECT Q_ENUMS(Stage) diff --git a/qtbase/include/transaction_p.h b/qtbase/include/transaction_p.h index a0705ac..1dacc9c 100644 --- a/qtbase/include/transaction_p.h +++ b/qtbase/include/transaction_p.h @@ -109,7 +109,7 @@ class WTransaction::LogWrap{ WTransaction*parent; }; -class WTransaction_PrivateBase { +class WOLF_BASE_EXPORT WTransaction_PrivateBase { private: int refctr; protected: diff --git a/qtbase/wbase.pro b/qtbase/wbase.pro index d740ecf..39a0f99 100644 --- a/qtbase/wbase.pro +++ b/qtbase/wbase.pro @@ -5,15 +5,19 @@ TEMPLATE = lib TARGET = qwbase DESTDIR = ../qtbase -CONFIG += dll create_prl separate_debug_info +CONFIG += dll create_prl separate_debug_info hide_symbols QT += xml network QT -= gui OBJECTS_DIR = .ctmp MOC_DIR = .ctmp RCC_DIR = .ctmp +#no version info yet, TODO: fixme VERSION = +#make sure symbols are exported: +DEFINES += WOLF_BASE_EXPORT=Q_DECL_EXPORT + HEADERS += \ include/nullable.h \ include/helper.h \ diff --git a/woc/qt/qtclass.cpp b/woc/qt/qtclass.cpp index 74ee73b..26ae801 100644 --- a/woc/qt/qtclass.cpp +++ b/woc/qt/qtclass.cpp @@ -46,6 +46,7 @@ void WocQtClass::newClass(const WocClass&cls) //lead in hdr.write(QByteArray(HDRSTART).replace("%",cna.toLatin1())); src.write(QByteArray(SRCSTART).replace("%",cna.toLatin1())); + hdr.write(m_parent->exportLines()); QString hcd; QString scd; @@ -59,7 +60,7 @@ void WocQtClass::newClass(const WocClass&cls) //class declaration QString cnb=cls.baseClass(m_parent->languageSpec(),m_parent->namePrefix()+"O"); hcd+=doxyFormat(cls.docStrings()); - hcd+="class "+cna+":public "+cnb+"\n{\n Q_OBJECT\n"; + hcd+="class "+m_parent->exportSymbol()+" "+cna+":public "+cnb+"\n{\n Q_OBJECT\n"; hdr.write(hcd.toLatin1()); //enums diff --git a/woc/qt/qtctrans.cpp b/woc/qt/qtctrans.cpp index d20bd0b..f6b4b0f 100644 --- a/woc/qt/qtctrans.cpp +++ b/woc/qt/qtctrans.cpp @@ -88,6 +88,7 @@ void WocQtClientTransaction::newTransaction(const WocTransaction&trn) //lead in hdr.write(QByteArray(HDRSTART).replace("%",cn.toLatin1())); src.write(QByteArray(SRCSTART).replace("%",cn.toLatin1())); + hdr.write(m_parent->exportLines()); //start constructing code @@ -96,7 +97,7 @@ void WocQtClientTransaction::newTransaction(const WocTransaction&trn) //start of class ct.hcd+="\nclass "+cnp+";\n"; ct.hcd+="\n"+doxyFormat(trn.docStrings()); - ct.hcd+="class "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n"; + ct.hcd+="class "+m_parent->exportSymbol()+" "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n"; ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n"; //create properties diff --git a/woc/qt/qtout.cpp b/woc/qt/qtout.cpp index f36cdcd..cbd0d30 100644 --- a/woc/qt/qtout.cpp +++ b/woc/qt/qtout.cpp @@ -28,6 +28,7 @@ WocQtOut::WocQtOut(QDomElement&el) m_cprefix=el.attribute("shareObjects",m_prefix); m_transbase=el.attribute("transactionBase","WTransaction"); m_genscript=str2bool(el.attribute("scriptable","0")); + m_export=str2bool(el.attribute("enableExport","0")); //get/create directory QDir d(m_basedir+"/"+m_subdir); if(!d.exists())QDir(".").mkpath(m_basedir+"/"+m_subdir); @@ -41,6 +42,8 @@ WocQtOut::WocQtOut(QDomElement&el) } m_pri.write(QByteArray("#AUTOMATICALLY GENERATED FILE - DONT CHANGE!\n")); m_pri.write(QByteArray("INCLUDEPATH += ")+m_subdir.toLatin1()+QByteArray("\n")); + if(m_export) + m_pri.write(QByteArray("DEFINES += ")+exportSymbol().toLatin1()+QByteArray("=Q_DECL_EXPORT\n")); //create interface class WocProcessor*woc=WocProcessor::instance(); @@ -61,10 +64,11 @@ WocQtOut::WocQtOut(QDomElement&el) m_iface.write(QByteArray(HDRSTART).replace("%",m_prefix.toLatin1()+"INTERFACE_H")); m_iface.write(QByteArray("#include \"WInterface\"\n")); m_iface.write(QByteArray("#include \n")); + m_iface.write(exportLines()); if(m_genscript) - m_iface.write(QByteArray("class QScriptEngine;\n")); + m_iface.write(QByteArray("class ")+exportSymbol().toLatin1()+QByteArray(" QScriptEngine();\n")); addIfaceHeaderClass(doxyFormat(pn+" interface class.")); - addIfaceHeaderClass(QString("class "+ifaceClassName()+":public WInterface\n{\n Q_OBJECT\n")); + addIfaceHeaderClass(QString("class "+exportSymbol()+" "+ifaceClassName()+":public WInterface\n{\n Q_OBJECT\n")); addIfaceHeaderClass(QString(" public:\n "+ifaceClassName()+"(QString name=\""+pn+"\"):WInterface(name){}\n")); addIfaceHeaderClass(" /// convenience override: returns a pointer to an instance with the given name if it is of the correct type, otherwise nullptr\n"); addIfaceHeaderClass(" static "+ifaceClassName()+"*instance(QString name=\""+pn+"\")\n\t{return qobject_cast<"+ifaceClassName()+"*>(WInterface::instance(name));}\n\n"); @@ -348,3 +352,29 @@ void WocQtOut::addIfaceImpl ( const QString& s ) { m_ifacecpp.write(s.toLatin1()); } + +QByteArray WocQtOut::exportLines() const +{ + if(!m_export)return QByteArray(); + QByteArray ret="\n#ifndef "+exportSymbol().toLatin1()+ + "\n#define "+exportSymbol().toLatin1()+" Q_DECL_IMPORT\n" + "#endif\n\n"; + return ret; +} + +QString WocQtOut::exportSymbol() const +{ + if(!m_export)return QString(); + if(m_exportsym.isEmpty()){ + m_exportsym="WOBGEN_"; + QString r=WocProcessor::instance()->projectName(); + r+="_"+m_subdir; + for(auto c:r.toUpper()){ + if(c>='A' && c<='Z')m_exportsym+=c; + else if(c=='_')m_exportsym+="__"; + else m_exportsym+="_"+QString::number((unsigned char)c.toLatin1(),16); + } + m_exportsym+="_EXPORT"; + } + return m_exportsym; +} diff --git a/woc/qt/qtout.h b/woc/qt/qtout.h index 4a674fb..16a277f 100644 --- a/woc/qt/qtout.h +++ b/woc/qt/qtout.h @@ -116,6 +116,11 @@ class WocQtOut:public WocOutput ///returns the base class of all transactions inline QString transactionBase()const{return m_transbase;} + ///returns some lines of code to define an export symbol + QByteArray exportLines()const; + ///returns the name of the preprocessor symbol used for export + QString exportSymbol()const; + private: ///internal: init the scripting env void initScripting(); @@ -124,7 +129,8 @@ class WocQtOut:public WocOutput private: QString m_basedir,m_subdir,m_prefix,m_cprefix,m_transbase,m_postiface,m_scriptcode; - bool m_clean,m_genscript; + mutable QString m_exportsym; + bool m_clean,m_genscript,m_export; MFile m_pri,m_iface,m_ifacecpp,m_hdr; QString m_iface_prefix,m_iface_class; protected: diff --git a/woc/qt/qtstrans.cpp b/woc/qt/qtstrans.cpp index 386ebb0..aeeddcf 100644 --- a/woc/qt/qtstrans.cpp +++ b/woc/qt/qtstrans.cpp @@ -72,6 +72,7 @@ void WocQtServerTransaction::newTransaction(const WocTransaction&trn) //lead in hdr.write(QByteArray(HDRSTART).replace("%",cn.toLatin1())); src.write(QByteArray(SRCSTART).replace("%",cn.toLatin1())); + hdr.write(m_parent->exportLines()); //start constructing code @@ -79,7 +80,7 @@ void WocQtServerTransaction::newTransaction(const WocTransaction&trn) genInclude(ct); //start of class ct.hcd+="\nclass "+cnp+";\n"; - ct.hcd+="\nclass "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n"; + ct.hcd+="\nclass "+m_parent->exportSymbol()+" "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n"; ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n"; //create properties