How can I use llvm-ar generated archive file? - clang

llvm-ar archives several LLVM bitcode files into a single archive library that can be linked into a program. The archive operation works as expected. Aslo, it is possible to use llvm-nm to show all the symbols in the generated archive.
However, I noticed the generated archive can not be used by the other standard llvm tools, for example, llc, lli and llvm-link directly.
In order to use the generated archived file, I have to extract all the bitcode files from the archived file and then use them directly by llc.
Questions:
Is there some more elegant or efficient way to use the generated archived file by llvm-ar?
Could clang use bitcode archived file directly as below:
// assumes hello.bc is valid bitcode file and it is built successfully
clang-3.8 -o main main.c hello.bc
// ar hello.bc into lib libhello.bca
llvm-ar-3.8 rcs libhello.bca hello.bc
llvm-nm libhello.bca // has below output
hello.bc:
---------------- T outupt
U puts
clang-3.8 -o main main.c libhello.bca // has below error
libhello.bca: error adding symbols: File format not recognized
clang: error: linker command failed with exit code 1 (use -v to see invocation)

LLVM tools like llc, lli, opt and others can't operate on bitcode archives directly. You have to unpack it before running them. Alternatively, you can link archive items into one single bitcode file, but that's not the same as having the archive, so it depends if that suits you.
As for clang, you can pass bitcode archives along with source files and libraries, and it will do the correct thing - unpack it, run passes, compile to object file and link into the final binary.

Related

Will the compiler strip the unrelated arch symbols from dependent static library in product binary file?

I'm a new in framework development, here is my case. I build a private static library to provide it to the vendors to link it.
Currently, I build my library with arch armv7 and arm64 only, this should be work for vendors to debug it in iOS device and archive their apps, but not for debugging in iOS Simulator. The simulator needs the x86_64 ( and even i386 in iPhone 5 Simulator). It isn't friendly to disable the ability to debug it in a simulator. I'm considering to provide a fat architecture of static library for them.
Here is the action
lipo -create libSignatureLibary_armv6.a libSignatureLibary_armv7.a libSignatureLibary_i368.a -output libSignatureLibary.a
After the merge operation, the output library has a double size than the single one.
The question is, will the compiler/Xcode strip the i386 and x86_64 arch symbols from final app product binary? If not, the fat arch library will increase the product app's size directly, right? Should I build two versions of the library for vendors, one for debugging, another for archiving? What's the right solution for this case?
I don't know what keywords I should research, I didn't have an existing product app linking it to verify this, either. (Maybe I should build a new later.)
Don't worry, the linker only uses the .o (relocatable object file, it is the output file of assembler, when you build a static library, a .m file will be translated to a .o file. The static library is a collection of relocatable object files) files for target arch in the static library, so it will strip the x86_64 and i386 .o files when building product binary.
Also the linker won't link the .o file which is not referenced directly or indirectly by compiled files into executable file.

Using scan-build command for clang code analysis

I have installed scan-build/clang version 2.9 on Ubuntu desktop. I build my C++ source code there using make . As it said scan-build would analyze a project which is built using make if you give
scan-build make
to
but after the make i see a message
scan-build: Removing '/tmp/scan-build-2013-10-16-1' because it contains no reports.
Also tried
scan-build --use-c++=/use/bin/clang++ make
Q1 - What am i doing wrong/missing here. How to use scan-build to analyze all source files.
Q2 - Is there any option to use clang++ --analyze myfile.cpp
to analyze single source file. But it gives an error about a header file included not found 'fatal' error' my.h
what is the option to clang analyze to point it to the folder having header files.
As for Q2, you should be able to use:
scan-build clang++ -c myfile.cpp
or what you suggested:
clang++ --analyze myfile.cpp
but you need to make sure that the compiler knows about all the includes and libraries (you should be able to successfully compile myfile.cpp to an object file without analysis). That includes especially the -I directories.
There is also the -o option to scan-build, which specifies the target directory for HTML report files. Subdirectories will be created as needed to represent separate "runs" of the analyzer. If this option is not specified, a directory is created in /tmp to store the reports, as you already know.
Another useful option would be -v (verbose), which should print any errors that the analyzer might run into.
Last but not least, you should use the analysis with debug builds where the optimization is disabled, but more importantly where the symbols are not stripped.
Not sure if it helps, let me know ...

clang: error: linker command failed with exit code 1, only when testing on device

