Commit c24052d9 authored by j4cbo's avatar j4cbo

Merge pull request #83 from mknejp/feature/objcpp-cmd-args

Command line arguments to control Obj-C++ generation
parents 04da0e9a 393421cf
......@@ -105,6 +105,8 @@ When the Djinni file(s) are ready, from the command line or a bash script you ca
--objc-out OBJC_OUTPUT_FOLDER \
--objc-type-prefix DB \ # Apple suggests Objective-C classes have a prefix for each defined type.
\
--objcpp-out OBJC_OUTPUT_FOLDER \
\
--idl MY_PROJECT.djinni
Some other options are also available, such as `--cpp-namespace` that put generated C++ code into the namespace specified. For a list of all options, run
......@@ -158,26 +160,19 @@ you'll need to add calls to your own `JNI_OnLoad` and `JNI_OnUnload` functions.
##### Includes & Build Target
Generated file for Objective-C / C++ is as follows (assuming prefix is `DB`):
| Type | C++ header | C++ source | Objective-C header | Objective-C source |
|----------------|------------------------|----------------------------|--------------------------------------------|-------------------------------------|
| Enum | my\_enum.hpp | | ` public/`DBMyEnum.h | `private/`DBMyEnumTranslator.mm |
| | | | `private/`DBMyEnumTranslator+Private.h | |
| Record | my\_record[\_base].hpp | my\_record[\_base].cpp (+) | ` public/`DBMyRecord[Base].h | `private/`DBMyRecord[Base].mm |
| | | | `private/`DBMyRecord[Base]+Private.h | |
| Interface `+c` | my\_interface.hpp | my\_interface.cpp (+) | ` public/`DBMyInterface.h | `private/`DBMyInterfaceCppProxy.mm |
| | | | ` public/`DBMyInterfaceCppProxy.h | |
| | | | `private/`DBMyInterfaceCppProxy+Private.h | |
| Interface `+o` | my\_interface.hpp | my\_interface.cpp (+) | ` public/`DBMyInterface.h | `private/`DBMyInterfaceObjcProxy.mm |
| | | | `private/`DBMyInterfaceObjcProxy+Private.h | |
| Type | C++ header | C++ source | Objective-C files | Objective-C++ files |
|-----------|------------------------|----------------------------|--------------------------|-----------------------------|
| Enum | my\_enum.hpp | | DBMyEnum.h | |
| Record | my\_record[\_base].hpp | my\_record[\_base].cpp (+) | DBMyRecord[Base].h | DBMyRecord[Base]+Private.h |
| | | | DBMyRecord[Base].mm (++) | DBMyRecord[Base]+Private.mm |
| Interface | my\_interface.hpp | my\_interface.cpp (+) | DBMyInterface.h | DBMyInterface+Private.h |
| | | | | DBMyInterface+Private.mm |
(+) Generated only for types that contain constants.
The folders `public` and `private` correspond to the options `--objc-out` and `--objc-private-out`
respecitvely, allowing you to isolate implementation headers and sources from the public files
exposed to Objective-C clients.
(++) Generated only for types with derived operations and/or constants. These have `.mm` extensions to allow non-trivial constants.
Add all generated files to your build target, as well as the contents of `support-lib/objc`.
Note that `+Private` headers can only be used with ObjC++ source (other headers are pure ObjC).
Note that `+Private` files can only be used with ObjC++ source (other headers are pure ObjC) and are not required by Objective-C users of your interface.
## Details of Generated Types
### Enum
......
......@@ -63,7 +63,8 @@ $base_dir/../src/run-assume-built \
--ident-jni-class NativeFooBar \
--ident-jni-file NativeFooBar \
\
--objc-out "$temp_out/objc" \
--objc-out "$temp_out/objc" \
--objcpp-out "$temp_out/objc" \
--objc-type-prefix TXS \
\
--idl "$in"
......
......@@ -51,14 +51,15 @@ object Main {
var cppIdentStyle = IdentStyle.cppDefault
var cppTypeEnumIdentStyle: IdentConverter = null
var objcOutFolder: Option[File] = None
var objcPrivateOutFolderOptional: Option[File] = None
var objcExt: String = "mm"
var objcppOutFolder: Option[File] = None
var objcppExt: String = "mm"
var objcHeaderExt: String = "h"
var objcIdentStyle = IdentStyle.objcDefault
var objcTypePrefix: String = ""
var objcIncludePrefix: String = ""
var objcIncludePrivatePrefixOptional: Option[String] = None
var objcIncludeCppPrefix: String = ""
var objcppIncludePrefix: String = ""
var objcppIncludeCppPrefix: String = ""
var objcppIncludeObjcPrefixOptional: Option[String] = None
var objcFileIdentStyleOptional: Option[IdentConverter] = None
var objcppNamespace: String = "djinni_generated"
var objcBaseLibIncludePrefix: String = ""
......@@ -122,22 +123,25 @@ object Main {
note("")
opt[File]("objc-out").valueName("<out-folder>").foreach(x => objcOutFolder = Some(x))
.text("The output folder for Objective-C files (Generator disabled if unspecified).")
opt[File]("objc-private-out").valueName("<out-folder>").foreach(x => objcPrivateOutFolderOptional = Some(x))
.text("The output folder for private Objective-C header and implementation files (default: the same as --objc-out)")
opt[String]("objc-ext").valueName("<ext>").foreach(objcExt = _)
.text("The filename extension for Objective-C files (default: \"mm\")")
opt[String]("objc-h-ext").valueName("<ext>").foreach(objcHeaderExt = _)
.text("The filename extension for Objective-C header files (default: \"h\")")
.text("The filename extension for Objective-C[++] header files (default: \"h\")")
opt[String]("objc-type-prefix").valueName("<pre>").foreach(objcTypePrefix = _)
.text("The prefix for Objective-C data types (usually two or three letters)")
opt[String]("objc-include-prefix").valueName("<prefix>").foreach(objcIncludePrefix = _)
.text("The prefix for #import of header files from Objective-C files.")
opt[String]("objc-include-private-prefix").valueName("<prefix>").foreach(x => objcIncludePrivatePrefixOptional = Some(x))
.text("The prefix for #import and #include of private header files from Objective-C files (default: the same as --objc-include-prefix)")
opt[String]("objc-include-cpp-prefix").valueName("<prefix>").foreach(objcIncludeCppPrefix = _)
.text("The prefix for #include of the main header files from Objective-C files.")
note("")
opt[File]("objcpp-out").valueName("<out-folder>").foreach(x => objcppOutFolder = Some(x))
.text("The output folder for private Objective-C++ files (Generator disabled if unspecified).")
opt[String]("objcpp-ext").valueName("<ext>").foreach(objcppExt = _)
.text("The filename extension for Objective-C++ files (default: \"mm\")")
opt[String]("objcpp-include-prefix").valueName("<prefix>").foreach(objcppIncludePrefix = _)
.text("The prefix for #import of Objective-C++ header files from Objective-C++ files.")
opt[String]("objcpp-include-cpp-prefix").valueName("<prefix>").foreach(objcppIncludeCppPrefix = _)
.text("The prefix for #include of the main C++ header files from Objective-C++ files.")
opt[String]("objcpp-include-objc-prefix").valueName("<prefix>").foreach(x => objcppIncludeObjcPrefixOptional = Some(x))
.text("The prefix for #import of the Objective-C header files from Objective-C++ files (default: the same as --objcpp-include-prefix)")
opt[String]("objcpp-namespace").valueName("<prefix>").foreach(objcppNamespace = _)
.text("Namespace for C++ objects defined in Objective-C++, such as wrapper caches")
.text("The namespace name to use for generated Objective-C++ classes.")
opt[String]("objc-base-lib-include-prefix").valueName("...").foreach(x => objcBaseLibIncludePrefix = x)
.text("The Objective-C++ base library's include path, relative to the Objective-C++ classes.")
......@@ -174,8 +178,7 @@ object Main {
val jniBaseLibClassIdentStyle = jniBaseLibClassIdentStyleOptional.getOrElse(jniClassIdentStyle)
val jniFileIdentStyle = jniFileIdentStyleOptional.getOrElse(cppFileIdentStyle)
var objcFileIdentStyle = objcFileIdentStyleOptional.getOrElse(objcIdentStyle.ty)
val objcPrivateOutFolder = if (objcPrivateOutFolderOptional.isDefined) objcPrivateOutFolderOptional else objcOutFolder
var objcIncludePrivatePrefix = objcIncludePrivatePrefixOptional.getOrElse(objcIncludePrefix)
val objcppIncludeObjcPrefix = objcppIncludeObjcPrefixOptional.getOrElse(objcppIncludePrefix)
// Add ObjC prefix to identstyle
objcIdentStyle = objcIdentStyle.copy(ty = IdentStyle.prefix(objcTypePrefix,objcIdentStyle.ty))
......@@ -231,14 +234,15 @@ object Main {
cppExt,
cppHeaderExt,
objcOutFolder,
objcPrivateOutFolder,
objcppOutFolder,
objcIdentStyle,
objcFileIdentStyle,
objcExt,
objcppExt,
objcHeaderExt,
objcIncludePrefix,
objcIncludePrivatePrefix,
objcIncludeCppPrefix,
objcppIncludePrefix,
objcppIncludeCppPrefix,
objcppIncludeObjcPrefix,
objcppNamespace,
objcBaseLibIncludePrefix)
......
......@@ -52,17 +52,17 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
val ext = d.body.asInstanceOf[Interface].ext
if (ext.cpp) {
header.add("@class " + objcMarshal.typename(tm) + ";")
body.add("#import " + q(spec.objcIncludePrivatePrefix + privateHeaderName(d.name)))
body.add("#import " + q(spec.objcppIncludePrefix + privateHeaderName(d.name)))
}
if (ext.objc) {
header.add("@protocol " + objcMarshal.typename(tm) + ";")
body.add("#import " + q(spec.objcIncludePrivatePrefix + privateHeaderName(d.name)))
body.add("#import " + q(spec.objcppIncludePrefix + privateHeaderName(d.name)))
}
case DRecord =>
val r = d.body.asInstanceOf[Record]
val prefix = if (r.ext.objc) "../" else ""
val objcName = d.name + (if (r.ext.objc) "_base" else "")
header.add("@class " + objcMarshal.typename(tm) + ";")
body.add("#import " + q(spec.objcIncludePrivatePrefix + prefix + privateHeaderName(d.name)))
body.add("#import " + q(spec.objcppIncludePrefix + privateHeaderName(objcName)))
}
case p: MParam =>
}
......@@ -77,8 +77,7 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
def headerName(ident: String): String = idObjc.ty(ident) + "." + spec.objcHeaderExt
def privateHeaderName(ident: String): String = idObjc.ty(ident) + "+Private." + spec.objcHeaderExt
def bodyName(ident: String): String = idObjc.ty(ident) + "." + spec.objcExt
def privateBodyName(ident: String): String = idObjc.ty(ident) + "+Private." + spec.objcExt
def bodyName(ident: String): String = idObjc.ty(ident) + "+Private." + spec.objcppExt
override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) {
val refs = new ObjcRefs()
......@@ -94,9 +93,9 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
val cppSelf = cppMarshal.fqTypename(ident, i)
refs.privHeader.add("#include <memory>")
refs.privHeader.add("!#include " + q(spec.objcIncludeCppPrefix + spec.cppFileIdentStyle(ident) + "." + spec.cppHeaderExt))
refs.privHeader.add("!#include " + q(spec.objcppIncludeCppPrefix + spec.cppFileIdentStyle(ident) + "." + spec.cppHeaderExt))
refs.body.add("#include <vector>")
refs.body.add("!#import " + q(spec.objcIncludePrefix + headerName(ident)))
refs.body.add("!#import " + q(spec.objcppIncludeObjcPrefix + headerName(ident)))
def writeObjcFuncDecl(method: Interface.Method, w: IndentWriter) {
val label = if (method.static) "+" else "-"
......@@ -131,7 +130,7 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
})
if (i.ext.cpp) {
refs.body.add("!#import " + q(spec.objcIncludePrivatePrefix + privateHeaderName(ident.name)))
refs.body.add("!#import " + q(spec.objcppIncludePrefix + privateHeaderName(ident.name)))
refs.body.add("#import " + q(spec.objcBaseLibIncludePrefix + "DJICppWrapperCache+Private.h"))
refs.body.add("#include <utility>")
refs.body.add("#import " + q(spec.objcBaseLibIncludePrefix + "DJIError.h"))
......@@ -193,7 +192,7 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
if (i.ext.objc) {
val objcExtSelf = objcppMarshal.helperClass("objc_proxy")
refs.body.add("#import " + q(spec.objcBaseLibIncludePrefix + "DJIObjcWrapperCache+Private.h"))
refs.body.add("!#import " + q(spec.objcIncludePrivatePrefix + privateHeaderName(ident.name)))
refs.body.add("!#import " + q(spec.objcppIncludePrefix + privateHeaderName(ident.name)))
writeObjcFile(bodyName(ident.name), origin, refs.body, w => {
arcAssert(w)
......@@ -250,17 +249,17 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
refs.header.add("#import <Foundation/Foundation.h>")
refs.privHeader.add("!#import " + q(spec.objcIncludePrefix + headerName(objcName)))
refs.privHeader.add("!#include " + q(spec.objcIncludeCppPrefix + spec.cppFileIdentStyle(ident) + "." + spec.cppHeaderExt))
refs.privHeader.add("!#include " + q(spec.objcppIncludeCppPrefix + spec.cppFileIdentStyle(ident) + "." + spec.cppHeaderExt))
refs.body.add("#import <Foundation/Foundation.h>")
refs.body.add("#include <cassert>")
refs.body.add("#include <utility>")
refs.body.add("#include <vector>")
refs.body.add("#import " + q(spec.objcBaseLibIncludePrefix + "DJIDate.h"))
refs.body.add("!#import " + q(spec.objcIncludePrivatePrefix + privateHeaderName(objcName)))
refs.body.add("!#import " + q(spec.objcppIncludePrefix + privateHeaderName(objcName)))
if (r.ext.objc) {
refs.body.add("#import " + q(spec.objcIncludePrefix + "../" + headerName(ident)))
refs.body.add("#import " + q(spec.objcppIncludeObjcPrefix + "../" + headerName(ident)))
refs.header.add(s"@class ${objcMarshal.typename(ident, r)};")
}
......@@ -292,7 +291,7 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
})
})
writeObjcFile(privateBodyName(objcName), origin, refs.body, w => {
writeObjcFile(bodyName(objcName), origin, refs.body, w => {
wrapNamespace(w, spec.objcppNamespace, w => {
w.wl(s"auto $helperClass::toCpp(ObjcType obj) -> CppType")
w.braced {
......@@ -316,7 +315,7 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
}
def writeObjcFile(fileName: String, origin: String, refs: Iterable[String], f: IndentWriter => Unit) {
createFile(spec.objcPrivateOutFolder.get, fileName, (w: IndentWriter) => {
createFile(spec.objcppOutFolder.get, fileName, (w: IndentWriter) => {
w.wl("// AUTOGENERATED FILE - DO NOT MODIFY!")
w.wl("// This file generated by Djinni from " + origin)
w.wl
......
......@@ -53,14 +53,15 @@ package object generatorTools {
cppExt: String,
cppHeaderExt: String,
objcOutFolder: Option[File],
objcPrivateOutFolder: Option[File],
objcppOutFolder: Option[File],
objcIdentStyle: ObjcIdentStyle,
objcFileIdentStyle: IdentConverter,
objcExt: String,
objcppExt: String,
objcHeaderExt: String,
objcIncludePrefix: String,
objcIncludePrivatePrefix: String,
objcIncludeCppPrefix: String,
objcppIncludePrefix: String,
objcppIncludeCppPrefix: String,
objcppIncludeObjcPrefix: String,
objcppNamespace: String,
objcBaseLibIncludePrefix: String)
......@@ -166,9 +167,11 @@ package object generatorTools {
new JNIGenerator(spec).generate(idl)
}
if (spec.objcOutFolder.isDefined) {
createFolder("Objective-C[++]", spec.objcOutFolder.get)
createFolder("Objective-C[++] private", spec.objcPrivateOutFolder.get)
createFolder("Objective-C", spec.objcOutFolder.get)
new ObjcGenerator(spec).generate(idl)
}
if (spec.objcppOutFolder.isDefined) {
createFolder("Objective-C++", spec.objcppOutFolder.get)
new ObjcppGenerator(spec).generate(idl)
}
None
......
......@@ -65,6 +65,7 @@ $base_dir/../src/run-assume-built \
--ident-jni-file NativeFooBar \
\
--objc-out "$temp_out/objc" \
--objcpp-out "$temp_out/objc" \
--objc-type-prefix DB \
\
--idl "$in"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment