Clang: How to see contents of pcm-file - clang precompiled module - swift

I am troubleshooting Swift build compile issues and want to see all C definitions inside pcm file (i.e. /.../sample-package/.build/aarch64-unknown-linux-android/debug/ModuleCache/3H5CVD7WO3N6R/SwiftGlibc-2G37BC3YW3KOQ.pcm).
How to do it? Is the any clang or llvm tool which can dump all symbols defined on C language side and included into precompiled clang module?

Using the command line tool strings
strings file.pcm

With Swift you can use:
swiftc -dump-pcm path/to/foo.pcm -target something ...
Where you do have to pass at least some of the flags you used to compile the module. In my testing you at least need -target and -sdk to be correct.
If you have a pcm generated by clang, you can use:
clang -module-file-info path/to/foo.pcm

Related

use library (gcc) in matlab and error with compile of mex

I am using Mac OSX (yosemite V 10.10.1) and running MATLAB 2014a on it.
I wanted to use SPAM library (sparse modeling software by J. Mairal) on MATLAB and for that I have to install XCode6.1 (that has gcc). First I type in command window mex -setup and result is shown below:
mex -setup
MEX configured to use 'Xcode with Clang' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
variables with more than 2^32-1 elements. In the near future
you will be required to update your code to utilize the
new API. You can find more information about this at:
http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.
To choose a different language, select one from the following:
mex -setup C++
mex -setup FORTRAN
So after that I run the compile.m file in SPAM library and suddenly I saw an error that was:
add_flag =
-mmacosx-version-min=10.6
Warning: Directory already exists.
> In compile at 144
compilation of: -I./linalg/ -I./decomp/ -I./prox/ -I./dictLearn/ dictLearn/mex/mexArchetypalAnalysis.cpp
Building with 'Xcode Clang++'.
clang: warning: argument unused during compilation: '-fopenmp'
Error using mex
ld: warning: directory not found for option '-L/usr/lib/gcc/x86_64-linux-gnu/4.8/'
ld: library not found for -lgomp
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error in compile (line 439)
mex(args{:});
I don't understand what to do. please help me!
It appears that the actual error is occurring at the point of linking with precompiled libraries. The 2 issues are as follows:
The compile code apparently included in the compile.m file looks like it is intended to compile with gcc (it is trying to include files installed by GCC, possibly even linux-specific ones, are you sure that it's an OSX-compatible toolbox?), and yet the error strongly suggests that you are in fact using clang to compile it - you will either need to change the compiler (easy) or rewrite compile.m (not so easy).
One of the libraries that the code needs to have installed in order to be properly linked hasn't been found. On OSX I think this file should be called libgomp.dylib (any mac afficionados want to confirm this?). If you have it on your computer, then it's not in a directory that clang is looking in. You can confirm the library is installed by running find / | grep libgomp.dylib from the terminal - if it is there, you can add it into the compiler argument in compile.m using the -I /DIRECTORY_HOLDING_LIBRARY syntax.
It is entirely possible that fixing 1. will also remediate 2. - I have never tried using SPAM

What predefined macro can I use to detect the target architecture in Clang?

I would like to write code depending on whether the target architecture is e.g. armv7, armv7s, or arm64.
The reason that I can't use sysctlbyname is that this would give me the underlying architecture at runtime, but when arm64 e.g. simulates armv7, sysctl (seemingly) still reports arm64.
Although this is not a 100% answer to the question, but may be useful:
When using clang, you can discern between 32 bit arm and 64 bit arm using:
__arm__ which is defined for 32bit arm, and 32bit arm only.
__aarch64__ which is defined for 64bit arm, and 64bit arm only.
clang --target=... -mcpu=... -E - -dM </dev/null will output all the pre-defined preprocessor macros (similar works for gcc, too)
I don't see single macro that provides the answer, but you can probably use some combination of __ARM_ARCH and defined(__ARM_ARCH_*).
__ARM_ARCH_ISA_A64 is predefined if it's target is arm64,
__ARM_ARCH_7S__ for armv7s,
__ARM_ARCH_7A__ for armv7.
Use: clang -arch arm64 -E -dM - < /dev/null which can output preprocess macro.

Cross-compiling C to armv7 using arm-apple-darwin10-llvm-gcc-4.2

This might seem like a very specific question but central idea is quite broad.
I have a simple hello world console application in C. I've compiled it on Mac OS X using following command:
$ export PLATFORM=/Developer/Platforms/iPhoneOS.platform
$ $PLATFORM/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2 -o hello hello.c -isysroot $PLATFORM/Developer/SDKs/iPhoneOS5.0.sdk/
It compiles successfully but gives this warning:
ld: warning: -force_cpusubtype_ALL will become unsupported for ARM architectures
Now, when I run lipo -info hello I get Non-fat file: hello is architecture: arm
Which specific arm is it and how to compile it to armv7 specifically?
A) "Lipo" is only for fat binaries (that is , multi-architecture). You're running it on a Mach-O file, single architecture. If you tried "file hello" it would tell you "mach-o Executable arm".
B) "arm" is , if memory serves, armv6. You can compile to armv6 by specifying "-arch armv7". You also specify "armv7s" (for Apple A6 devices), and now also arm64 (technically armv8) for 5S/iPad Air/Mini 2. Though technically, all ARM architectures are also v6 compatible, and the v7/v7s only makes a difference for NEON/SIMD instructions.
C) You can compile multiple times for different architectures (even x86_64) with different -arch specifiers, then use lipo -create to fuse all the binaries together to one big binary (hence the name "fat" binary), which would work on all devices.

