• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Vague linkage and RTTI (was LINK_WITH_STANDARD_LIBRARIES = NO)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Vague linkage and RTTI (was LINK_WITH_STANDARD_LIBRARIES = NO)


  • Subject: Vague linkage and RTTI (was LINK_WITH_STANDARD_LIBRARIES = NO)
  • From: Steve Baxter <email@hidden>
  • Date: Tue, 31 Jan 2006 13:54:37 +0000

I'm still battling with this, and trying to understand what the dynamic linker does.

In reading the ABI documentation on vague linkage, it looks like the dynamic linker should coalesce symbols from different bundles as they are loaded. This means that the one-definition-rule should then hold true for the application as a whole:

http://gcc.gnu.org/faq.html#dso

I now export all the symbols from all my plugins, and type_info passed between plugins mostly works - the problem is it doesn't always work. Does anyone know why?

Here is the exact scheme we have:

(a) An executable - this links to a shared framework (b). The executable is very small, it's really just a stub to the framework.

(b) A shared framework.

(c) Plugins - these are loaded by the shared framework using CFBundle. The plugins link to the shared framework, but cannot link to each other. They can however pass data to each other through messaging APIs in the shared framework.

Within this scheme we have a messaging API. Messages are all subclasses of XMessage and are differentiated by RTTI. Messages sent by the framework (b) to plugins (c) work fine, as do messages sent within a plugin. The problem arises when one plugin broadcasts a message to other plugins.

The messages are generally defined completely inline a bit like this:

class XMyMessage : public XMessage
{
	XMyMessage() 		{}

	Data someSortOfPayload;
}

Now, lets say that plugin A broadcasts a message:

SpeakMessage( new XMyMessage() );

This message is passed through our messaging system and is picked up by plugin B:

void B::HandleMessage( const XMessage& inMsg )
{
	if( typeid( inMsg ) == typeid( XMyMessage ) )
	{
		// This is the message we want - do something
	}
}

The problem is that both plugins A and B included XMyMessage as an inline header. They each have their own type_info for that class. In Codewarrior and VC++, type_info is compared by name and so this always works. In GCC, type_info is compared by address - though these types are the same, the type_info objects have different addresses and the comparison fails.

Looking at the ABI documentation, I was expecting the dynamic linker to fix this up. It would see that plugin A defines type_info for XMyMessage and that plugin B defines type_info for XMyMessage and it should then coalesce these together dynamically so that XMyMessage::type_info is defined only once.

Does anyone know why this sometimes works and sometimes doesn't? All my plugins have the same compile and link settings (I use .xcconfig files). Here is nm output for two different plugins that should share the same type_info for a message XDetectFrameGrabbersMessage, but do not:

From A:

000069fc (__TEXT,__const_coal) weak external __ZTS27XDetectFrameGrabbersMessage

From B:

00057064 (__TEXT,__const_coal) weak external __ZTS27XDetectFrameGrabbersMessage

Should I expect the dynamic linker to resolve these properly when the two bundles are loaded?

Cheers,

Steve.

On 27 Jan 2006, at 18:06, Steve Baxter wrote:

Hi,

We have finally come up against a wall in moving our application from CW to Xcode. The problem is that GCC's implementation of RTTI considers the same class defined in two different DSOs to be two different classes. This unfortunately breaks a lot of our code (please no discussions about the wrongs and rights of having the same class in two different DSOs, it happens unavoidably with inline classes and it would be way too much work for us to change this now).

The solution to this is I think to compile libsupc++ with __GXX_MERGED_TYPEINFO_NAMES=0. This reverts GCC back to the old (reliable) behaviour where type_info objects are compared by name() rather than by pointer (this is the behaviour in both VC++ and CodeWarrior as well). So, what I want to do is to link (statically) against my own version of libsupc++. I suspect I will also need to link my own version of libstdc++ as well. I will link these files statically into my shared framework - this way all my plugins will share the right RTTI information.

So:

- I can tell Xcode not to automatically link with standard libraries using LINK_WITH_STANDARD_LIBRARIES = NO. The question is, what are these standard libraries? Can anyone give me a list? A search in Google and the docs for LINK_WITH_STANDARD_LIBRARIES elicits nothing at all! I need to link to my version of libstdc+ +.a, but standard libs for everything else.

