No symbols/source for external library in Xcode 4 - ios

My application is not seeing source code for a library:
If I "Jump to definition" on a library method, XCode takes me to the .h file but says there is no .cpp counterpart
When debugging, I see no source code and most of the call-stack is missing for the library:
I have made sure "Show disassembly when debugging" is UNchecked
I built the library as DEBUG and then packaged up the headers+.a file into a SDK dir. So I guess I need to either copy the debug files into that SDK dir as well, or tell my application where to look. I'm not sure how to do either.
To clarify, my application project doesn't maintain a reference to the library project, only to the .a files and the header dirs. This is because the library project is created by CMake and I don't want to modify it.

First of all, you should check the .debug_str section of your static library to verify it contains the appropriate debug information.
Try running this command on the terminal:
xcrun dwarfdump /path/to/library.a | grep "\.m"
You should see a bunch of your source (.m) file paths printed out. Theoretically, this is where Xcode is going to look when you stop in the debugger, so make sure the paths here are correct. If you don't see any paths, you will need to pass an appropriate debug flag (e.g. -g to the compiler when building your library.
If the paths are somehow incorrect, or you want to point them to some other location, you may be able to modify them as part of the build process in CMake, for example to make them relative to your project directory. Try looking at "Make gcc put relative filenames in debug information", which uses CMake to adjust these debug paths.

Related

Socket.IO error: zlib no such module (Swift 3, Xcode 8.3)

I followed the instructions of Socket.IO's README.md of manually implementing Socket.IO. I dragged in the Source folder into my project and I double-checked to make sure 'Add to target' was selected. When I try to run my project, I get an error 'No such module' because zlib can't be found in Compression.swift. Am I supposed to add any other files or folder to my project? What am I missing here?
Okay, I managed to find the answer on my own, even though the documentation of Socket.IO is very unclear about this and doesn't mention anything about zlib. To import zlib, go to your project's Build Settings and scroll to Swift Compiler - Search Paths. There, you should create a new path by clicking the + in both Release and Debug. Then, add the folder path to the zlib folder that was included in the Github file you downloaded. You can either direct your folder path to its original location inside the Github folder you downloaded, or you can place the zlib folder inside your project folder. It doesn't matter where you leave the folder, as long as you're referring to it correctly. Now, build and run and the No such module error should disappear.
I also got this error when compiling the project after having added socket.io. I fixed it by adding libz.tbd to the Linked Frameworks and Libraries (clicked the + button in the General tab of the target, then I picked it from the list).
After doing that however, I got another error:
No such module 'CZLib'
I'm not sure which version of socket.io I added as I copied the entire folder from one of our previous projects. Anyway, the socket folder had a module.modulemap file which seemed to define the missing module. So I tried to fix the error by adding the socket.io folder containing the module map to the targets Import Paths, found in Build Settings under Swift Compiler - Search Paths.
The project would now compile without errors. At this point I tried to remove the linked libz.tbd and it would still compile. I have still not tried to establish a socket connection, but for now I'm moving forward without linking libz.tbd.

Xcode .pch error while compiling. clang file not found

I have a very annoying problem.
I backed up my code on Dropbox but now i get this error while compiling
clang: error: no such file or directory: '../firstFoo-Prefix.pch'
Since the only .pch file in my project in Xcode and my project folder is secondFoo-Prefix.pch and I don't know how to fix this error I've decided to remove every .pch file so i went into Project> Build Settings and removed everything in the Prefix Header and set Precompile Prefix Header to NO.
Before this the Prefix Header had value secondFoo-Prefix.pch and not firstFoo-Prefix.pch.
Even though the compiler should not look for .pch files I still get that error.
I've looked everywhere in my project but I can't seem to find anywhere firstFoo-Prefix.pch.
Any ideas?
Thank you
This can occur (not your fault) when the Xcode project file database gets messed up such that the referenced file does not appear in the navigation area but is still somehow included in one of the various list of files used for the build phases.
To see if this is the case:
In the Finder, right click on the project file and select 'Show Package Contents'
Right click on the file 'project.pbxproj' and 'Open With->TextEdit.app'
In TextEdit menu: 'Edit->Find->Find...' [or command-F] then enter '.pch'
Look at all occurrences of '.pch' [command -G to move to next one]
If you find occurrences of '../firstFoo-Prefix.pch' then your project file is corrupted. Looking at the context of the occurrence(s) will give you some indication of which area the corruption occurs in (e.g. build phase compile files list).
Sometimes just deleting those references (after having backed-up the project file of course) has worked for us but other times it just makes matters worse. The safest recovery is to create a new project file and copy over all the folder groups and settings manually. Your source code is all fine, it's just the cross-references and build settings that need reworking.
Do a clean for build using this combination: Shift+Option+Command+K
In my case, I have Framework which need to add to main project from derived data after it building successful. So copy items if needed was not tick marked and that's why giving error and also #ZAZ and #chiwangc mentioned cleaned it before building.

