添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm getting these non-virtual thunk errors only in the Deployment build of my app. It uses a private framework called Lgi. Building on 10.5.8 using XCode 3.1.4 (latest for leopard?) The error looks like this:

Ld /Users/matthew/Code/Scribe-Branches/v2.00/build/Development/Scribe.app/Contents/MacOS/Scribe normal i386
    cd /Users/matthew/Code/Scribe-Branches/v2.00
    /Developer/usr/bin/g++-4.0 -arch i386 -L/Users/matthew/Code/Scribe-Branches/v2.00/build/Development -F/Users/matthew/Code/Scribe-Branches/v2.00/build/Development -F/Users/matthew/Code/Lgi/build -F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development -F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development -F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment -F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development -F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment -filelist /Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Development/Scribe.build/Objects-normal/i386/Scribe.LinkFileList -framework Carbon -framework Lgi -o /Users/matthew/Code/Scribe-Branches/v2.00/build/Development/Scribe.app/Contents/MacOS/Scribe
Undefined symbols:
  "non-virtual thunk to GWindow::OnDrop(char*, GVariant*, GdcPt2, int)", referenced from:
      vtable for ScribeWndin ScribeApp.o
      vtable for GShutdownin ScribeApp.o
      vtable for CalendarUiin Calendar.o
      vtable for CalendarViewWndin CalendarView.o
      vtable for CalendarConfigin CalendarView.o
      vtable for ScribeExportin Exp_Scribe.o
      vtable for GNewMailDlgin GNewMailDlg.o
      ....etc for lots of classes....

Anyway I know I'm not leaving those undefined because it does in fact link and run fine in the development build. Now after googling the issue the first thing to try is changing the optimization setting, which I did... and no dice. Some link error.

So these virtual functions are initially defined in GDragDropTarget, and GWindow's inheritance looks like this:

class LgiClass GWindow : public GView
#ifndef WIN32
    , public GDragDropTarget
#endif

(LgiClass being for __declspec export/import on win32)

Any ideas on what to try next?

Btw this is some example flags for the framework:

CompileC build/Lgi.build/Deployment/Lgi.build/Objects-normal/i386/GViewCommon.o 
/Users/matthew/Code/Lgi/src/common/Lgi/GViewCommon.cpp normal i386 c++ 
com.apple.compilers.gcc.4_0
cd /Users/matthew/Code/Lgi
/Developer/usr/bin/gcc-4.0 -x c++ -arch i386 -fmessage-length=0 -pipe -Wno-trigraphs 
-fpascal-strings -fasm-blocks -Os -Wreturn-type -Wunused-variable 
-isysroot /Developer/SDKs/MacOSX10.4u.sdk -fvisibility-inlines-hidden 
-mmacosx-version-min=10.4 
-I/Users/matthew/Code/Lgi/build/Lgi.build/Deployment/Lgi.build/Lgi.hmap 
-F/Users/matthew/Code/Lgi/build/Deployment 
-F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks -Iinclude/common 
-Iinclude/mac -Iinclude/posix -I/Users/matthew/Code/Lgi/build/Deployment/include 
-I/Users/matthew/Code/Lgi/build/Lgi.build/Deployment/Lgi.build/DerivedSources/i386 
-I/Users/matthew/Code/Lgi/build/Lgi.build/Deployment/Lgi.build/DerivedSources 
-DMAC 
-include /var/folders/b4/b4LnxwCQGLCmwy36TH3QuU+++TQ/-Caches-/com.apple.Xcode.503/SharedPrecompiledHeaders/Lgi_Prefix-aukthgaeovjxcucuoascfyqekpzz/Lgi_Prefix.pch -c /Users/matthew/Code/Lgi/src/common/Lgi/GViewCommon.cpp 
-o /Users/matthew/Code/Lgi/build/Lgi.build/Deployment/Lgi.build/Objects-normal/i386/GViewCommon.o
Ld /Users/matthew/Code/Lgi/build/Lgi.build/Deployment/Lgi.build/Objects-normal/i386/Lgi normal i386
cd /Users/matthew/Code/Lgi
setenv MACOSX_DEPLOYMENT_TARGET 10.4
/Developer/usr/bin/g++-4.0 -arch i386 -dynamiclib -isysroot /Developer/SDKs/MacOSX10.4u.sdk 
-L/Users/matthew/Code/Lgi/build/Deployment 
-F/Users/matthew/Code/Lgi/build/Deployment 
-F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks 
-filelist /Users/matthew/Code/Lgi/build/Lgi.build/Deployment/Lgi.build/Objects-normal/i386/Lgi.LinkFileList 
-install_name @executable_path/../Frameworks/Lgi.framework/Versions/A/Lgi 
-mmacosx-version-min=10.4 -framework Carbon 
-framework SystemConfiguration -Wl,-single_module -compatibility_version 1 
-current_version 1 -o /Users/matthew/Code/Lgi/build/Lgi.build/Deployment/Lgi.build/Objects-normal/i386/Lgi

And this is the compile/link flags for the application:

    CompileC build/Scribe.build/Deployment/Scribe.build/Objects-normal/ppc/IHttp.o 
