Posts Tagged ‘PNaCl’

Xcode 5 custom compiler

January 15, 2014

Chrome 32 ships with PNaCl enabled by default. It has begun.

Ok but what to do if You want to jump into deep water and port an SDK consisting of quite large C/C++ codebase to PNaCl ( everybody understand that the possibility to run native code with almost native performance directly in the browser is cool )? Which tools to use?

I started with QMake. I thought it would be easy. Create new MkSpec, set paths to pnacl-clang and that is it. Well it is not that easy, but possible.

For some reason, though, I am not really into makefiles. These days i would expect that a click on the error or warning  generated by the compiler taking me  directly on the line of source code that caused problem (or at least compiler thinks so). Wait a second… Our SDK is already ported to iOS. And we have nice Xcode project and C++ unit test, all running. And Xcode used to support GCC side by side with LLVM compiler. Maybe there is a way to tweak Xcode and add custom compiler that would compile PNaCl code in Xcode?

First i looked around and found a few attempts (Erlang Xcode plugin, C# Mono plugin). I did not realize that these plug-ins stopped development in Xcode 3.0 stage. Nevertheless i tried. First by copying : 

/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/Clang LLVM 1.0.xcplugin

to 

/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/PNaCl.xcplugin

and renaming compiler specification file Contents/Resources/Clang LLVM 1.0.xcspec to PNaCl.xcspec and then modifying ExecPath to point to pnacl-clang (and also Identifier, and a few others) after rerunning Xcode (actually there were few other steps involved)   – voila, the PNaCL compiler appear on the list of the compilers in Xcode. So I copied one of the existing targets in the SDK project, named it SDK-PNaCl and clicked Build. The actual pnacl-clang command was run, but it failed because of -F option which was not understood. After a few hours of searching and thinking i decided that there is no way to override this behavior just by modifying the xcspec, while the class is still XCCompilerSpecificationClang.

I needed a custom class. I tried to copy the implementation of compiler specification from Erlang Xcode plugin’ but the method 

-computeDependenciesForInputFile:ofType:variant:architecture:outputDirectory:inTargetBuildContext:

was not called no matter what i did. After some time i realized that in Xcode 4+ this method has changed to: 

- computeDependenciesForInputNodes:ofType:variant:architecture:outputDirectory:withMacroExpansionScope:

But, wtf? I was able to link to /Applications/Xcode.app/Contents/OtherFrameworks/DevToolsCore.framework so there must be another version of this framework. A quick search under /Application/Xcode.app revealed that there is another set of frameworks, for Xcode 5, namely here: 

/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/Frameworks/DevToolsCore.framework

which were correct for Xcode 5. I used class dump to generate headers out of the binary versions of framework. Class dump is an awesome tool but it has some flaw which means that generated headers need to be manually fixed. One of them is that it tries to include “NSObject.h” where it should include <Foundation/Foundation.h>. 

Having obtained the correct header i tried to go through them and try to understand but this will take me another i don’t know how many sleepless hours. Currently i am able to compile a file into an object file but i am not sure how to substitute the linker/librarian. 

Open questions. Just a few: 

  1. How to substitute linker/librarian? Does product node play a role in this process? Does a file type play a role? 
  2. How to set output file type of the node of the C/C++ file node to newly created pnacl-o, as opposed to mach-o?
  3. How to get rid of unnecessary Build options?
  4. Would it be beneficial to define PNaCl.platform as a platform, and each of  pepper_32, pepper_30, pepper_canary as their SDK? Is it possible?
  5. Very naive: is there a documentation pointing out the Xcode build process, role of specifications, etc?

UPDATE:Added references with very important link. I should have read it thoroughly earlier since it might have a solution for the linker thing ready.
References:

Advertisements