I was just about to test my app on a device when I ran into this problem, I'm getting this Linker Error.
I've already checked all my compile sources and Build Phases, but there's no sign of my importing things twice.
ld: duplicate symbol _calculateNextSearchPage in /Users/wouter/Sites/test/FastPdfKit.embeddedframework/FastPdfKit.framework/FastPdfKit(FastPdfKit) and /Users/wouter/Sites/test/FastPdfKit.embeddedframework/FastPdfKit.framework/FastPdfKit(FastPdfKit) for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This only happens when testing on a device, not in the simulator.
Alright guys I had the same problem. Seems like I fixed it.
I am using cocapods therefor the described standard procedure can not be properly executed.
Steps to do to properly add FastPDFKit with Cocoapods.
Download FastPDFKit
In your project Add Files to "Your Project"
go to FastPDFKit folder you just have downloaded
locate 1 folder and 1 project file. Press and hold Command key and add these in to your project
FastPdfKit.xcodeproj
FastPdfKit.embeddedframework
(Note: FastPdfKit.embeddedframework is the actual Framework and you
might want to open FastPdfKit.xcodeproj standalone before adding it
to your project, delete FastPdfKit.embeddedframework folder from
your disk and Build FastPdfKit target in the project. You should see
newly created FastPdfKit.embeddedframework folder)
Go to your Project Settings > Your target > Build Phases > Link Binary with Libraries
Make sure FastPdfKit.framework is there.
If not, drag it from the project and put it there.
Clean the project, delete derived data
Add #import <FastPdfKit/FastPdfKit.h> where you need it and you are good to go.
Here is how my Link Binary with Libraries look like
Please let me know if you have any troubles I might've missed something.
Try to delete duplicate files/images which are in target-> Build phase -> Compile files, Copy bundle resources

How to build ASSIMP Library for iOS (Device and Simulator) with boost-library?

I want to use the ASSIMP library http://assimp.sourceforge.net in an iOS project. Unfortunately, I'm not very experienced with makefiles and that stuff, so I need some help.
I've downloaded the sources and first I tried to build with make (in the code-subfolder)
In the makefile I've added INCLUDEFLAGS = -I/Lib because my boost header-files are in /Lib/boost
Executing make static succeeds with some warnings. A static library (.a) is generated.
Then I tried to add the .a-file to my xcode-project and specified the assimp-header folder as additional include directory (Other Search Paths). Linking failed with the message that the library has not the right architecture (i386 required for the simulator)
file libassimp.a outputs: "libassimp.a: current ar archive random library"
How can I build the library for the i386 architcture and for arm6 or arm7, whatever I need on an iOS device?
Is it ok to use the boost-headers only or is it better/necessary to build boost as a library? Currently I'm using boost headers only, which should be fine since boost is a header only library?!
There is also a cmake - makefile (CMakeLists.txt). cmake is the recommended way of building the library but I don't have any experience with cmake.
Or another thought: Is it possible to build a library via xcode?
The final result should be a library for i386, arm6 and arm7 architecture.
What shall I do? And how?
Edit:
I've just discovered that there are the following preprocessor checks in the file aiDefines.h:
#if defined(_MSC_VER)
// See http://msdn.microsoft.com/en-us/library/b0084kay.
# if defined(_M_IX86)
# define ASSIMP_BUILD_X86_32BIT_ARCHITECTURE
# elif defined(_M_X64)
# define ASSIMP_BUILD_X86_64BIT_ARCHITECTURE
# elif defined(_M_IA64)
# define ASSIMP_BUILD_IA_64BIT_ARCHITECTURE
# else
# error unknown architecture
# endif
#elif defined(__GNUC__)
// See http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html.
# if defined(__x86_32__) || defined(__i386__)
# define ASSIMP_BUILD_X86_32BIT_ARCHITECTURE
# elif defined(__x86_64__)
# define ASSIMP_BUILD_X86_64BIT_ARCHITECTURE
# elif defined(__ppc__)
# define ASSIMP_BUILD_PPC_32BIT_ARCHITECTURE
# else
# error unknown architecture
# endif
#else
# error unknown compiler
#endif
Does this mean, it is not possible to compile the ASSIMP library for ARM architecture?
I personally don't do any iOS development, but I know that others have successfully compiled Assimp for their iDevices using Xcode. An Xcode 3 project should be included with the distribution, although I don't know if you can use it without further modification.
The architecture preprocessor defines are currently only used for logging output (in code/Importer.cpp), and support for ARM has been added to trunk in the meantime (r919, to be exact).
I also had a few issues getting assimp to work on iOS devices.
Here's what I did in case anyone is also having similar issues - similar to Artur Sampaio's example above, but with a few differences:
get the latest assimp from https://github.com/assimp/assimp, i.e., git clone git://github.com/assimp/assimp.git
cd into the assimp directory and open up CMakeLists.txt. For some reason, the make file couldn't find my glut and gl libs, so I commented out the lines in CMakeLists.txt that referred to making the samples, i.e., the "IF ( BUILD_ASSIMP_SAMPLES)" block of code. There's probably a simple way to point to these, but since I didn't need the samples I just did commented those lines out.
cd to port/iOS/ and then sudo ./build_ios.sh (it takes a few minutes to compile all 3 versions of the lib).
now if you cd to assimp/lib/ios and lipo -info libassimp.a you will see that the library is a fat file with i386, arm6 and arm7 architectures (and will work on both the simulator and the arm6 or arm7 device).
to get it to work in XCode 4.3.2, drag&drop the libassimp.a file into my project (from the finder). You don't have to actually copy it over to your project directory, it doesn't hurt if you do though.
for some reason, a build will still fail unless you explicitly link to the libz dynamic library. Click the main project from the XCode file list, select TARGETS, then click on the Build Settings tab, scroll down to the Linking section, and then add "/usr/lib/libz.dylib" under "Other Linker Flags".
the current version of assimp on github seems to have restructured the code somewhat, and while all of the examples I tested from the assimp website work, they all require different, or at least renamed, header files:
Here I've commented out the previous names of the headers and below are the new names:
//#include <assimp.hpp> // C++ importer interface
//#include <aiScene.h> // Output data structure
//#include <aiPostProcess.h> // Post processing flags
#include "Importer.hpp"
#include "scene.h"
#include "postprocess.h"
After this point I was able to use assimp on my iPad.
Also, you probably want to make sure that you have uninstalled other versions of assimp before doing this (eg from macports or brew).
I found branch where one guy already changed project setting for your needs. https://github.com/blandinw/assimp/tree/ios-xcode46/doc
What I did was:
download version 1090 of the Assimp repo: http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/?pathrev=1090
unzip
cd ~/Downloads/trunk/port/iOS
sudo ./build_ios.sh
(replace ~/Downloads/trunk with the path to the unzipped folder)
wait...
check libs at ~/Downloads/trunk/libs/ios/
hope that works

