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. .frameworks 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 .frameworks 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 #imported 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