2

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

我尝试install.txt在 wxHaskell-master.zip 中进行操作,到目前为止我所做的是:

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++ 命令行上给出目标文件的顺序。但这里似乎都不是这样。我尝试删除 functionELJLog::DoLog函数或注释掉 virtual 关键字。奇怪的是,总是有一个链接错误/错误说明 ELJLog 的 vtable,并且指的是 wxLog::DoLog,即使没有出现 DoLog。

此外,作为旁注,wxLog::DoLogwxWidgets 3.0 文档中似乎缺少。我不确定此功能是否已弃用。但是,它仍然以我无法理解的方式导致遗留派生类的错误。

有什么想法吗?

--- 编辑2 ---

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

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

- - 编辑 - -

我在 mingw.org 的 mingw32 下工作。我从源代码构建了 wxWidgets 3.0.0 稳定版本,我做的 stpes 如下:

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/
4

2 回答 2

1

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

  1. 完全删除您现有的来源。
  2. 重新获取它们(并应用 MinGW 修复程序)。
  3. 创建build_shared子目录并在../configure && make && make install那里运行。
  4. 如果这还不够,即如果你真的需要静态库,创建build_static顶级源目录的子目录并在../configure --disable-shared && make && make install那里运行。

如果将来出现任何问题,您总是可以rm -rf build_whatever创建一个新的构建目录并在那里重建(cd build_whatever && make -s clean也可以,但rm -rf更令人满意)。


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


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

如果wxLog::DoLog()库中确实存在(您可以使用nmobjdump检查这个),那么我会检查是否使用过时的 g++#pragma interface#pragma implementation编译指示,因为它们可能导致 IME 损坏。如果您确实在任何地方找到它们,只需将它们完全删除(但将它们都删除,否则您肯定会遇到链接错误)。

于 2014-03-05T15:51:23.327 回答
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);
}
于 2014-03-13T11:08:31.510 回答