- Anyone got any pointers for compiling libstdc++ and libsupc++? I've downloaded the darwin source and tried to make the libs, but I get some errors from make:

steve-baxters-power-mac-g5:/Volumes/Stuff/Users/stevebaxter/Desktop/ gcc-5026.1/libstdc++-v3 stevebaxter$ make
make "AR_FLAGS=" "CC_FOR_BUILD=" "CC_FOR_TARGET=" "CFLAGS=-g -O2" "CXXFLAGS=" "CFLAGS_FOR_BUILD=" "CFLAGS_FOR_TARGET=" "INSTALL=/usr/ bin/install -c" "INSTALL_DATA=/usr/bin/install -c -m 644" "INSTALL_PROGRAM=/usr/bin/install -c" "INSTALL_SCRIPT=/usr/bin/ install -c" "LDFLAGS=" "LIBCFLAGS=" "LIBCFLAGS_FOR_TARGET=" "MAKE=make" "MAKEINFO=/bin/sh /Volumes/Stuff/Users/stevebaxter/ Desktop/gcc-5026.1/missing --run makeinfo " "PICFLAG=" "PICFLAG_FOR_TARGET=" "SHELL=/bin/sh" "RUNTESTFLAGS=" "exec_prefix=/ usr/local" "infodir=/usr/local/info" "libdir=/usr/local/lib" "includedir=/usr/local/include" "prefix=/usr/local" "tooldir=" "gxx_include_dir=/usr/local/include/c++/4.0.1" "AR=ar" "AS=as" "LD=ld" "RANLIB=ranlib" "NM=" "NM_FOR_BUILD=" "NM_FOR_TARGET=" "DESTDIR=" "WERROR=" all-recursive
Making all in include
make[2]: Nothing to be done for `all'.
Making all in libsupc++
make[2]: Nothing to be done for `all'.
Making all in libmath
make[2]: Nothing to be done for `all'.
Making all in src
/bin/sh ../libtool --tag CXX --mode=link g++ -Wl,-single_module - fno-implicit-templates -Wall -Wextra -Wwrite-strings -Wcast-qual - fdiagnostics-show-location=once -ffunction-sections -fdata- sections -DAPPLE_KEYMGR -o libstdc++.la -rpath /usr/local/lib - version-info 6:4:0 -lm bitmap_allocator.lo pool_allocator.lo mt_allocator.lo codecvt.lo complex_io.lo ctype.lo debug.lo debug_list.lo functexcept.lo globals_locale.lo globals_io.lo ios.lo ios_failure.lo ios_init.lo ios_locale.lo limits.lo list.lo locale.lo locale_init.lo locale_facets.lo localename.lo stdexcept.lo strstream.lo tree.lo allocator-inst.lo concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo istream-inst.lo istream.lo locale-inst.lo locale-misc-inst.lo misc-inst.lo ostream-inst.lo sstream-inst.lo streambuf-inst.lo streambuf.lo string-inst.lo valarray-inst.lo wlocale-inst.lo wstring-inst.lo atomicity.lo codecvt_members.lo collate_members.lo ctype_members.lo messages_members.lo monetary_members.lo numeric_members.lo time_members.lo basic_file.lo c++locale.lo ../libmath/libmath.la ../ libsupc++/libsupc++convenience.la -lm
rm -fr .libs/libstdc++.lax
rm -fr .libs/libstdc++.lax
mkdir .libs/libstdc++.lax
rm -fr .libs/libstdc++.lax/libmath.a
mkdir .libs/libstdc++.lax/libmath.a
(cd .libs/libstdc++.lax/libmath.a && ar x /Volumes/Stuff/Users/ stevebaxter/Desktop/gcc-5026.1/libstdc++-v3/src/../libmath/.libs/ libmath.a)
rm -fr .libs/libstdc++.lax/libsupc++convenience.a
mkdir .libs/libstdc++.lax/libsupc++convenience.a
(cd .libs/libstdc++.lax/libsupc++convenience.a && ar x /Volumes/ Stuff/Users/stevebaxter/Desktop/gcc-5026.1/libstdc++-v3/src/../ libsupc++/.libs/libsupc++convenience.a)
-dynamiclib -flat_namespace -undefined suppress -o .libs/libstdc++. 6.0.4.dylib .libs/bitmap_allocator.o .libs/pool_allocator.o .libs/ mt_allocator.o .libs/codecvt.o .libs/complex_io.o .libs/ ctype.o .libs/debug.o .libs/debug_list.o .libs/functexcept.o .libs/ globals_locale.o .libs/globals_io.o .libs/ios.o .libs/ ios_failure.o .libs/ios_init.o .libs/ios_locale.o .libs/ limits.o .libs/list.o .libs/locale.o .libs/locale_init.o .libs/ locale_facets.o .libs/localename.o .libs/stdexcept.o .libs/ strstream.o .libs/tree.o .libs/allocator-inst.o .libs/concept- inst.o .libs/fstream-inst.o .libs/ext-inst.o .libs/io-inst.o .libs/ istream-inst.o .libs/istream.o .libs/locale-inst.o .libs/locale- misc-inst.o .libs/misc-inst.o .libs/ostream-inst.o .libs/sstream- inst.o .libs/streambuf-inst.o .libs/streambuf.o .libs/string- inst.o .libs/valarray-inst.o .libs/wlocale-inst.o .libs/wstring- inst.o .libs/atomicity.o .libs/codecvt_members.o .libs/ collate_members.o .libs/ctype_members.o .libs/ messages_members.o .libs/monetary_members.o .libs/ numeric_members.o .libs/time_members.o .libs/basic_file.o .libs/c+ +locale.o .libs/libstdc++.lax/libmath.a/stubs.o .libs/libstdc+ +.lax/libsupc++convenience.a/cp-demangle.o .libs/libstdc++.lax/ libsupc++convenience.a/del_op.o .libs/libstdc++.lax/libsupc+ +convenience.a/del_opnt.o .libs/libstdc++.lax/libsupc+ +convenience.a/del_opv.o .libs/libstdc++.lax/libsupc++convenience.a/ del_opvnt.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_alloc.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_aux_runtime.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_catch.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_exception.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_globals.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_personality.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_term_handler.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_terminate.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_throw.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_type.o .libs/libstdc++.lax/libsupc++convenience.a/ eh_unex_handler.o .libs/libstdc++.lax/libsupc++convenience.a/ guard.o .libs/libstdc++.lax/libsupc++convenience.a/ new_handler.o .libs/libstdc++.lax/libsupc++convenience.a/ new_op.o .libs/libstdc++.lax/libsupc++convenience.a/ new_opnt.o .libs/libstdc++.lax/libsupc++convenience.a/ new_opv.o .libs/libstdc++.lax/libsupc++convenience.a/ new_opvnt.o .libs/libstdc++.lax/libsupc++convenience.a/pure.o .libs/ libstdc++.lax/libsupc++convenience.a/tinfo.o .libs/libstdc++.lax/ libsupc++convenience.a/tinfo2.o .libs/libstdc++.lax/libsupc+ +convenience.a/vec.o .libs/libstdc++.lax/libsupc++convenience.a/ vterminate.o -lm ../libmath/.libs/libmath.a -lm ../libsupc+ +/.libs/libsupc++convenience.a -lm -lm -lc -Wl,-single_module - install_name /usr/local/lib/libstdc++.6.dylib - compatibility_version 7 -current_version 7.4
../libtool: line 1: -dynamiclib: command not found
make[2]: *** [libstdc++.la] Error 127
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
steve-baxters-power-mac-g5:/Volumes/Stuff/Users/stevebaxter/Desktop/ gcc-5026.1/libstdc++-v3 stevebaxter$


Cheers,

Steve.

Stephen Baxter
Software Development Manager
Improvision
email@hidden
+44-2476-692229


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40improvision.com


This email sent to email@hidden

Stephen Baxter Software Development Manager Improvision email@hidden +44-2476-692229


_______________________________________________ Do not post admin requests to the list. They will be ignored. Xcode-users mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
References: 
 >LINK_WITH_STANDARD_LIBRARIES = NO (From: Steve Baxter <email@hidden>)

  • Prev by Date: Re: xcodebuild, ARCHS and subprojects
  • Next by Date: Re: Removing source code paths from executable
  • Previous by thread: LINK_WITH_STANDARD_LIBRARIES = NO
  • Next by thread: NSBox subclass hangs IB when attempting to add view to the box.
  • Index(es):
    • Date
    • Thread