Xcode 8 Swift 3 Undefined symbols for architecture armv7 - swift

As I'm not allowed to add an answer to several duplicated questions, I will ask this question and give also one answer ;-)
The undefined symbol was a call to a self written swift function. This function sits in an swift file with only "global" functions (no class in that file). The function is called from several classes and all was good until this morning.
Suddenly I got this link-error message when producing the release product. The funny think was, it was only for ONE function call. All other calls got no errors, and when I commented out this particular function call, all was good. And this function is a very easy one. There is only one function parameter (Int64) and it returns a CLocationCoordinate2D.
I checked all possible solutions found here and at other places in the web. I even copied the function 1:1 as a local function inside the class.. nothing worked.
The final solution was the compiler flag for optimization. For release builds the flag in "Swift Compiler - Code Generation" is set to "Fast, Whole Module Optimization".
After changing that to "Fast, Single Module Optimization", everything worked ...
I think it is simply a bug in the optimization engine.
.. maybe that will help others in similar situations.

Related

How to avoid not used function to be wiped out by optimizer

While compiling and Xcode swift project for MacOS, not used functions are removed from the binary (removed by the optimizer I guess). Is there a way to tell the compiler to not remove unused functions, perhaps with a compiler option (--force-attribute?) so that even with optimization enabled those functions remain in the binary?
I know that if a global function is declared as public (public func test()) then it's not removed even if not used (Since it can be used by other modules), but I can't use public since that would export the symbol for that function.
Any suggestion?
If this is indeed removed by the optimiser, then the answer is two-fold.
The optimiser removes only things that it can prove are safely removable. So to make it not remove something, you remove something that the optimiser uses to prove removability.
For example, you can change the visibility of a function in the .bc file by running a pass that makes the functions externally callable. When a function is private to the .bc file (also called module) and not used, then the compiler can prove that nothing will ever call it. If it's visible beyong the .bc file, then the compiler must assume that something can come along later and call it, so the function has to be left alive.
This is really the generic answer to how to prevent an optimisation: Prevent the compiler from inferring that the optimisation is safe.
Writing and invoking a suitable pass is left as an exercise for the reader. Writing should be perhaps 20 lines of code, invoking… might be simple, or not, it depends on your setting. Quite often you can add a call to opt to your build system.
As I discovered, the solution here is to use a magic compiler flag -enable-private-imports (described here: "...Allows this module's internal and private API to be accessed") which basically add the function name to the list #llvm.used that you can see in the bitcode, the purpose of the list is:
If a symbol appears in the #llvm.used list, then the compiler,
assembler, and linker are required to treat the symbol as if there is
a reference to the symbol that it cannot see (which is why they have
to be named)
(cit.) As described here.
This solves my original problem as the private function even if not used anywhere and not being public, during compilation is not stripped out by the optimiser.

Swift Xcode 11 breakpoints for conditionals do not work

I am trying to add a Symbolic Breakpoint in XCode to check for UI engine modifications on the background thread.
What I am doing is the following:
However, the error message I am getting back is always:
Stopped due to an error evaluating condition of breakpoint 5.1: "!Thread.isMainThread"
Couldn't parse conditional expression:
error: use of undeclared identifier 'Thread'
UI Engine must be modified on main thread.
I do not understand why the breakpoint condition cannot evaluate my condition. Can someone explain what I may be doing wrong here? I have tried putting that in Obj-c as well, to no luck.
EDIT: Obj-C version, here: !(BOOL)[NSThread isMainThread]
EDIT 2: Xcode version Version 11.3 (11C29)
EDIT 3: Ok, so, closing XCode and reopening has gotten the Obj-C version "working" they pause on a breakpoint for something like, 4-5 minutes each time. This effectively makes these breakpoints unusable. Not sure how to resolve this.
I was able to get your original symbolic breakpoint working as expected by writing the condition as
(BOOL)[NSThread isMainThread] == NO
I suspect there's a better way, and comparing a BOOL directly to NO is very bad style, but at least it got me past the "doesn't work" stage to the "does work" stage.
To clarify, setting symbolic breakpoints and using conditions DOES work, but
I would hazard that self and Thread are not available as symbols for much of the UIKit framework because there is no debugging information available for most of it, hence the error: use of undeclared identifier 'Thread'.
See the answer in this post:
How to log out self when add a symbol breakpoint at -[UIViewController viewWillAppear] method
There is also additional info about creating symbolic breakpoints for child classes and a possible workaround using an objective-c condition here:
Using of symbolic breakpoints for child classes in Xcode?
That being said, if you are only interested in particular classes in your modules where that method (layoutSubviews) is invoked, you can specify the module inside your symbolic breakpoint, and if you have your own implementation of that method (e.g. you have overridden it in your class code), the condition Thread.isMainThread or !Thread.isMainThread will in fact work for that class.
I know this may not in fact solve your dilemma, especially if you need to check all the invocations of layoutSubviews, but I hope it at least helps to explain why a condition using Thread does not work all the time.

