Can you use macros defined in static libraries?
I have my own debug macro called TWDEBUG that I use in a static library I create for sharing.
If I import the static library to my new project and use it, the compiler does not seem to recognize it. I did set up preprocessor macros to TWDEBUG and Other C flags and Other C++ flags to -TWDEBUG, but when I ran the code the ifdef macro doesn't get executed.
Macros are evaluated at compile-time. So their values are frozen when you build the static library. For debugging statement, this usually means that they are omitted and not part of the built library.
If you later add the static library to a project, you can change the value of the macros. But it won't have any effect on the static library since it is not compiled anymore. The debugging statements are missing.
Update:
So to implement a debug option, I see two options:
Instead of macros and ifdefs, you use a global variable and proper ifs to turn debugging on and off. Other developers can use an API (global function) to set the debugging level so you can hide the global variable.
Create two static library from the same source code, one with debugging enabled for development purposes and the other with debugging disabled for production use. This option is probably only viable if XCode can automatically switch between the two libraries. And at the moment, I don't know how you would configure that.
Related
What is the difference between **.dll and **d.dll?
Does mean dynamic such as a dynamic module?
Or definitely having different contents?
if **d.dll mean dynamic module Can I use opencv_world440.dll to static link?
The *d.dll is compiled in Debug mode -> therefore its unoptimized and you can place breakpoints in it.
The *.dll is built in release mode and IS optimized -> therefore its recommended for production.
This specifier and dynamic/static linkage have nothing to do with each other!
I have a problem that I haven't been able to resolve in regards to when I link my iOS App against one or more static libraries. Here is the issue:
I am creating several static libraries (MACH-O type: Relocatable Object File) each of which contain a large number of symbols. Each of these static libraries are FAT libraries, containing a slice for each iOS/Simulator architecture. From my understanding, when I compile my iOS Application only the symbols that are used by my App should be compiled into and included in my App, however, ALL of the symbols are being included.
I've done some testing using otool, nm, and other tools and can see that when I link against any of these libraries, even if I don't call any of the code in the libraries, ALL of the symbols are being compiled into the App. It takes my App from 42kB all the way to 3+MB.
Any ideas on why this is happening?
Objective-C is a dynamic runtime; it is permissible e.g. to perform:
NSString *classToUse = ["MPViewController" stringByAppendingString:class];
return [[NSClassFromString(classToUse) alloc] init];
... and furthermore this is more or less exactly what happens when you load a NIB — string class and property names are loaded from disk, the backing classes are then found via the runtime and properties applied by key-value coding. So dynamic lookup is not an edge case.
A linker can therefore not make any assumptions about which symbols are used from an Objective-C static library, unlike e.g. a C linker.
Yes,It can be done by stripping static libraries, but if post-processing is enabled. Set Xcode build setting "Deployment Postprocessing" to yes. (DEPLOYMENT_POSTPROCESSING=YES). Also make sure that "Use separate strip" is set to Yes. You can check this
You can also achieve what you are expecting by using Dynamic Library, there is a very nice article here
Extra Tip
* While creating library set Debug Symbols to NO in your build settings. This can reduce the size of your static library by up to 30%.
I did quite a bit of googling for a definitive answer, but I could not find one.
We have cross-platform sources that need to be used by our iOS apps. I have already packaged them as static framework and got a test app to link successfully against and make a call into it.
The problem I am having is that it makes heavy use of global static constructors.
I am seeing erratic behavior with only a subset of objects getting instantiated but not all.
My questions:
Do static constructors even work within the context of an iOS static
lib?
How would one debug such a problem?
Thanks!
constructors in a static library get called erratically
The use of -all_load and -force_load does not make any difference in invocation of constructor attribute labeled functions
What you need to do is this:
make sure the constructors are global symbols. do this by exporting them via a symbols' file.
consider creating an init function and use the linker setting "initialization routine" to control the order of the instantiation of your global objects..
Do static constructors work within the context of an iOS static lib?
They only start to work once they're linked into an executable, but once that is accomplished they will work.
How do you debug such a problem
There are a few approaches
You have to presume no specific order of the invocation of the constructors.
Make sure the constructors are being linked into the executable (use nm to determine this)
You can try an -Wl,-all_load to get it to load all the components of all archives into the executable (or -Wl,-force_load,libstatic.a to just load for a specific static archive).
I've built a static library that I'm my iOS binary is linking in. Code stripping is off, etc. for the static library, and I can see the symbols in the archive (via nm).
So, I link that library into my application as a framework. But, I'm not actually calling that function directly. As a result, I can see the symbols that I'm calling directly in my binary, but not the ones that aren't called. But, since I actually want these symbols to be there at runtime, I'm compiling with -all_load.
But, this seems to place an unnecessary burden on the users of the library. Is there something I can add in the static library that enforces this, rather than relying on the user of the library?
Depending on what you are trying to accomplish, you can precisely control which symbols are dead-stripped and which are always loaded, even if the user of the library doesn't actually use them.
The easiest way is to create a library initialization function that references the exact symbols you don't want dead-stripped. This is precise, and saves you the burden of wrestling with the linker command-line options, which may insulate you from (unlikely) tool behavior changes down the road.
Frameworks have automatic initializers (quite handy) that can be called automatically when the framework is loaded at runtime, right after any static variables are initialized.
__attribute__((constructor))
static void MyModuleInitializer()
{
static BOOL initialized = NO;
if (!initialized) {
// References to symbols that should be kept around.
initialized = YES;
}
}
Just for grins, automatic finalizers are also supported using the __attribute__((destructor)) decorator.
Is there a way to add some uncompiled source code (in an NSString for example) and conditionally modify it and execute it at runtime?
Why not provide two frameworks or static libraries, one pre-compiled for use with CoreDate, and one for without?
Have you considered using the runtime methods to determine whether CoreData methods are available rather than using preprocessor macros?