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!
Related
I'd created a custom framework in iOS, with swift4 in Xcode 9.2. The framework contains 9 .swift files, when I tried to archive and create a .framework file, the resultant shows a size of 5MB. However, the 9swift files totally shows a file size of just 72KB. The archived, .framework file is too big in size(5 MB) which my client doesn't agree with.
I'd tried to remove the unwanted code but still the size remains the same, they want me to make it like that of Android framework, which is just 34KB of size. This is the first time I'm creating a framework and I'm out of solutions, can someone help me to reduce the size of the framework without reducing the files?
There are two things I've tried and it has worked for me. Maybe it can also be useful for you.
The linker exports all the symbols by default. You can limit that through some techniques discussed in this article about Symbol Visibility. Also, there is a nice feature in the linker that allows you specify with symbols must be exported or not exported. Exporting only the interface symbols might help you reduce size and your client not waste memory.
So, in practice:
Considering that my framework archive is MyFramework.framework.
I've listed all symbols of MyFramework.framework/MyFramework by running $ nm -g MyFramework.framework/MyFramework and selected the symbols that my binary needed to export (symbols my client would need to access).
All selected symbols were saved in a text file. So assuming that among all the symbols listed, you'll need to save to the text file only the ones you need (your client needs).
Open MyFramework project and set Build Settings -> Exported Symbols File to point to the text file you just created.
With the binary in hands, you can strip some symbols using strip -N MyFramework.framework/MyFramework.
In my case I could achieve something good but I think it might change from project to project. Also, I was dealing with Objective-C. I made a sample Swift project with the results achieved. You can check it out at https://github.com/gbazilio/ios-framework-size.
Hope it helps for you as it did for me.
I have code for a VST plugin and need to port some of it to an iOS app.
I have tried building the OSX version and using the lib.a and it doesnt work. When I open the iOS version of it, Xcode shows that it is missing the tagret.
If I copy the code directly into Xcode with all the JUCE modules, and I set the header search paths, I get compilation errors on things like no such type for String
After this latest JUCE update, Xcode would give the same errors until I updated the JUCE file itself, so I think the JUCE build settings or configuration of the new version is doing something differently. How can I get this code into a different Xcode project, so that I can use it?
Can I compile it as a library and use the objects through the header?
JUCE is designed to be included in projects generated by the Introjucer / Projucer (the JUCE project management tool). Without this, the correct preprocessor definitions will not be set up.
If you really needed to include JUCE source code inside your program, you could manually set up these preprocessor definitions (take a look at the AppConfig.h header from a generated project to get an idea of how much work this will be), but you'd really be going against the normal "JUCE way".
Simply including the headers and linking against the library will not work without considerable effort, as the include structure is ... odd ... and there isn't any library to link against directly anyway (the generated projects contain all the JUCE source normally, so there's no need).
Adding the JUCE source files (i.e. .cpp and .mm) to be compiled in a project directly will result in compilation errors, as they need to be compiled in a very specific order which is mandated by the header file (the header files #include certain implementation files after setting up their dependencies).
In short, if you can at all I would advise generating the project with the Projucer and adding other source files in as you need them, rather than the other way around.
I have created a static library and added it to my project, when i try to debug my application it goes to the .m file of the library. If this library is distributed to some one he will also be able to see code in that library which is blunder, how should i get rid of this.Are there any settings that are to be changed?
If you don't distribute the source file, they cannot see the source file. They may be able to see symbols within the library, such as function or method names, if you don't strip the binary after building it. There is a setting in the "Build Settings" of the project and target settings where you can turn stripping on or off. I believe that it's on for debug and off for release by default.
I'm having trouble linking to a static library in Xcode 5. I did read the chapter on building and using a static library in the Pro iOS 5 Tools. What it told me to do after creating your static library, was to link against the framework in the Build Phases tab. That part is pretty straight forward. Then it says in the Build Settings, under "Header Search Paths", to add:
$(BUILT_PRODUCTS_DIR)
Then in order to use my static library, I just import it like so:
#import "ConversionCalculator/ConversionCalculator.h"
So this used to work up until yesterday. I tried adding a new static library to my project which didn't seem to work. So I cleaned my project, and tried rebuilding again, but now Xcode complains about #import "ConversionCalculator/ConversionCalculator.h". It says
Lexical or Preprocessor issue. 'ConversionCalculator/ConversionCalculator.h' file could not be found.
I was wondering if anyone has any tips on debugging this. I've looked through different tutorials like this:
http://blog.stevex.net/2012/04/static-libraries-in-xcode/
http://cocoamanifest.net/articles/2011/06/library-management-with-xcode-workspaces.html
http://www.raywenderlich.com/41377/creating-a-status-library-in-ios-tutorial
But I can't seem to find the "golden way" to link to a static lib, or how to troubleshoot why Xcode cannot find my file. My file structure is setup on my machine like so:
Projects\
DistanceCalculator\DistanceCalculator.xcodeproj
ConversionCalculator\ConversionCalculator.xcodeproj
DistanceCalculator.workspace
Like I said, this all used to work too when I followed the tutorial in Pro iOS 5 Tools book. Now I don't know why my workspace cannot find ConversionCalculator when it has used it before. The part I find hard is different articles say different things about the header search path, and I'm not sure what the best way to populate that field is. Any thoughts? Thanks in advance!
Edit:
I'll add that I can build for the device without errors. But when I switch to the iPhone simulator, it gives me that error about not being able to find the file. I also see that I get this warning:
ConversionCalculator was rejected as an implicit dependency for 'libConversionCalculator.a' because its architectures 'i386' didn't contain all required architectures 'i386 x86_64'
Looking at that, I'm not sure what that means. If it means that my library is not being built for all architectures, I just tried creating a Target that builds for all architectures according to the wenderlich article in the above link. That seems to work as when I go to the dervieddata folder, I see for debug, release, and universal, I see the libConversionCalculator.a file. But then when I go back into the workspace and try to rebuild the project for the simulator, I get that could not find file error and the implicit warning.
Edit #2:
I just saw a warning flag on Xcode that says upgrade to recommended Build Settings. Now I get no errors. Not sure what happened... but I guess no errors is good.
I would follow the description available in Xcode's Help topic "Linking Against Your Library" in chapter Configuration Your Application in Introduction to Using Static Libraries in iOS
(you may search within Xcode Help, too).
Except that I would recommend to include your headers from libraries always using angle brackets:
#import <ConversionCalculator/ConversionCalculator.h>
Using double quotes may inadvertently search and find files with the same name in some sub-folder relative to the file where this import directive is written. Only after there was no file in any sub-folder the preprocessor starts searching with the specified header search paths.
Using angle brackets, the preprocessor immediately searches only at the specified header search paths.
So, since you actually want to find headers for the corresponding library, always use angle brackets.
Note: If you follow the recommendation to create a static library project, you don't need to explicitly set a header search path in the target that links agains the library: Xcode will already add a search path:
$(BUILT_PRODUCTS_DIR)/includes
Your library headers are located in
$(BUILT_PRODUCTS_DIR)/includes/<product-name>
which are placed there through the "Copy-Files" phase of the iOS static library target, whose "Destination" is set to "Products Directory" and whose "Subpath" is set to "includes/${PRODUCT_NAME}" per default.
You may change these default settings to other reasonable and sensible values. (if you do, consider the the consequences for Xcode's default search paths!)
I am testing an image capture library that sent over their code library as a regular header file and a file ending in a "*.a" extension. I am not familiar with using a file in this format and can't seem to find the right "magic" to search for.
What does this file extension stand for?
What if any extra steps are needed to get it integrated with my XCode project?
Maybe a bit more of theory can get you in the right track so you'll know how to search next time:
.a files are archives of object (.o) files. These object files are generally produced by an assembler, compiler, or other language translator; They contain machine code that is usually not directly executable, but are used by linker tools to generate an executable or yet another library by combining parts of these object files.
Another important thing you should know is that since these files contain machine code, they must have been compiled for the correct architecture you're targeting for (ex.: armv7, i386, etc). That can be the reason why sometimes you will be able build your project for one device but not to another if you don't have the right set of files for the targeted platform (e.g. iPhone simulator vs. actual iPhone).
It is also possible to have "universal binaries", which are files that in turn package together archives of object files (.a) for different architectures (e.g. using tools such as lipo), so that the same library file can be given to the linker for multiple architectures. Or, you may have a different linker configuration for each target (e.g. using conditional build settings in XCode). All of these files can be analyzed with certain tools (e.g. "file", "otool", "lipo -info", etc), and each has several parameters to play with. Debuggers will also check the symbols within these files for their own purposes.
When you drag the '.a' file to your project's directory within Xcode, you can notice that it will automatically add this file to the list of "Link Binary With Libraries" items under your target's "Build Phases".
Since the header files allows us to separate certain elements of a program's source code into reusable files, that commonly contain forward declarations of classes, subroutines, variables, and other identifiers that are needed for reference during the compilation step, it is common to have libraries provided as archives of compiled objects (.o) in ".a" files along with their respective headers. For instance, as soon as you include the headers files in your XCode project, the editor will provide auto-complete for these new functions.
Sometimes, you might also consider having the actual source code of the library instead of binaries inside your project as this * might * make debugging easier in case an unexpected behavior is happening inside that "library" package. Many times this is not an option though (when you have no access to the sources) when the binary distribution is made in purpose to hide implementation details (commercial libraries).
.a stands for archive. It is also known as a static library. I believe you should be able just to drag it and the header files into Xcode. Xcode should pick up the right thing to do from its extension.
Example, see appr. from 30 sec here
http://memention.com/ac3dreader/usage/quickstart.html
Another example from Google Analytics, under Setup
Drag GANTracker.h and libGoogleAnalytics.a from the SDK's Library directory into your new project.
https://developers.google.com/analytics/devguides/collection/ios/devguide