Swift 3 (Omit Needless Words) causing two functions to have the same name

In Swift 3.0, the automated changing of function names due to the "Omit Needless Words" rule has caused two functions in an ObjC class to be the same.
- (void)showLoader;
...and...
- (void)show __deprecated_msg("User 'showLoader'");
The problem is that these functions are within a third party Cocoa Pod (otherwise I would just delete the unnecessary 'show' function).
This results in getting the error "Ambiguous use of 'show'" when I try to invoke the function like this:
loader?.show()
Is there a way to reverse the automatic changing of function name in Swift 3.0 or to help the compiler know which function I want to invoke?
Thanks for your help!
See MartinR's answer to my similar question here: Converting to Swift 3 renamed my own Objective-C method
If you owned the code, you could use NS_SWIFT_NAME(showLoader()) after your method declaration to force the ObjC-to-Swift method conversion to be named what you want:
- (void)showLoader NS_SWIFT_NAME(showLoader());
I think it's worth mentioning even though in your case it doesn't exactly solve your problem because you don't own the code.
You can work around this by calling
loader?.perform(Selector("showLoader"))
You will see a warning from the compiler, but it will compile successfully, and things will work correctly at runtime.

Marmalade IwUIController causes crash when accessing IwUIElement objects

I created an app that works which is similar to the examples from the Marmalade SDK. Then I tried to move the IwUIController derived class in a separate files .h/.cpp to clean the code up a bit but I get a crash every time I try to access any IwUIElement? For example:
CIwUIImage* image = IwSafeCast<CIwUIImage*>(pScreen->GetChildNamed("Image"));
pScreen is declared as
static CIwUIElement *pScreen;
and then in main(): pScreen = CIwUIElement::CreateFromResource("Screen");
What can be the reason for these crashes? Does the Controller class need to be in the same file as main()? I've tried to debug and the pointer appears to be passed properly.
Not sure it really counts as an answer, but I don't have enough stackoverflow reputation to comment apparently;-)
If you've got C++ code that worked OK until you split it into two files, I would seriously check the #include and other declarations are the same in the new two files as they were in the originals. 9 times out of 10, my experience is that for some reason something is not the same. Actually one specific issue worth checking for is that a struct or class is only partly declared (e.g. a forward declaration) in one file and has lost its parent.
Having said that, as Creator, said what were the symptoms of the crash? Is this possibly the dynamic cast failing of IwSafeCast failing?

MS VS-2005 Compiler optimization not removing unused/unexecuted code

I have a workspace built using MS-Visual Studio 2005 with all C code.In that i see many functions which are not called but they are still compiled(they are not under any compile time macro to disable them from compiling).
I set following optimization settings for the MS-VS2005 project to remove that unused code:-
Optimization level - /Ox
Enable whole program optimization - /GL
I tried both Favor speed /Ot and Favor Size /Os
Inspite of all these options, when i see the linker generated map file, I see the symbols(unsed functions) names present in the map file.
Am I missing something? I want to completely remove the unused code.
How do I do this?
The compiler compiles C files one-at-a-time. Therefore, while compiling a C-file that does contains an unused function, the compiler cannot be sure that it will not be called from another file and hence it will compile that function too. However, if that function were declared as static (file-scope), then the compiler would know it is not used and hence remove it.
Even with whole program optimization, I think it would still not be done since the compilation could be for a library.
Linkers do something similar to what you are looking for. If your code links against a library containing multiple objects, then any objects that do not contain functions used by your code (directly or indirectly) would not be included in the final executable.
One option would be to separate your code into individual libraries and object files.
PS - This is just my guess. The behavior of the compiler (with whole program optimization) or linker essentially depends on the design choices of that particular compiler or linker
On our projects we have a flag set under the project properties\Linker\Refrences. We set it to Eliminate Unreferenced Data (/OPT:REF), according to the description this is supposed to remove function calls or data that are never used. I am just going by the description, I have never tested this or worked with it. But I just happened to see it within the last hour and figured it might be something you could try.