/Users/matthew/Code/Lgi/src/common/INet/IHttp.cpp normal ppc c++ com.apple.compilers.gcc.4_0
cd /Users/matthew/Code/Scribe-Branches/v2.00
/Developer/usr/bin/gcc-4.0 -x c++ -arch ppc -fmessage-length=0 -pipe -Wno-trigraphs 
-fpascal-strings -Os -mdynamic-no-pic -DMAC -DSCRIBE_APP -isysroot /Developer/SDKs/MacOSX10.4u.sdk 
-mtune=G4 -fvisibility=hidden -fvisibility-inlines-hidden -mmacosx-version-min=10.4 
-I/Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Deployment/Scribe.build/Scribe.hmap 
-F/Users/matthew/Code/Scribe-Branches/v2.00/build/Deployment -F/Users/matthew/Code/Lgi/build 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment 
-I/Users/matthew/libpng-1.2.37 -I/Users/matthew/jpeg-6b -I../../Lgi/include/common 
-I../../Lgi/include/mac -I../../aspell-0.60.6/interfaces/cc 
-I/Users/matthew/Code/Scribe-Branches/v2.00/build/Deployment/include 
-IResources -I../Lgi/include/common -I../Lgi/include/mac 
-I/Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Deployment/Scribe.build/DerivedSources/ppc 
-I/Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Deployment/Scribe.build/DerivedSources 
-DMAC 
-include /var/folders/b4/b4LnxwCQGLCmwy36TH3QuU+++TQ/-Caches-/com.apple.Xcode.503/SharedPrecompiledHeaders/Scribe_Prefix-ebutivbeomfbzzguhklrzxnwuwzc/Scribe_Prefix.pch 
-c /Users/matthew/Code/Lgi/src/common/INet/IHttp.cpp 
-o /Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Deployment/Scribe.build/Objects-normal/ppc/IHttp.o
Ld /Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Deployment/Scribe.build/Objects-normal/i386/Scribe 
normal i386
cd /Users/matthew/Code/Scribe-Branches/v2.00
setenv MACOSX_DEPLOYMENT_TARGET 10.4
/Developer/usr/bin/g++-4.0 -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk 
-L/Users/matthew/Code/Scribe-Branches/v2.00/build/Deployment 
-F/Users/matthew/Code/Scribe-Branches/v2.00/build/Deployment 
-F/Users/matthew/Code/Lgi/build 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Development 
-F/Users/matthew/Code/Scribe-Branches/v2.00/../../Lgi/build/Deployment 
-filelist /Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Deployment/Scribe.build/Objects-normal/i386/Scribe.LinkFileList 
-mmacosx-version-min=10.4 -framework Carbon -framework Lgi 
-o /Users/matthew/Code/Scribe-Branches/v2.00/build/Scribe.build/Deployment/Scribe.build/Objects-normal/i386/Scribe
Undefined symbols:
"non-virtual thunk to GWindow::OnDrop(char*, GVariant*, GdcPt2, int)", referenced from:
    vtable for ScribeWndin ScribeApp.o
    vtable for GShutdownin ScribeApp.o

I'm not sure whats relevant so I posted them all.

What compiler flags (the ones used to compile the source) are you using for the framework and your app code when the link error subsequently occurs? – ergosys Apr 24, 2010 at 3:10

Found this posting from Matt, presumably someone at Apple: http://lists.apple.com/archives/unix-porting/2003/Dec/msg00107.html

In it, Matt says:

[A non-virtual thunk is] an internal implementation detail used for C++ class hierarchies that involve multiple inheritance. You aren't doing anything wrong; this is a compiler bug. We know that we need to fix it. In the mean time, the best workaround we know of is to use the same optimization level for linking against a library that you used to compile the library.

(You might also consider not exporting a C++ interface from a library. We work very hard to make sure that the C and Objective C ABI stays the same from one compiler release to the next, but we make no such promise for C++.)

      --Matt

So perhaps you are trying to use a C++ library that was compiled by a differently-versioned C++ compiler? The C++ ABI is not defined as portable it seems.

Why not change the compiler flags of your production build to the ones you use for development and then gradually change them back to look like the production flags you use now one at the time until you catch the one that causes the problem?

Then you can look this flag up in the gcc manual and dig deeper.

Turns out the ultimately the _DEBUG define was making the error occur. But I used your comment as a method for isolating the issue. Thx – fret Apr 27, 2010 at 6:18

I've made a tiny example framework and app that follow all the same patterns/class heirarchies that I use in my main app, with a view towards making a simple example of the problem. But that compiled and linked. I couldn't be sure whether that was because I'd cut too much code from it, or because by recreating the project files in the current version of XCode had fixed the problem.

So try and isolate which of those cases was true I re-created my entire framework project from scratch (fast forward some hours) and THAT builds in "Release" (not deployment) mode and links with my app with NO ERRORS! Huh? Ooooooooooooook.

That means that the original project file is broken in some way that isn't easily visible in the options. I diff'd all the options against a newly created project and it's pretty 1:1. Nothing obviously different. So it's something NOT visible in the options file. One problem I did have is not noticing that the project options are actually different to the target options. Now that I know to look in both places I can see where some "user defined" options are getting in the way.

The old project file has been through several OS upgrades and numerous XCode upgrades... I guess it's possible some of the upgrades have conflicted and messed up the project. So thanks for reading and for your comments.

Update: Well after getting "Release" mode to compile, guess what? Yup Debug DOESN'T compile. ARRRRGGGGGGGHHHHH!! So I've copied over all the settings for the framework so that the Debug build is exactly the same as the Release build for both Target and Project. That doesn't link. Work continues...

Turns out that the last difference between the Release and Debug builds of the App, is that I'm defining "_DEBUG" for the debug build. Which switches on various things like asserts and some extra debugging API's. Now I have to work out which of those is causing the link error.

This time I fixed by making the parent class "virtual public" in the child class declaration. – fret Sep 14, 2017 at 6:59

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.