Can't compile plcrashreporter in Xcode 4

I can use the prebuilt framework provided on the plcrashreporter project page when compiling for the device, but not for the simulator. I have the same problem described here.
I assume the prebuilt framework does not support the simulator's architecture, so I downloaded out the plcrashreporter source. I opened the Xcode project and selected the CrashReporter-iOS-Simulator > iPhone 4.3 Simulator target. When I try to build the project, I get this error:
libtool: unknown option character `D' in: -D__IPHONE_OS_VERSION_MIN_REQUIRED=30000
I get the same error when I try to build most of the other targets (such as for device).
My next step was to try adding the source files to my project. I no longer have the aforementioned problem; however, I get this error when I try to compile:
fatal error: 'crash_report.pb-c.h' file not found [2]
#import "crash_report.pb-c.h"
^
1 error generated.
Command clang failed with exit code 1
The crash_report.pb-c.h file which is mentioned in the error message simply does not exist; I've searched the plcrashreporter source tree and the internet. Therefore, I have to assume that this file is supposed to be generated somehow, but I cannot figure out how.
(Commenting out the line in PLCrashReport.m on which crash_report.pb-c.h is included results in numerous other compilation errors.)
You are correct in that the file does not exist normally, nor does crash_report.pb-c.c exist, which will be your next error after this one.
The crash_report.pb.h and crash_report.pb.c files are generated at compile time through a build rule. You need to add a custom script to your build process to make them.
First, make sure you have protoc-c in the plcrashreporter folder of your project (plcrashreporter-1.0/Dependencies/protobuf-2.0.3/bin/protoc-c). They buried it deep. This is what your script will be running.
Then find your crash_report.proto file. This is the main input that protoc-c will be using to create your missing files. You can take this directory and put it manually into your script, OR you can make a rule to run the script on every *.proto file. I do the latter.
Then edit your build rules to include a script that runs protoc-c with the flag --c_out="${DERIVED_FILES_DIR}" and your crash_report.proto file as two inputs, this will output crash_report.pb-c.h and crash_report.pb-c.c into the same directory as where your crash_report.proto file is, which should already be accessible in your project.
The build rules in Xcode 4 (and above) are under your project's target's build rules tab. You add a build rule before all your other build rules. Here's what mine looks like in Xcode:
You'll probably have to fiddle with the directory

Resources