Import Projects
The EBuild tool chain supports a special kind of project called an Import Project that allows you to automatically import a C or Objective-C library and generate the necessary .fx
file(s) to use it in your Elements projects.
Import projects contain no code themselves; instead they reference am existing binary, one or more C or Objective-C .h
header files or a .framework
. When build, the project will analyze the header file and generate one or more .fx
files as output.
You can reference Import Projects via Project References in your regular Elements project, or youcan reference the final .fx
files directly, depending on your need.
Fire and Water provide support to help you create import projects, by simply dragging a .framework
from Finder into your solution, or using the provided project templates.
Structure of an Import Project
An Import Project is a regular .elements
project file, with the OutputType
setting set to Import
. The project mode must be either Toffee
or Island
, as imports are only supported for these two platforms.
An import project may contain no source files, but it can contain additional settings and objects, depending on the type, and it may contain References to other libraries needed by the import, base SDK frameworks or Project References to other imports it depends on.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<OutputType>Import</OutputType>
<SDK>iOS</SDK>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.Toffee.targets" />
</Project>
Importing Frameworks
Frameworks are the easiest to import, as they collect all the required information in a simple bundle. .framework
s are supported only by the Apple platform, typically created by Xcode, so they are available for Cocoa.
To import a framework, make sure to specify Mode and SubMode (Toffee) or Mode, SubMode and SDK for Island/Darwin, as well as any core references needed (usually at least rtl
, Foundation
and UIKit
or AppKit
), as well as a single .framework
file:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<ProjectGuid>{...}</ProjectGuid>
<OutputType>Import</OutputType>
<Mode>Toffee</Mode>
<SubMode>iOS</SubMode>
</PropertyGroup>
<ItemGroup>
<Reference Include="rtl" />
<Reference Include="Foundation" />
<Reference Include="UIKit" />
<ImportFramework Include="My.framework" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.targets" />
</Project>
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<ProjectGuid>{...}</ProjectGuid>
<OutputType>Import</OutputType>
<Mode>Island</Mode>
<SubMode>Island</SubMode>
<SDK>iOS</SDK>
</PropertyGroup>
<ItemGroup>
<Reference Include="rtl" />
<Reference Include="Foundation" />
<Reference Include="UIKit" />
<ImportFramework Include="My.framework" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.targets" />
</Project>
The path to the framework, My.framework
in the example above, can be relative to the project, or absolute.
That's it. You can now build this project, and it will import the headers and generate one or more .fx
files for you, as well as a zipped copy of the .framework, you can use when later compiling projects on Windows (since .framework
s are bundle folders, and do not survice the move to Windows).
Simulator vs. Device, and Architectures
If you have separate copies of your frame work for device vs simulator, make sure the two versions are in properly named subfolders next to each other (e.g. iOS/My.framework
and iOS Simulator/My.framework
).
EBuild will automatically detect this, and switch between the two versions, depending on whether you build the project for Simulator, Device or both.
Automatically Creating Import Projects in Fire
In Fire, you can simply drag a .framework
from Finder onto the References node of your project, just as would when referencing an existing .fx
(or a .dll
or .jar
on other platforms).
Fire will automatically create an Import Project for you, add it to your solution, and add a [Project Reference](/Projects/References/ProjectReferences to that Import project to your existing project.
Importing Multiple Frameworks with Dependencies
To import multiple .frameworks that depend on each other, simply create an individual Import project for each Framework. Then add project references between them as necessary.
E.g. if Second.framework
depends om First.framework
, import "First" as shown above. To the import project for "Second" add a project reference to "First" (e.g. via drag and drop in Fire or Water), before you build:
<ProjectReference Include="First">
<HintPath>/optional/path/to/First.fx</HintPath>
<Project>{...GUID of First.elements...}</Project>
<ProjectFile>/path/to/First.elements</ProjectFile>
</ProjectReference>
Importing Libraies
Static (.a
) or Dynamic (.dll
, .so
, .dylib
) libraries require a bit more configuration to import, as you will need to manually provide EBuild with information on on where to find the .h
header files that describe them.
...
Additional Settings and Objects
Setting: ConditionalDefines
Optionally, a set of conditional defines can be provided to affect the import. This is a semicolon-separated list, and each entry will be treated as if it was provided via #define
directive in source. Since this is C, defines may be name/value pairs with an =
sign.
<CondirtionalDefines>DEBUG;TRACE</CondirtionalDefines>
Setting: RootNamespace
Optionally, this setting can provide the base namespace for the imported APIs. Header files in the root level of the import will use this namespaces, heders in subfolders will get their folder structure appended to the namespace hierarchy.
Note that since Cocoa Frameworks are always contained in a folder, hey will by default get the framework name as namespace name, when RootNamespace
is empty (then default).
Object: ImportFramework
A single ImportFramework
object can be provided to import a Cocoa .framework, as described above. This may not be combioned with the ImportFile
objects.
Object: ImportHeader
One or more C header file can be provided as ImoportHeader
objects in order to drive a manual import. These files can be specified relative to the project or provided as absolute path.
Inside the file, regular #include
directives can be used to pull in the required actual headers. When parsing
Object: ImportVirtualFile
The ImportVirtualFile
object can be used to provide "missing" files that are being #import
ed by some of the header files but, for one reason or another, cannot be found. ImportVirtualFile
objects reference an actual file in the project, that well be used whenever the imported header request a dfile hy that name.
Object: ImportLinkLibrary
The ImportLinkLibrary
object can be used to specify one or more binary files that will need to be linked, in order for the imported library to be used in an application. These can be static libraries (.a
, .lib
) or dynamic ones (.dll
, .so
, .dylib
).
The referenced file must exist on disk, and can be referred to with a path relative to the project, or with an absolute path. If the file is set to CopyLocal
(or Private
), it will be copied next to the generated .fx
file(s) as part of the build.
For each ImportLinkLibrary
object, an ImportLinkName
(see below) will be set automatically, using the filename, dropping the file extension (and, on Cocoa or Island/Darwin, any lib
prefix).
Object ImportLinkNames
The ImportLinkNames
setting can specify the name of one or more binary files (as semicolon-separated list) that will need to be linked, in order for the imported library to be used in an application. This setting affects only the generated linker comm and when applications using the library are built.
Use the ImportLinkName
(instead of the ImportLinkLibrary
object described above), if the actual binary is not available/required at import time, or is part of the standard platform libraries. For example for importing libz
or libxml2
on Cocoa, the actual binary is found on the system, so merely specifying a link name of z
or xml2
will suffice for the linker to locate the right library.
Setting: ImportBlacklist
Optionally, a semicolon-separated list of filenames can be provided to black-list files from being imported into the .fx
.
Setting: ImportForceInclude
C Headers are often inconsistent and sometimes depend on the implied assumption that the user will #import
another file ahead of using a specific header file. The ImportForceInclude
option can be used to manually inject such an include into a file before import.
There is no fast and easy rule for when to add a force-include. Typically, you will encounter an error about a missing type or identifier during import; locate the header that defines the item in question, and try adding a force-include for it.
Force includes come as key/value pairs separated by the =
sign. The name of the problematic file will be on the left, and the name of the file shat should be force-included when importing that problematic file will be on the right.
Multiple force-inlcues can be provided, separated by semicolons:
<ImportForceInclude>MaterialComponents/MDCMultilineTextInputDelegate.h=MaterialComponents/MDCTextInput.h</ImportForceInclude>
Setting: ImportDropPrefixes
Setting: ImportSearchPaths
A semicolon-separate list of search paths where to look header files. Each path must either be absolute, or relative to the project.
Both EBuild settings and environment variables may be used in the search path, for maximum flexibility, using the $(VarName)
syntax. For example, the following search path would find files in the current Xcode SDK for macOS (since the XcodeDeveloperFolder
setting is automatically filled by EBuild, for Toffee and Island/Darwin projects):
<ImportSearchPaths>$(XcodeDeveloperFolder)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include</ImportSearchPaths>
Object: ImportOverrideNamespace
Object: Reference
See Also
.fx
Files- Blog Post and Video: Import Projects
- Blog Post: Import Recipes
- GitHub: github.com/RemObjects/Recipes