iOS static library compiled with Xcode remembers its source files

I compiled a static library for iOS with Xcode with symbols stripped. It's compiled in the Release configuration. When I copy the static library into another iOS project (I physically copy it into another directory), I'm still able to view the source of the static library when stepping through code. I clicked Show in finder in the source window and it pointed me to the appropriate source file on disk.
I opened the library in a hex editor, and it indeed contains paths to my source files on my machine, as well as a bunch of other text data that that shouldn't be exposed.
Have I missed something in my project settings? If this is expected behavior, how can I make sure that the customer will not see the symbols, source file names etc.?
Found the compiler options required.
In LLVM code generation, set Generate debug symbols to No and Symbols hidden by default to Yes. For some reason, even if you tell it to strip symbols, it's not going to do it unless these are set.
You can check whether symbols are striped or not using
nm filename
Stripping doesn't happens automatically, you need to setup xcode to strip them and there are several flags that are in charge:
a) DEPLOYMENT_POSTPROCESSING
Prerequisite for: “STRIP_INSTALLED_PRODUCT (Strip Linked Product).”
b) STRIP_INSTALLED_PRODUCT
This one is going to work in non-appstore builds only if you will have set DEPLOYMENT_POSTPROCESSING to YES.
There is a way to strip symbols manually, just call
strip YOURBINARYNAME
strip YOURBINARYNAME as suggested by #andrei-shender is not enough. You need to do the following:
strip -S YOURBINARYNAME
To get rid of the debugging symbols manually. Of course configuring your project properly is better, but if you are building a 3rd party library using a vendor script you may have to do it manually. Mapbox-native-gl goes from 550mb to 22mb if you strip the debug symbols!

Importing .dylib or .la files into iOS project

