wiki:CustomFramework

Version 1 (modified by adamvh, 4 years ago) (diff)

--

The Objective-C bridge makes it very easy to use existing Cocoa classes from Lisp code, and to define classes in Lisp that interact with Objective-C code. However, sometimes you may wish to access functionality contained in third-party Objective-C sources. It is possible to do this using the Objective-C sources; however, there are a few steps, so I will list them here.

  1. You will want to build a framework from the Objective-C sources containing the desired functionality. This can be done with XCode, and there are good explanations elsewhere.
  1. To support its FFI, CCL maintains a binary database of information about classes, methods, functions, types, and variables available from foreign libraries in several ".cdb" files. You will need to generate this information for your particular library. In order to do this, you will need to obtain and build ffigen4. Once you have done so, navigate to $CCL_DIRECTORY/darwin-x86-headers or $CCL_DIRECTORY/darwin-x86-headers64, depending. In this directory, create a directory with the same name as the Framework you built in step 1, and inside that directory, create a directory named "C". Inside C, you must write a shell script named "populate.sh," that invokes another shell script "h-to-ffi.sh," (which should be on your path after building and installing ffigen4) on every header in your framework. The directories that already exist in darwin-x86-headers[64] contain examples that can be adapted to this purpose. (Note that Apple's frameworks have one "mega header" that includes all of the others, so many (all?) of the example shell scripts only have to pass one header to h-to-ffi.sh. This will generate a directory tree that contains (eventually) several ".ffi" files inside the directory "C."
  1. Now, the ".ffi" files must be converted to ".cdb" files. This happens entirely within Lisp. Just invoke the command (ccl::parse-standard-ffi-files :interface-dir), where :interface-dir is the name of the directory that you created in step 2.
  1. CCL maintains a list of "active interface directories". In order to successfully (require 'cocoa), the only directories that can be active are :cocoa and :libc. Unfortunately, the previous command adds your interface directory to this list, which will cause (require 'cocoa) to bork. So, exit the REPL or otherwise modify the state of the Lisp image to be original and pristine.
  1. Now, you can (require 'cocoa), followed by an (objc:load-framework :framework :interface-dir) and use the classes from your own Objective-C framework.