gcc linker can't find library (openNI)

Can anybody give me some hints for solving this?
I'm trying to compile "Kinect Matlab" (on Mac OS 10.7), in the compile script is the following line:
mex('-v','-L/usr/lib/','-lOpenNI',[...],Filename);
This is the full command run by mex: (1)
gcc-4.2 -O -Wl,-twolevel_namespace -undefined error -arch x86_64 -Wl,-syslibroot,/Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.5 -bundle -Wl,-exported_symbols_list,/Applications/MATLAB_R2011a.app/extern/lib/maci64/mexFunction.map -o "mxNiChangeDepthViewPoint.mexmaci64" mxNiChangeDepthViewPoint.o -L/usr/lib/ -lOpenNI -L/Applications/MATLAB_R2011a.app/bin/maci64 -lmx -lmex -lmat -lstdc++
Then I'm getting the following error:
ld: library not found for -lOpenNI
collect2: ld returned 1 exit status
mex: link of ' "mxNiChangeDepthViewPoint.mexmaci64"' failed.
There is most definitely a file at /usr/lib/libOpenNI.dylib.
What kinds of things cause ld to throw this error?
What I tried:
I have tried creating a symlink called libOpenNI.so, like jmlopez suggested, no effect.
Could it be that libOpenNI is a 32bit library, and ld is not seeing it for that reason? Or would the error then be different?
Regarding the point above, it says that the build is "universal x86/x64"
Env vars:
I've tried to add the library to the environment variables using the following command, from the matlab terminal. No effect.
setenv('DYLD_LIBRARY_PATH', [getenv('DYLD_LIBRARY_PATH') ':/usr/lib/']);
In bash:
Just calling gcc as suggested here https://serverfault.com/questions/54736/how-to-check-if-a-library-is-installed gives no problems.
$ gcc -lOpenNi
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.6.o
However, if I run g++ first, then gcc as in (1), same error as before. (library not found). How come gcc can find the library, but when matlab adds the stuff in (1) it messes things up?
So, related to what is said above, I started removing all arguments from (1) until I got a different error. I removed the -Wl,-syslibroot, meaning that -syslibroot would no longer be passed to ld, this seems to have fixed it. So -syslibroot is messing up the library search directory! Now to find a way to remove this argument from the mex() call.
Did you trying adding OpenNi to your LIBRARY_PATH ?
export LIBRARY_PATH=$LIBRARY_PATH:/YOUR-PATH/OpenNi
First option: if libOpenNi isn't of the same architecture as the binary you're compiling, the whole compiler suite will likely ignore it. If you did manage to get it to link anyway, it would probably crash. Find a native 64 bit library and link against that.
Second option: I'm not 100% sure on this, but whenever I've tried doing linking on some esoteric linux projects, I start with a .a object archive in the path specified by -L. If it links, then I'll add -fPIC -shared on x86_64 to get it to compile against the shared library. I'm not sure if this will work on OSX: I've never done development on that platform yet.
BOOM! IT WORKS!
Okay, here it is:
The -Wl,-syslibroot option in the gcc call (1) is sending a -syslibroot option to the linker, and somehow that gets prepended to the library search path (even though it shouldn't according to cannot specify root sdk directory with syslibroot when linking)
So, removing this -syslibroot can solve our problem, this can be done in mexopts.sh. Copying matlab's version from the default location:
cp /Applications/MATLAB_R2011a.app/bin/mexopts.sh ~/.matlab/R2011a/
And then changing this line (201):
LDFLAGS="-Wl,-twolevel_namespace -undefined error -arch $ARCHS -Wl,-syslibroot,$SDKROOT -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET"
Removing the -Wl,-syslibroot,$SDKROOT argument.
Additionally, I could remove the -L/usr/lib argument from the call to mex, making it simply:
mex('-v','-lOpenNI',['-I' OpenNiPathInclude],Filename);

make arm architecture c library in mac

I'm trying to make my own c library in Mac and include it to my iphone program.
The c code is simple , like this:
math.h:
int myPow2(int);
math.c:
#include "math.h"
int myPow2(int num) {
return num*num;
}
I search how to make the c library file ( .a or .lib ..etc) seems need to use gcc compiler (Is there other methods?) so I use this command:
gcc -c math.c -o math.o
ar rcs libmath.a math.o
And include it in iPhone Project. Now it has the problem when build xcode iphone project.
"file was built for unsupported file
format which is not the architecture
being linked"
I found some pages discuss about the problem, but no detail how to make the i386/arm architecture library. And I finally use this command to do it:
gcc -arch i386 -c math.c -o math.o
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-gcc-4.2.1 -c math.c -o math.o
I dont know if this method is correct? Or there has another method to do it?
What Bavarious said.
Add a new target to your project. When XCode asks you what template to use, chose "Static Library".
Add the files for the library to that target. Add the static library target as a dependency of your main executable target. Add the library that gets built to your main executable target. Voila!