Add technical documents and improve readme (#646)
- https://github.com/mono/Embeddinator-4000/issues/160 - Contributing guide "borrowed" from xamarin-macios
This commit is contained in:
Родитель
398a2e017f
Коммит
6017d8bd00
|
@ -0,0 +1,36 @@
|
|||
# Contributing
|
||||
|
||||
There are many ways to contribute to Embeddinator-4000: logging bugs, submitting pull requests, reporting issues, and creating suggestions.
|
||||
|
||||
## Work Branches
|
||||
|
||||
Even if you have push rights on the mono/Embeddinator-4000 repository, you should create a personal fork and create feature branches there when you need them. This keeps the main repository clean and your personal workflow cruft out of sight.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
To enable us to quickly review and accept your pull requests, always create one pull request per issue and link the issue in the pull request. Never merge multiple requests in one unless they have the same root cause. Be sure to follow our [Coding Guidelines](http://www.mono-project.com/community/contributing/coding-guidelines/) and keep code changes as small as possible. Avoid pure formatting changes to code that has not been modified otherwise. Pull requests should contain tests whenever possible.
|
||||
|
||||
**Where to Contribute**
|
||||
Check out the [full issues list](https://github.com/mono/Embeddinator-4000/issues) for a list of all potential areas for contributions. Note that just because an issue exists in the repository does not mean we will accept a contribution to it. There are several reasons we may not accept a pull request like:
|
||||
|
||||
- Some `enhancement` describe a real issue but the proposed way to solve it might not be the best one. Discussions on how to best solve the root issue should happen on the GitHub issue (and before a pull-request);
|
||||
- Negative impact on build time or build size. E.g. ideally the cost of fixing something should not have a huge impact on people that do not require that feature;
|
||||
- Incomplete support of all platforms. If a feature **can** exists across all platforms then it should be implemented for all of them. This helps to create cross-platform applications;
|
||||
|
||||
To improve the chances to get a pull request merged you should select an issue that is labeled with the <a href="https://github.com/mono/Embeddinator-4000/labels/help%20wanted"><code>help wanted</code><a> or <a href="https://github.com/mono/Embeddinator-4000/labels/bug"><code>bug</code></a> labels. If the issue you want to work on is not labeled with `help-wanted` or `bug`, you can start a conversation with the issue owner asking whether an external contribution will be considered.
|
||||
|
||||
To discuss this project, and participate in the design or development, we use [Gitter](https://gitter.im/managed-interop).
|
||||
|
||||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/managed-interop?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
## Suggestions
|
||||
|
||||
We're also interested in your feedback for the future of Embeddinator-4000. You can submit a suggestion or feature request through the issue tracker. To make this process more effective, we may ask that these include more information to help define them more clearly.
|
||||
|
||||
## Coding Guidelines
|
||||
|
||||
We use [Mono's Coding Guidelines](http://www.mono-project.com/community/contributing/coding-guidelines/).
|
||||
|
||||
## Discussion Etiquette
|
||||
|
||||
In order to keep the conversation clear and transparent, please limit the discussion to English and keep things on topic with the issue. Be considerate of others and try to be courteous and professional at all times.
|
|
@ -0,0 +1,32 @@
|
|||
## Project Structure
|
||||
|
||||
The Embeddinator-4000 project covers a number of languages (Objective-C, Java, C) and is made up of a number of different components.
|
||||
|
||||
The most major current distinction is between the Android/C generators and Objective-C generator. Currently these areas are quite distinct, with different folders and projects, without a lot of overlap. Future work is planned to harmonize the differences where possible.
|
||||
|
||||
### Projects
|
||||
|
||||
- Embeddinator-4000.sln is the top solution which contains all Embeddinator projects.
|
||||
- build/projects/Embeddinator-4000.csproj contains the Java and C backends and is interally called "binder" in a number of build files.
|
||||
- objcgen/objcgen.csproj contains the Objective-C backend and is exposed as the objcgen tool.
|
||||
|
||||
### Folders
|
||||
|
||||
Here is a high level description of what each folder contains:
|
||||
|
||||
- **binder** - Android/C backend code
|
||||
- **build** - Cake build files and projects used primariy for Android/C.
|
||||
- nuget generation is here as well, and shared by all platforms.
|
||||
- **docs** - **Temporary** - External user facing documentation. This will move to docs.microsoft.com soon.
|
||||
- **external** - External libraries used, pulled in as submodules, which include:
|
||||
- IKVM - Used by Objective-C backend
|
||||
- CppSharp - Used by Android/C backend
|
||||
- **objcgen** - Makefiles and code for the Objective-C backend
|
||||
- **packages** - External libraries used, pulled in as nugets, which include:
|
||||
- Mono.Cecil - Used by Java/C backend
|
||||
- NUnit - Powering unit tests
|
||||
- A large number of Xamarin.Android support libraries used by Java backend, primarily in tests.
|
||||
- **samples** - A handful of samples libraries showing use of Embeddinator
|
||||
- **support** - Native (Objective-C, Java, and C) headers and files consumed by the generated bindings
|
||||
- **tests** - Automated test suite described in more detail [here](tests/Tests.md) here.
|
||||
- **tools** - Developer scripts and internal tooling
|
51
README.md
51
README.md
|
@ -24,7 +24,7 @@ and Java (Android and regular Java), across Windows, Linux and macOS platforms.
|
|||
|
||||
## Getting Started
|
||||
|
||||
Check out our [documentation to get started](https://mono.github.io/Embeddinator-4000/)
|
||||
Check out our [documentation to get started](https://docs.microsoft.com/en-us/xamarin/tools/dotnet-embedding/index).
|
||||
|
||||
## Community
|
||||
|
||||
|
@ -32,39 +32,38 @@ Feel free to join us at our [#managed-interop](https://gitter.im/managed-interop
|
|||
|
||||
## Building
|
||||
|
||||
Clone this repository and initialize/update submodules as well as solution depends on them.
|
||||
- Clone this repository
|
||||
- Initialize/update submodules: `git submodule update --recursive --init`
|
||||
- Open the solution file `Embeddinator-4000.sln` with Visual Studio or Visual Studio For Mac
|
||||
- Build
|
||||
|
||||
The Android/C portions of the project can also be built with [Cake](https://cakebuild.net/) using the build.ps1 / build.sh scripts.
|
||||
|
||||
The Objective-C portions of the project can be built with `make` in `objcgen`.
|
||||
|
||||
### Nuget
|
||||
|
||||
To generate the nuget use can use either (they both invoke the same build process):
|
||||
|
||||
- `make nuget` in `objcgen`
|
||||
- [Cake](https://cakebuild.net/) :`./build.sh -t Create-Package`
|
||||
|
||||
Open the solution file `Embeddinator-4000.sln` with Visual Studio or Xamarin Studio and press F7.
|
||||
|
||||
## Usage
|
||||
|
||||
To generate bindings for a managed library you invoke the `Embeddinator-4000.exe` command line tool.
|
||||
The getting started [documentation](https://docs.microsoft.com/en-us/xamarin/tools/dotnet-embedding/index) walks through basic usage of the Embeddinator.
|
||||
|
||||
_Important: please follow the instructions in `objcgen`'s [README](https://github.com/mono/Embeddinator-4000/blob/objc/objcgen/README.md) to use the new and improved Objective-C generator (will eventually fusion with `Embeddinator-4000.exe`)._
|
||||
More details on platform specific invocations can be found [here](Usage.md).
|
||||
|
||||
If you do not pass any arguments, you will get a list of the tool options:
|
||||
|
||||
```
|
||||
Embeddinator-4000.exe [options]+ ManagedAssembly.dll
|
||||
Generates target language bindings for interop with managed code.
|
||||
## Development
|
||||
|
||||
--gen=VALUE target generator (C, C++, Obj-C, Java)
|
||||
-p, --platform=VALUE target platform (iOS, macOS, Android, Windows)
|
||||
-o, --out, --outdir=VALUE output directory
|
||||
-c, --compile compiles the generated output
|
||||
-d, --debug enables debug mode for generated native and
|
||||
managed code
|
||||
-t, --target=VALUE compilation target (static, shared, app)
|
||||
--dll, --shared compiles as a shared library
|
||||
--static compiles as a static library
|
||||
--vs=VALUE Visual Studio version for compilation: 2012, 2013,
|
||||
2015, 2017, Latest (defaults to Latest)
|
||||
-v, --verbose generates diagnostic verbose output
|
||||
-h, --help show this message and exit
|
||||
```
|
||||
The [contributing guide](Contributing.md) covers a number of areas to consider when contributing to Embeddinator-4000.
|
||||
|
||||
To generate C bindings for a `Xamarin.Foo.dll` assembly you would call
|
||||
the tool like:
|
||||
A number of internal documentation files exist describing the project and internal structure of Embeddinator:
|
||||
|
||||
- [General Project Structure](ProjectStructure.md)
|
||||
- [Automated Tests](tests/Tests.md)
|
||||
- [Objective-C Generator Internals](objcgen/Internals.md)
|
||||
|
||||
`Embeddinator-4000.exe -gen=c -out=foo Xamarin.Foo.dll`
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
## Usage
|
||||
|
||||
Until tooling unification occurs, there are number of differences between invoking the Embeddinator between Objective-C and Java/C.
|
||||
|
||||
|
||||
### Objective-C
|
||||
|
||||
To generate bindings to Objective-C for a managed library you invoke the `objcgen` command line tool.
|
||||
|
||||
If you do not pass any arguments, you will get a list of the tool options:
|
||||
|
||||
```
|
||||
Generates target language bindings for interop with managed code.
|
||||
|
||||
Usage: objcgen [options]+ ManagedAssembly1.dll [ManagedAssembly2.dll ...]
|
||||
|
||||
-c, --compile Compiles the generated output
|
||||
-e, --extension Compiles the generated output as extension safe api
|
||||
--nativeexception Compiles the generated output to throw native
|
||||
exceptions (Apple only)
|
||||
-d, --debug Build the native library with debug information.
|
||||
--gen=VALUE Target generator (default ObjectiveC)
|
||||
--abi=VALUE A comma-separated list of ABIs to compile. If not
|
||||
specified, all ABIs applicable to the selected
|
||||
platform will be built. Valid values (also
|
||||
depends on platform): i386, x86_64, armv7,
|
||||
armv7s, armv7k, arm64.
|
||||
-o, --out, --outdir=VALUE Output directory
|
||||
-p, --platform=VALUE Target platform (iOS, macOS [default], macos-[
|
||||
modern|full|system], watchOS, tvOS)
|
||||
--vs=VALUE Visual Studio version for compilation (unsupported)
|
||||
-h, -?, --help Displays the help
|
||||
-v, --verbose generates diagnostic verbose output
|
||||
--version Display the version information.
|
||||
--target=VALUE The compilation target (staticlibrary,
|
||||
sharedlibrary, framework).
|
||||
--warnaserror[=VALUE] An optional comma-separated list of warning codes
|
||||
that should be reported as errors (if no
|
||||
warnings are specified all warnings are reported
|
||||
as errors).
|
||||
--nowarn[=VALUE] An optional comma-separated list of warning codes
|
||||
to ignore (if no warnings are specified all
|
||||
warnings are ignored).
|
||||
```
|
||||
|
||||
To generate Objective-C bindings for a `Xamarin.Foo.dll` assembly you would call
|
||||
the tool like:
|
||||
|
||||
`objcgen Xamarin.Foo.dll --target=framework --platform=macOS-modern --abi=x86_64 --outdir=output -c --debug`
|
||||
|
||||
with platform and abi depending on the specific target (macOS, iOS, etc).
|
||||
|
||||
### Java / C
|
||||
|
||||
|
||||
To generate bindings to Java or C for a managed library you invoke the `Embeddinator-4000.exe` command line tool.
|
||||
|
||||
If you do not pass any arguments, you will get a list of the tool options:
|
||||
|
||||
```
|
||||
Embeddinator-4000.exe [options]+ ManagedAssembly.dll
|
||||
Generates target language bindings for interop with managed code.
|
||||
|
||||
--gen=VALUE target generator (C, C++, Obj-C, Java)
|
||||
-p, --platform=VALUE target platform (iOS, macOS, Android, Windows)
|
||||
-o, --out, --outdir=VALUE output directory
|
||||
-c, --compile compiles the generated output
|
||||
-d, --debug enables debug mode for generated native and
|
||||
managed code
|
||||
-t, --target=VALUE compilation target (static, shared, app)
|
||||
--dll, --shared compiles as a shared library
|
||||
--static compiles as a static library
|
||||
--vs=VALUE Visual Studio version for compilation: 2012, 2013,
|
||||
2015, 2017, Latest (defaults to Latest)
|
||||
-v, --verbose generates diagnostic verbose output
|
||||
-h, --help show this message and exit
|
||||
```
|
||||
|
||||
To generate C bindings for a `Xamarin.Foo.dll` assembly you would call
|
||||
the tool like:
|
||||
|
||||
`Embeddinator-4000.exe -gen=c -out=foo Xamarin.Foo.dll`
|
|
@ -0,0 +1,41 @@
|
|||
## Objective-C Generator Internals
|
||||
|
||||
Code generators by their nature of generating code that will later be compiled can be difficult to trace through and understand.
|
||||
|
||||
The Objective-C backend covers a number of different platforms (macOS, iOS, tvOS, etc). For all platforms, other than macOS without Xamarin.Mac, building frameworks is the default and supported packaging technique. Static libraries and dylib are available on macOS without Xamarin.Mac.
|
||||
|
||||
This document will provide a high level roadmap of the components of `objcgen` and how they fit together.
|
||||
|
||||
### Flow of Execution
|
||||
|
||||
- Executation begins in the [driver](driver.cs) which handles a few tasks:
|
||||
- Use [Mono.Options](https://github.com/xamarin/XamarinComponents/tree/master/XPlat/Mono.Options) to parse command line arguments
|
||||
- Setup error handling in case of later crashes/exceptions
|
||||
- In the common "generate" action case, instance an [embedder](embedder.cs) and configure it based on command line arguments
|
||||
- If compilation is requested then the [driver](driver.cs) invokes `Compile ()` on the [embedder](embedder.cs) post generation
|
||||
- The [embedder](embedder.cs) drives code generation and packaging by:
|
||||
- Validating settings passed in by [driver](driver.cs) are valid based on platform specific rules
|
||||
- Use [IKVM](https://github.com/mono/ikvm-fork) to load the .NET assembly in question for processing via reflection.
|
||||
- Also configure IKVM to look for BCL and Facades from the appropriate SDK directory
|
||||
- Instance a [ObjCProcessor](objcprocessor.cs) which reflects the library extracting needed information.
|
||||
- Instance a [ObjCGenerator](objcgenerator.cs) which uses the ProcessedAssembly data to generate the native Objective-C bindings.
|
||||
- The [ObjCProcessor](objcprocessor.cs) walks each "acceptable" type creating various ["Processed"](processedtypes.cs) data structures for each Type, Method, Property, etc.
|
||||
- Acceptable types a subset of public, non-NSObject subclasses that we support.
|
||||
- Some type references (such as DateType) require binding additional BCL types to be useable in Objective-C and are pulled in "magically" during processing.
|
||||
- This is the first, and best, stage where items can be removed from binding if they require features not yet supported.
|
||||
- A number of mappings are done from C# to Objective-C to make APIs more friendly, such as nicely exposing subscripting.
|
||||
- Items are all OrderBy'ed to force generation to produce consisently ordered output later.
|
||||
- As each catagory of items is handled (types, methods, etc) a [postprocessor](objcgenerator-postprocessor.cs) walks the data.
|
||||
- This [postprocessor](objcgenerator-postprocessor.cs) analyzes each catagory looking for items that will cause trouble later in generation\compilation or produce suboptimal bindings:
|
||||
- Names that will produce identical selectors or shadow important pre-existing Objective-C selectors
|
||||
- Duplication detection is done via the [Type Mapper](TypeMapper.cs).
|
||||
- [Operator Overloads](OperatorOverloads.cs) can often be exposed in more friendly names than `op_Addition` and are renamed where possible. Where both "friendly" named and operator methods exist, we expose only one copy.
|
||||
- Each ["processed"](processedtypes.cs) data structure is then "frozen" so that we can cache generated data (such as names) only after no additional changes will occur. Processed types should now be considered effectively immutable.
|
||||
- Now that we have a hierarchy of ["processed"](processedtypes.cs) data types, we can finally enter the [ObjCGenerator](objcgenerator.cs).
|
||||
- [SourceWriters](sourcewriter.cs) are created for headers/private headers/implementations to buffer text until it is written to disk and readably handle indentation.
|
||||
- After writing the standard introduction parts to each file, each assembly is processed in turn.
|
||||
- Each Enum/Protocol/Type/Extension from that assembly is then generated in turn, each from a GenerateFoo method.
|
||||
- Some but not all Generation methods depend on "helpers" such as [ProtocolHelper](protocolhelper.cs) which help generate correct code.
|
||||
- [NameGenerator](NameGenerator.cs) contains the mapping between C# and Objective-C names for types/arguments.
|
||||
- If compilation is requested then the [Embedder's](embedder.cs) Compile () generates and executes clang invocations.
|
||||
- Special post processing occurs in some target types, frameworks for example, and may involve moving files / lipo / etc
|
|
@ -0,0 +1,19 @@
|
|||
### Tests
|
||||
|
||||
Given the task of processing arbitrary .NET assemblies and binding them to multiple languages, effective testing is crucial.
|
||||
|
||||
It is very easy for untested changes to regress previously working behavior. All new binding features should have both managed and unmanaged test to validate that they continue to work.
|
||||
|
||||
In the event that binding features are landed without test coverage on all supported platforms, [Github Issues](https://github.com/mono/Embeddinator-4000/issues) should be opened to track the testing defect.
|
||||
|
||||
The "managed" tests test the core binding functionality are come in three parts:
|
||||
|
||||
- A managed-*platform* (or fsharp-*platform*) C# library that compiles the same files from the shared project into a C# library specific to that platform (macOS, iOS, Android, etc)
|
||||
- A native (Objective-C, Java, C) application (objc-cli, android, common/Tests.C.cpp) which consumes the managed assembly after being bound and confirms expected behavior.
|
||||
- A managed nunit test (objcgentest, MonoEmbeddinator4000.Tests) which invokes Embeddinator to bind the managed test library to the specific platform and then invokes the native application to test the bindings.
|
||||
- C is the exception here, which uses the "Run-C-Tests" target in build/Tests.cake
|
||||
|
||||
- Beyond the "managed" tests, a few specialized test projects exist as well:
|
||||
- **MonoEmbeddinator4000.Tests** - Contains a number of Android specific tests as well
|
||||
- **leaktest** - A [test](tests/leaktest/README.md) that uses Apple's [leaks](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/leaks.1.html) to search for memory leaks.
|
||||
- **managedwarn** - Along with objcgentest/ObjCGenErrWarnTests.cs used to test a number of tool warning scenarios.
|
|
@ -0,0 +1,6 @@
|
|||
"diff" generates diffs of the managed test assembly before and after a generator change
|
||||
|
||||
### Usage
|
||||
|
||||
make baseline - compile managed.dll and save the output for comparision
|
||||
make compare - compile maanged.dll and compare to the saved output
|
Загрузка…
Ссылка в новой задаче