enable proper symbol export
authorKonrad Rosenbaum <konrad@silmor.de>
Fri, 8 Feb 2013 14:44:32 +0000 (15:44 +0100)
committerKonrad Rosenbaum <konrad@silmor.de>
Fri, 8 Feb 2013 14:53:27 +0000 (15:53 +0100)
16 files changed:
Makefile
doc/wolf.html
qtbase/include/exception.h
qtbase/include/helper.h
qtbase/include/interface.h
qtbase/include/nullable.h
qtbase/include/object.h
qtbase/include/server.h
qtbase/include/transaction.h
qtbase/include/transaction_p.h
qtbase/wbase.pro
woc/qt/qtclass.cpp
woc/qt/qtctrans.cpp
woc/qt/qtout.cpp
woc/qt/qtout.h
woc/qt/qtstrans.cpp

index 4540e33..bda871d 100644 (file)
--- 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
 
index 7d60e50..efad70d 100644 (file)
@@ -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 <tt>shareObjects</tt> attribute - if present it contains the class prefix for communication objects. If that prefix is different from the one given as <tt>classPrefix</tt> 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).<p>
 
+Another optional attribute is <tt>enableExport</tt> - 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).<p>
+
 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 <tt>transactionBase</tt> 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.<p>
 
 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.<p>
index 172ec11..76b72b0 100644 (file)
@@ -9,7 +9,11 @@
 
 #include <QString>
 
-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;}
index ed6d8bf..df24b21 100644 (file)
 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)*/
index 8085a1f..daf4503 100644 (file)
@@ -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)
index c447f2f..3927476 100644 (file)
@@ -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*/
-template<class T>class Nullable
+template<class T>class WOLF_BASE_EXPORT Nullable
 {
        public:
                /**creates a NULL value*/
@@ -93,9 +97,9 @@ Q_DECLARE_METATYPE(Nullable<quint64>)
 Q_DECLARE_METATYPE(Nullable<QString>)
 Q_DECLARE_METATYPE(Nullable<QByteArray>)
 
-inline bool operator==(Nullable<qint64> i1,int i2){return i1.operator==(i2);}
-inline bool operator==(Nullable<quint32> i1,int i2){return i1.operator==(i2);}
-inline bool operator==(Nullable<quint64> i1,int i2){return i1.operator==(i2);}
-inline bool operator==(Nullable<quint64> i1,unsigned int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<qint64> i1,int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<quint32> i1,int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<quint64> i1,int i2){return i1.operator==(i2);}
+inline WOLF_BASE_EXPORT bool operator==(Nullable<quint64> i1,unsigned int i2){return i1.operator==(i2);}
 
 #endif
index 37de42c..391baee 100644 (file)
@@ -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"){}
index 2e69b67..6921a17 100644 (file)
@@ -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:
index d0d51f1..e4f902f 100644 (file)
@@ -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)
index a0705ac..1dacc9c 100644 (file)
@@ -109,7 +109,7 @@ class WTransaction::LogWrap{
                WTransaction*parent;
 };
 
-class WTransaction_PrivateBase {
+class WOLF_BASE_EXPORT WTransaction_PrivateBase {
        private:
                int refctr;
        protected:
index d740ecf..39a0f99 100644 (file)
@@ -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 \
index 74ee73b..26ae801 100644 (file)
@@ -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
index d20bd0b..f6b4b0f 100644 (file)
@@ -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
index f36cdcd..cbd0d30 100644 (file)
@@ -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 <QStringList>\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;
+}
index 4a674fb..16a277f 100644 (file)
@@ -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:
index 386ebb0..aeeddcf 100644 (file)
@@ -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