未定义引用wxLog :: DoLog错误构建wxHaskell对wxWidget 3.0

时间:2014-03-05 02:10:22

标签: c++ haskell wxwidgets vtable wxhaskell

我正在尝试为wxWidgets 3.0构建wxHaskell。我使用了来自https://github.com/wxHaskell/wxHaskell的最新git版本的wxHaskell。

我试图在wxHaskell-master.zip中关注install.txt,到目前为止我做的是:

cd wxdirect
cabal install
cd ../wxc
cabal install 

wxc不会编译,因为它的Setup.hs需要wxWidgets 2.9。我换了

let wxRequiredVersion = "2.9"

let wxRequiredVersion = "3.0"

然后做了:

cabal install --extra-lib-dirs=/usr/local/lib

所有编译都没问题,但最后我收到了一些链接错误。最难解决的问题如下:

dist\build\src\cpp\eljlog.o:eljlog.cpp:(.rdata$_ZTV6ELJLog[vtable for ELJLog]+0x20): undefined reference to `wxLog::DoLog(unsigned long, char const*, long)'

相应的源代码位于wxc/src/cpp/eljlog.cpp

class ELJLog : public wxLog
{
    private:
        TLogFunc func;
        void*    EiffelObject;

    protected:
        virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t)
                  {
                    wxString s(szString);
                    func (EiffelObject, (int)level, (void*)&s , (int)t);
                  }
              ....

我无法弄清楚导致此错误的原因以及解决方法。我对这个vtable问题做了一些搜索,有些人认为这是因为在子类中声明虚函数而没有定义它。其他人建议它是在g ++命令行上给出目标文件的顺序。但这似乎都不是这样的。 我尝试删除函数ELJLog::DoLog函数或注释掉虚拟关键字。奇怪的是,总有一个链接错误/错误说明了关于ELJLog的vtable,并引用了wxLog :: DoLog,即使没有出现DoLog。

另外,作为旁注,wxWidgets 3.0文档中似乎缺少wxLog::DoLog。我不确定这个函数是否已被弃用。但是,它仍然以我无法理解的方式导致遗留派生类的错误。

任何想法在这里发生了什么?

--- EDIT2 ---

如果我注释掉有问题的功能

virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t) ...

我得到了不同的链接错误,如下所示:

dist\build\src\cpp\eljlog.o:eljlog.cpp:(.rdata$_ZTV6ELJLog[vtable for ELJLog]+0x
20): undefined reference to `wxLog::DoLog(unsigned long, char const*, long)'
dist\build\src\cpp\eljlog.o:eljlog.cpp:(.rdata$_ZTV6ELJLog[vtable for ELJLog]+0x
24): undefined reference to `wxLog::DoLog(unsigned long, wchar_t const*, long)'
collect2: ld returned 1 exit status

---编辑---

我在mingw32的mingw32下为此工作。我从源代码构建了wxWidgets 3.0.0稳定版本,我所做的工作如下:

per http://mingw.5.n7.nabble.com/win32api-version-4-td32288.html :
 edit line 2217 of /c/mingw/{,mingw32/}include/commctrl.h to read
 #define TV_DISPINFO NMTVDISPINFO
 instead of
 #define TV_DISPINFO __AW(NMTVDISPINFO) 
The above was needed to fix a MinGW32 4.8.1-4 issue. Then,

./configure --enable-stl --disable-shared
make
make install

./configure --enable-stl
make
make install 
mv /usr/local/lib/wx*.dll /c/mingw/bin/

2 个答案:

答案 0 :(得分:1)

现在看到您的构建步骤,我不明白为什么要构建库的静态版本和共享版本。你真的需要他们两个吗?通常只有一个(通常在构建扩展时共享/ DLL)就足够了。如果你确实需要两者,你真的应该在不同的构建目录中构建它们,以避免由于具有旧构建的文件而导致的奇怪的构建问题。所以我建议你做以下事情:

  1. 完全删除现有来源。
  2. 重新获取它们(并应用MinGW修复程序)。
  3. 创建build_shared子目录并在那里运行../configure && make && make install
  4. 如果这还不够,即如果您确实还需要静态库,请创建顶级源目录的build_static子目录并在那里运行../configure --disable-shared && make && make install
  5. 如果将来出现任何问题,您可以随时执行rm -rf build_whatever并创建新的构建目录并在那里重建(cd build_whatever && make -s clean也可以,但rm -rf更令人满意)。


    下面的原始答案:它对其他人仍然有用,但它似乎不适用于您的情况。


    一种可能性是你构建了没有2.8兼容性的wxWidgets。它默认是打开的,所以检查你没有使用--disable-compat28配置选项(我想这是在Unix下?)。

    如果wxLog::DoLog()实际存在于库中(您可以使用nmobjdump来检查),那么我将检查是否使用了过时的g ++ {{1} }和#pragma interface pragma因为它们会导致IME破损。如果你确实在任何地方找到它们,只需将它们完全删除(但要删除它们,否则你肯定会有链接错误)。

答案 1 :(得分:1)

似乎是

的定义
virtual void DoLog(wxLogLevel level, const char *szString, time_t t)
ELJLog的子类wxLog中缺少

。在界面中添加以下DoLog副本只会解决问题:

virtual void DoLog(wxLogLevel level, const char *szString, time_t t)
{
    wxString s(szString);
    func (EiffelObject, (int)level, (void*)&s , (int)t);
}