After reading this awesome post by Tristan, where he compiled FreeTDS for use in iOS, I attempted to compile UnixODBC for use in iOS. I was able to get it to compile, which is great.
However, when I compiled FreeTDS, I had a .a file that I was able to easily bring into XCode (along with a few .h files). This time, the compiler didn't produce a .a file. Instead, it produced a .la and a .dylib file. So far, I have not been able to use these files in my iOS project.
If I could accomplish any of the following, I think my problems would be solved:
1. Re-compile UnixODBC so that it produces a .a file, or
2. Convert either the .la or .dylib to a .a file, or
3. Import either the .la or .dylib to my project, so I can use it in the same way I would use a .a file.
So far, I am clueless as to how I would do any of these things (or if it's even possible). Can anybody please help me out?
Thank you!
-Rob
.dylib files are dynamically linked libraries, whereas .a files are statically linked ones (just google these two expressions). .la files are irrelevant now, they're not essential, and they don't contain any code,
If the configure script of UnixODBC supports it, you can specify the --enable-static --disable-shared options to enable building an .a archive and not a dylib. If the configure script doesn't accept these flags, then you can just go ahead a compile the source files (it will be done by configure), then instead of taking the resulting dylib, use the ar command to put the .o object files together to form a static archive.

Delphi Search path vs Library Path vs Browsing Path

In Delphi, I can include a folder's source code by adding it to the project Search Path, or adding it to the Library Path. The Search Path applies only to the current project, while the Library Path applies to any project opened with the IDE.
Other than that, is there any functional difference between the Search and Library paths?
My reason for asking: I have a folder X with source used by project A. When I include that folder under Project A's search path, it says it cannot find a specific file in that folder. When I include it under the Library path, then project A compiles fine.
Until now, I was always under the impression that the only difference was that one was project-specific, and the other was global.
While we're on the topic (and at the risk of making a fool of myself): What is the functional difference between "library path" and "browsing path"?
As far as I know, browsing path is where the debugger should look for files when breaking/stepping into source files thats not in the library path.
Lets say that you have a thirdparty component that you use. You point the library path to the directory where the pre-compiled dcu-files of that component are. Your project will use these dcu-files when you compile. This is good, because it wont be recompiled every time you do a build.
But by including the compiled dcu files, you loose the possibility to debug the thirparty component. If you include the path to where the source files are in the browse path, the debugger will find the source, and allow you to step in to it.
The default settings for the vcl show this. In library path they have put $(BSD)\Lib, and in the browsing path they have put $(BDS)\SOURCE\WIN32...
Update: There are two different kind of search paths: Compiler search path and debugger search path. The first is there the compiler looks for files during compiling, and the second is where the debugger looks for source files during debugging.
The compiler will only find files in the Library path or the projects search path.
The debugger will find identifiers in the compilers search path plus the browsing path, the debug source path for the project, and the global debug search path.
There should not be any difference in specifying things globally or pr project.
The “Library path” field
This is the path where the compiler looks for files that it needs when it compiles our project.
There are three main categories of paths that we will find here:
On the first lines we can see listed Delphi’s own precompiled DCUs. We will talk about precompiled DCUs soon.
These paths are added here by Delphi’s installer. Don’t touch them, or you will fuckup the whole Delphi and you will have to reinstall - unless you have a backup of the appropriate registry key, which is: KEY_CURRENT_USER\SOFTWARE\Embarcadero\BDS\21.0\Library\
Next, if you installed 3rd party packages/libraries using their automatic installers, you will see their paths here. Usually, only the folder containing the DCU files (not the Pas files) will be listed here. Here are some examples:
These paths are automatically added by the above-mentioned installers.
If you want to use 3rd party libraries (such as LightSaber) that don’t have an automatic installer, you will have to enter their path manually, as described below (point 3).
Finally, if we built our own library, we would want to manually put the path to this library here.
The “Browsing path” field
If we Ctrl+Click in the IDE on a routine (like Application.ProcessMessages), the IDE will take us to the source code of ProcessMessages which is in:
c:\Delphi\source\vcl\Vcl.Forms.pas
How can the IDE know where to look for Vcl.Forms.pas when the “c:\Delphi\source\vcl” folder is not in Library Path?
This is done by Browsing Path. If we look into the “Browsing Path” we see that the VCL folder is already there:
When the IDE cannot find an identifier (function, variable, etc) in project’s “Search path” it starts to search in “Library path”. If the identifier is also not there, the IDE looks into the Browsing Folder.
It is critical to understand that the folders listed in the “Browsing Path” are accessible to the IDE (and also to the debugger, so we can step into the source code of our libraries while debugging) but not to the compiler.
So, in “Browsing Path” we add the folders that hold units that we want to be able to see/browse with Ctrl+Click in the IDE, but we don’t want to be found by the compiler.
I think Embarcadero team screwed up a bit here. They should have used “Compiler paths” instead of “Library paths” and “IDE paths” instead of “Browsing paths”.
The “Debug DCU path” field
The documentation says, “Specifies the path for the Delphi-compiled units used for debugging”. What it means is that it contains the folder where the Delphi’s debug DCUs are located (see the “Precompiled DCUs” section). We should not touch this.
Usually, we will only have a single folder listed here:
The “Debug source path” field
“Debug source path” is a less obvious place where we can enter paths. Here we enter paths to the Pas files that we have them precompiled to speed up the general compilation speed of your project. Note that this is located under the “Embarcadero debuggers” page and not under the “Library” page:
The “Use debug DCUs” field
Delphi’s units are coming precompiled in two “flavors”: the debug and the release flavor.
So, one might be inclined to think that when we compile our application in Debug mode, the compiler will implicitly use the debug DCUs for RTL/VCL framework. It doesn’t. The compiler will use the debug DCUs for our code, but not the debug DCUs for the RTL/VCL library.
And we can test that easily: we simply build our application in Debug mode and put a breakpoint somewhere in its source code. We will speak about breakpoints and debugging soon. We will see that we can step into our routines when we press the F7 key. But if we try to step into a Delphi routine (let’s say Application.ProcessMessages), we simply can’t. The debugger won’t go in that routine because Delphi compiled the “release” version of Vcl.Forms.pas (the unit where ProcessMessages resides) even if our app was compiled in “Debug” mode.
To force the compiler to link the “debug” version of its VCL/RTL library, we need to activate the “Use Debug DCUs” check box in “Project options”. Careful here! I said, “Project options”, not Delphi’s “Global options”:
When to activate the “Use debug DCUs”?
If “Use Debug DCUs” option is not activated, and we debug our application, we can only single step through our own code. This is what we want in the most cases, because it is our code that is buggy, not Delphi’s code. It will be quite annoying to keep stepping into Delphi’s code.
We activate “Use Debug DCUs”:
• If we want to see how Delphi is working internally – for example, when we want put a break point inside ProcessMessages to see when it is executed.
• If we think we have found a bug in the RTL/VCL
Note: After we activate this option, we need to rebuild our project! For some changes it is enough to compile, but for others it is not enough. I haven't spent the time to make a list about which ones need to compile and which ones need to build. So, as any lazy person, I always Build, after changing project's options.
Debugger will also find files in Library Path.

Resources