I was just browsing swift-corelibs-foundation by accident (to see something totally unrelated) and I just ran into how it solves the issue. It uses a linker feature I did not even know existed to use a "symbol alias list". It does exactly what I'd wondered if it were possible – mapping an actual class symbol (their "NSCFConstantString") into __CFConstantStringClassReference.
It passes `-Wl,-alias_list,SymbolAliases` to the linker, and `SymbolAliases` contains https://github.com/apple/swift-corelibs-foundation/blob/19249417b01573bd6aa32b9a24cc42273315a48b/CoreFoundation/Base.subproj/SymbolAliases#L4. Any change CoreBase could make use of this? -- Daniel. On Wed, Jun 28, 2017 at 9:30 AM, Stefan Bidigaray <stefanb...@gmail.com> wrote: > Hi Daniel, I guess I should throw my 2 cents in as I know the hacks I had to > do in CoreBase in order to get constant CFStrings. > > The files of interest will be Source/GSPrivate.h and > Source/CFConstantString.c in the CoreBase sources. > > GSPrivate.h defined a macro called CONST_STRING_DECL() that creates a > constant string structure with the *isa = NULL. CoreBase is able to deal > with the *isa pointer being NULL, but not it being a pointer to a structure > that is "malformed". > > At runtime, it mimics I had to mimic what the libobjc's did and assign the > correct *isa for each string. This requires having a complete list of all > constant strings and initializing them one-by-one at library load time. This > is done in CFConstantString.c. The CFConstantStringInitialize() function is > called by CFInitialize() when the library is loaded. I thought about doing > what you're suggesting, somehow making a point to _OBJC_CLASS_* structures, > but that ended up being a dead-end and not worth pursuing. > > Unfortunately, I had to make CoreBase somewhat dependent on various > implementation details, for many reasons. In this case, library load times > are important, since libobjc and -base need to be up and running before > CFConstantStringIntialize() is called. The problem with using > __builtin_CFStringMakeConstantString() is that it is equivalent to @"", and > this was a problem for me at the time because it would cause the toll-free > bridging mechanism to be constant called, unnecessarily. > > As you'll quickly see, all this stuff is private to CoreBase, so you'd > either have to expose this functionality or come up with your own constant > string solution. I wouldn't have a problem exposing it, even though I would > rather keep my messy hacks "private". > > I think I should also mention that there is nothing in CoreBase that makes > it inherently dependent on -base or libobjc. At the time I was still > actively working on CoreBase, the need arose for a pure-C base library that > was familiar to me. Since I had already done some work with GNUstep and > understood the paradigms it made sense to make this so. That was around the > time I reimplemented all the toll-free bridged CF-types in C instead of > relying on -base's implementations. By modifying the makefile, you can still > built a pure-C version on CoreBase, by the way. I'd like to keep it that > way. > > Hope this helps! And I apologize for taking so long to reply to your email. > > Regards > Stefan > > On Tue, Jun 27, 2017 at 8:19 PM, Daniel Ferreira (theiostream) > <bnm...@gmail.com> wrote: >> >> Hmm, bad news about this. >> >> Here's the commit that enables this feature on CoreBase, for some >> context on what I'll discuss next: >> >> https://github.com/theiostream/corebase/commit/98d799a6de056f1b99fa9a218a0f354f613ba578. >> >> Sadly, simply switching CFSTR() from __CFStringMakeConstantString() to >> __builtin___CFStringMakeConstantString() doesn't just work >> out-of-the-box. Both clang and gcc generate, out of that builtin, a >> struct that "fits" into CFStringRef's spec, but there is one tricky >> detail. Its "isa" member is set on compile-time to a pointer tracked >> by the __CFConstantStringClassReference symbol. >> >> The symbol itself would not be a problem. We could just point it on >> compile-time to null bytes and pretend that never existed (as Apple >> seems to do on CFLite). But CoreBase totally relies on that "isa" >> member having something meaningful, and it'll pretty much always >> forward that null "isa" to libobjc2 to try to figure out the CFType of >> that constant string. This broken "isa" will crash libobjc2. >> >> That said, I need a way to place a valid Objective-C class definition >> in that symbol on compile-time (probably it'd be an empty subclass of >> NSCFString), but I'm totally unaware of any way to do that. Or maybe >> make that point to an ordinary _OBJC_CLASS_* symbol somehow. Any >> hints? >> >> Otherwise, the other way I can see to implement this is to check if >> the "isa" member is a pointer to __CFConstantStringClassReference >> every time we try to do something with it. But that'd require a bunch >> of changes to CoreBase, Base, and would likely leave behind a lot of >> bugs, so I'm really not into this. >> >> Also, Apple's "workaround" on CFLite and CFNetwork for compilers that >> don't support this builtin is to simply build the CFString struct by >> hand -- still relying on __CFConstantStringClassReference as an isa. >> So that'd break CoreBase as well. >> >> If we choose not to implement this right now due to the complexity >> being too large, I suppose I *can* export these constant strings as >> Objective-C string literals. But it'd still be weird for a CF-only >> library to rely on ObjC to export its CFStringRefs. :( >> >> -- Daniel. >> >> On Tue, Jun 27, 2017 at 6:32 PM, Ivan Vučica <i...@vucica.net> wrote: >> > The test should be done similarly, though: test for the feature rather >> > than the compiler. >> > >> > On Tue, Jun 27, 2017 at 9:15 PM, Fred Kiefer <fredkie...@gmx.de> wrote: >> >> I agree that we should add this feature, but from looking at the actual >> >> code I don’t think it will help us. >> >> The feature seems to be only present in gcc on Darwin with the Next, >> >> that is old Apple ObjC, runtime. We should rather be looking for a way to >> >> convince the gcc people to enable this on more platforms. >> >> This shouldn’t be much of a limitation for Daniel as he will be using >> >> clang anyway. >> >> >> >> Fred >> >> >> >> >> >>> Am 27.06.2017 um 19:34 schrieb Ivan Vučica <i...@vucica.net>: >> >>> >> >>> It seems sane, and you should update corebase's autoconf to detect >> >>> presence of this compiler built-in. >> >>> >> >>> That is: an installed header should be generated and contain a >> >>> constant describing whether CFStringMake...() is present. >> >>> >> >>> On June 27, 2017 5:32:04 PM GMT+01:00, "Daniel Ferreira (theiostream)" >> >>> <bnm...@gmail.com> wrote: >> >>> Hi, >> >>> >> >>> I'm currently working on developing a CoreFoundation-based library >> >>> with CoreBase, and I just realized that unlike in OSX, CFSTR() does >> >>> not generate a compile-time CFStringRef constant. >> >>> >> >>> This is fine compatibility-wise since CFSTR() does not guarantee that >> >>> it will do so -- in fact, Apple's own CoreFoundation headers check if >> >>> we are on Linux and if that is the case, it does not enable this >> >>> compile-time feature. >> >>> >> >>> However, as far as my (extremely brief) investigation went we can >> >>> generate compile-time CFStringRefs using >> >>> __builtin___CFStringMakeConstantString(), which is present since this >> >>> gcc commit[1] and since forever in clang. So it makes sense to me that >> >>> this should not be platform-dependent, but rather compiler-dependent. >> >>> >> >>> This helps because I need to export some CFStringRefs as symbols in a >> >>> new lib for WebKit compatibility, and without this feature I'd be left >> >>> with the option to either: >> >>> a) create an Objective-C file in a C-only library just for exporting >> >>> NSStrings; >> >>> b) make a bizarre __attribute__((constructor))-like thing to >> >>> initialize the constant strings onto the symbols on library load. >> >>> >> >>> Does this seem sane? If so, I need a tip in how to guard for this >> >>> builtin in gcc. >> >>> >> >>> -- Daniel. >> >>> >> >>> [1]: >> >>> https://github.com/gcc-mirror/gcc/commit/d4238e8bcce578381de9480d78a651830a8f9754, >> >>> looks like it was added in gcc 5.3. >> >>> >> >>> >> >>> Gnustep-dev mailing list >> >>> Gnustep-dev@gnu.org >> >>> https://lists.gnu.org/mailman/listinfo/gnustep-dev >> >>> >> >>> -- >> >>> Sent from my Android device with K-9 Mail. Please excuse my brevity. >> >>> _______________________________________________ >> >>> Gnustep-dev mailing list >> >>> Gnustep-dev@gnu.org >> >>> https://lists.gnu.org/mailman/listinfo/gnustep-dev >> >> >> >> >> >> _______________________________________________ >> >> Gnustep-dev mailing list >> >> Gnustep-dev@gnu.org >> >> https://lists.gnu.org/mailman/listinfo/gnustep-dev >> > >> > _______________________________________________ >> > Gnustep-dev mailing list >> > Gnustep-dev@gnu.org >> > https://lists.gnu.org/mailman/listinfo/gnustep-dev >> >> _______________________________________________ >> Gnustep-dev mailing list >> Gnustep-dev@gnu.org >> https://lists.gnu.org/mailman/listinfo/gnustep-dev > > _______________________________________________ Gnustep-dev mailing list Gnustep-dev@gnu.org https://lists.gnu.org/mailman/listinfo/gnustep-dev