3 Replies
      Latest reply on May 17, 2019 1:25 AM by eskimo
      amit1990namdev Level 1 Level 1 (0 points)

        Created two frameworks with the same cpp file name and classes name in Xcode,

        Actually, I have to duplicate our codebase using the framework and need to use both the framework in application target which uses objc.

         

        I am able to generate both the frameworks without duplication symbol error and also link with the application target.

         

        But when accessing framework class from application it links to the incorrect framework. below I have explained it.

         

        Let say Framework Name A and B, I am importing framework A in objc class and calling its class and method but it redirects to framework B class and when import framework B in objc class, it redirects correctly to framework B.

        Since both the file name and class name are same but I created a saperate project and folder structure to generate the framework.

        • Re: creating two frameworks with different name for same cpp classes in xcode
          eskimo Apple Staff Apple Staff (11,495 points)

          Are the classes in these framework C++ classes?  Or Objective-C classes?

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: creating two frameworks with different name for same cpp classes in xcode
              amit1990namdev Level 1 Level 1 (0 points)

              Thanks for the reply.

              All classes are CPP classes inside the framework.

                • Re: creating two frameworks with different name for same cpp classes in xcode
                  eskimo Apple Staff Apple Staff (11,495 points)

                  Apple systems use a two-level namespace.  When a client Mach-O image imports a symbol from a shared library, the symbol is referenced by name within that shared library.

                  When you export a C++ class from a Mach-O image, it exports various symbols that are mangled to embed the name of the class.

                  These two factoids combine to determine how C++ linkage works.  When you link the client Mach-O image, the linker finds the first library that exports the class’s symbols.  It then embeds into the client a reference to that library and references to the symbols that make up the class.

                  Note This is in stark contrast to Objective-C, where all classes within a process live within a single flat namespace.

                  The critical thing here is that this resolution happens when you link the client.  After that, the client has a reference to the shared library containing the symbols and that’s what will be used when you load the client.

                  There are two standard tools used for investigating this:

                  • otool -L will show you a list of shared libraries being imported by the client.  For example, this:

                    $ otool -L MyTestTool
                    MyTestTool:
                        /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1570.15.0)
                        /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
                        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)

                    shows that MyTestTool is importing the shared libraries Foundation, libobjc and libSystem.

                  • nm will show you a list of symbols being imported by the client library.  Pass the -m option to see which shared library these are coming from.  For example, in the following:

                    $ nm -m MyTestTool
                                     (undefined) external ___stderrp (from libSystem)
                    0000000100000000 (__TEXT,__text) [referenced dynamically] external __mh_execute_header
                                     (undefined) external _fprintf (from libSystem)
                                     (undefined) external _getprogname (from libSystem)
                    0000000100000ee0 (__TEXT,__text) external _main
                                     (undefined) external _objc_autoreleasePoolPop (from libobjc)
                                     (undefined) external _objc_autoreleasePoolPush (from libobjc)
                                     (undefined) external dyld_stub_binder (from libSystem)

                    imported symbols are those without an address, and for each imported symbol there is both the symbol name and the library in which it’s expected to be found.  As you can see, the fprintf function is being imported from libSystem.

                  You can see this info to confirm which shared library is being referenced by your client.  Once you do that, you can try various things to change that, the most likely candidate being the order in which A and B are presented to the linker.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"