23 Commits
Author SHA1 Message Date
NanoTech 1d0791226a Explain how to add a label in Interface Builder 2017-02-25 21:22:39 -06:00
NanoTech f4e9fe6d04 Add workaround for "Use of unresolved identifier" 2017-02-25 18:00:06 -06:00
NanoTech 23e63b31b6 Reset project module settings to match tutorial results
These are the default settings on a new Xcode
Swift project.

This fixes "Umbrella header 'SwiftAppLibrary.h'
not found" on clean builds.
2017-02-25 17:35:11 -06:00
NanoTech 5ccabf268b Switch project group order to match the reader's project 2017-02-25 17:31:19 -06:00
NanoTech 52703c2dc9 Need to build the framework after adding runNSApplication 2017-02-25 17:17:58 -06:00
NanoTech b545a3ae24 Add a screenshot for adding Run Script 2017-02-25 17:17:33 -06:00
NanoTech 8f52ca7cb9 Update Swift stdlib embed screenshot 2017-02-25 16:24:31 -06:00
NanoTech 624b296fa4 Add a step to remove @NSApplicationMain 2017-02-25 16:15:10 -06:00
NanoTech b4e8e344e1 Table of contents 2017-02-24 00:35:23 -06:00
NanoTech 6e2df7fc73 Add troubleshooting section 2017-02-24 00:35:23 -06:00
NanoTech 4a6f94a435 Add more clarification 2017-02-24 00:35:23 -06:00
NanoTech 7f46097382 Add flag references 2017-02-24 00:35:23 -06:00
NanoTech 6c24bf8649 Clarify the framework conversion section
Also, switch to embedding the Swift standard
libraries in the app's Frameworks directory.
It works just as well (@executable_path/../Frameworks
is one of the framework's rpaths) and is
consistent with typical Swift apps.
2017-02-24 00:35:23 -06:00
NanoTech ab21acac78 Describe script output 2017-02-24 00:35:23 -06:00
NanoTech 4e47c437f3 Order targets in addition order
To match what the reader will see in their project.
2017-02-24 00:35:23 -06:00
NanoTech 163d0d0a6d Improve link-deps.sh comments 2017-02-24 00:35:23 -06:00
NanoTech 3c0871874d Add a short introduction 2017-02-24 00:35:23 -06:00
NanoTech fcf526afb1 Instruct to build the framework before linking it 2017-02-21 18:59:28 -06:00
NanoTech 31d3a4771b Reminder to change EXECUTABLE_NAME if needed 2017-02-21 18:58:23 -06:00
NanoTech 7e9f47e85a Change some titles 2017-02-15 22:40:47 -06:00
NanoTech 4f82e89ba9 Update screenshots
- Crop the first two project creation screenshots
- Update and use the New Copy Files Phase screenshot
- Remove unused screenshots
2017-02-15 22:40:47 -06:00
NanoTech e504bbd81d Update Run Script input files 2017-02-15 22:40:47 -06:00
NanoTech 01fd35818c Fix linking with -whole-module-optimization enabled 2017-02-15 22:40:47 -06:00
25 changed files with 283 additions and 94 deletions
+257 -78
View File
@@ -1,14 +1,42 @@
# Integrating Haskell with Swift Mac Apps
In this tutorial, we'll create a Mac app using Swift and Xcode
to build the UI, and Haskell to implement backend logic.
A basic familiarity with Haskell, Swift, Objective-C, C, Xcode,
and shell scripting will be assumed.
### Table of Contents
1. [Project Setup](#project-setup)
2. [Exporting Haskell Functions](#exporting-haskell-functions)
3. [Importing Haskell's Generated FFI Headers into Swift](#importing-haskells-generated-ffi-headers-into-swift)
4. [Converting the Swift App to a Framework](#converting-the-swift-app-to-a-framework)
1. [Framework Configuration](#framework-configuration)
2. [App Bundle Configuration](#app-bundle-configuration)
5. [Linking to the Framework](#linking-to-the-framework)
6. [Starting Cocoa](#starting-cocoa)
7. [Linking to the Executable](#linking-to-the-executable)
8. [Calling Haskell from Swift](#calling-haskell-from-swift)
9. [Passing Complex Data Types](#passing-complex-data-types)
1. [Bytes](#bytes)
2. [Functions and Closures](#functions-and-closures)
10. [Troubleshooting](#troubleshooting)
## Project Setup
To start, create a new Cocoa Application Xcode project
with Swift as the default language:
![Select the Cocoa app template](tutorial/xcode-cocoa-template.png)
![Select the Cocoa app template](tutorial/xcode-cocoa-template-icon.png)
![Create a new project](tutorial/xcode-create-project.png)
with Swift as the default language.
Then `cd` into the directory with the `.xcodeproj` and create a
new stack project:
![Select Swift as the default language](tutorial/xcode-create-project-language-swift.png)
Name the project SwiftHaskell.
`cd` into the directory with the `.xcodeproj` and create a new
stack project:
```sh
$ cd SwiftHaskell
@@ -136,7 +164,9 @@ create a symlink to the built executable's location for later.
#!/usr/bin/env bash
set -eu
# Change EXECUTABLE_NAME to the name of your Haskell executable.
EXECUTABLE_NAME=SwiftHaskell
DIST_DIR="$(stack path --dist-dir)"
GHC_VERSION="$(stack exec -- ghc --numeric-version)"
GHC_LIB_DIR="$(stack path --compiler-bin)/../lib/ghc-$GHC_VERSION"
@@ -159,53 +189,116 @@ module_map="${module_map} export *${NL}"
module_map="${module_map}}"
echo "${module_map}" > "${STUB_MODULE_MAP}"
# Symlink to the current GHC's header directory from a more
# convenient place for Xcode to find.
# Symlink to the current GHC's header directory so we can add it
# to Xcode's include path as $(PROJECT_DIR)/build/ghc/include.
mkdir -p build/ghc
ln -sf "${GHC_LIB_DIR}/include" build/ghc/
# Symlink to the Haskell executable for Xcode.
# Symlink to the Haskell executable so we can easily drag it
# into Xcode to use as the executable for the app bundle.
ln -sf "../${DIST_DIR}/build/${EXECUTABLE_NAME}/${EXECUTABLE_NAME}" build/
```
Change the value of the `EXECUTABLE_NAME` variable to the
name of the executable in your `.cabal` file if you named it
something other than SwiftHaskell.
Save the script as `link-deps.sh`, run `stack build`, and then
run `bash link-deps.sh` to prepare for the next section.
Running the script will create
`SwiftHaskell/include/module.modulemap` and two symlinks in
the project's `build/` directory:
- `SwiftHaskell` `-> ../.stack-work/dist/{arch}/Cabal-{version}/build/SwiftHaskell/SwiftHaskell`
- `ghc`
- `include` `-> ~/.stack/programs/{arch}/ghc-{version}/bin/../lib/ghc-{version}/include`
Text marked as `{}` will vary.
## Converting the Swift App to a Framework
Create a new Cocoa Framework target in the Xcode project
named SwiftAppLibrary, then change the Target Membership of
`AppDelegate.swift` and `MainMenu.xib` to only SwiftAppLibrary
in Xcode's File Inspector in the right sidebar:
Create a new Cocoa Framework target in the Xcode project,
![Select the Cocoa Framework template](tutorial/xcode-cocoa-framework-template-icon.png)
with Swift as the default language.
![Select Swift as the default language](tutorial/xcode-create-project-language-swift.png)
Name the framework SwiftAppLibrary.
### Framework Configuration
To move over our application code and UI, change the Target
Membership of `AppDelegate.swift` and `MainMenu.xib` in Xcode's
File Inspector in the right sidebar so that they are only
included in SwiftAppLibrary:
![Target Membership](tutorial/xcode-target-membership.png)
In the new framework's build settings, set **Always Embed Swift
Standard Libraries** to **Yes**.
In `AppDelegate.swift`, remove the `@NSApplicationMain`
attribute from the `AppDelegate` class, as we don't want an
auto-generated `main` function in our framework. We will
implement an equivalent way to start Cocoa later, to be called
from the Haskell executable's `main`.
Drag the `SwiftHaskell` executable we built previously with
Stack into Xcode from the `build/` directory that we symlinked
it into, but do not add it to any targets when prompted:
Xcode will place the built framework in a temporary directory
(`~/Library/Developer/Xcode/DerivedData/`) with an unpredictable
subpath. So that Cabal will be able to find the framework for
linking, add a new **Run Script** build phase
![The SwiftHaskell executable in Xcode](tutorial/xcode-files-swifthaskell-executable.png)
![New Run Script Phase](tutorial/xcode-new-framework-run-script-phase.png)
In the SwiftHaskell app target's Build Phases, remove the
**Compile Sources** and **Link Binary With Libraries**
phases, and add a new **Copy Files** phase that copies the
`SwiftHaskell` executable into the app bundle's Executables
directory:
![Copy into Executables](tutorial/xcode-copy-files-swifthaskell-executable.png)
Finally, in the SwiftAppLibrary framework target's Build Phases,
add a new **Run Script** phase to create a symlink to the built
framework for us to link to from Cabal:
that creates a symlink to the built framework in `build/`:
```sh
set -u
ln -sf "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}" "${PROJECT_DIR}/build/"
```
### App Bundle Configuration
Drag the `SwiftHaskell` executable we built previously with
Stack into Xcode from the `build/` directory that we symlinked
it into,
![The SwiftHaskell executable in Xcode](tutorial/xcode-drag-swifthaskell-executable.png)
but do not add it to any targets when prompted:
![Do not add the executable to any targets](tutorial/xcode-add-to-no-targets.png)
When Xcode creates Swift frameworks, it expects that the
application that links the framework will include the Swift
standard libraries. Xcode automatically adds these libraries to
Swift applications. Since our application executable is built
with Haskell and not Swift, we'll need to explicitly tell Xcode
to include the Swift standard libraries in our application.
In the app target's Build Settings tab, set **Always Embed Swift
Standard Libraries** to **Yes**:
![Always Embed Swift Standard Libraries: Yes](tutorial/xcode-embed-swift-standard-libs.png)
In the app target's Build Phases, remove the **Compile Sources**
and **Link Binary With Libraries** phases. We are using Stack to
build the app's executable instead of Xcode.
Add a new **Copy Files** phase that copies the `SwiftHaskell`
executable into the app bundle's Executables directory:
![New Copy Files Phase](tutorial/xcode-new-copy-files-phase.png)
![Select the executable](tutorial/xcode-choose-executable.png)
![Copy into Executables](tutorial/xcode-copy-files-swifthaskell-executable.png)
Build the SwiftAppLibrary framework in Xcode to prepare for the
next sections.
![Select the SwiftAppLibrary target](tutorial/xcode-select-framework-target.png)
## Linking to the Framework
Add these options to the executable's section in the `.cabal`
@@ -226,35 +319,48 @@ executable SwiftHaskell
executable where the dynamic linker should look for shared
libraries.
## Starting the GUI
See [the Flag Reference in the GHC Users'
Guide][ghc-guide-flags] and [`man 1 ld`][man-ld] for more details.
[ghc-guide-flags]: https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/flags.html
[man-ld]: x-man-page://1/ld
## Starting Cocoa
Because Haskell has control over the program's entry point
(`main`), we'll need to have it call out to Swift to
start Cocoa's main thread. Add this top level function to
`AppDelegate.swift`:
```swift
@_cdecl("runNSApplication")
func runNSApplication() {
let app = NSApplication.shared()
var topObjects: NSArray = []
NSNib.init(nibNamed: "MainMenu", bundle: Bundle(for: AppDelegate.self))!
.instantiate(withOwner: app, topLevelObjects: &topObjects)
app.run()
}
```
`@_cdecl` sets the symbol name of the Swift function, overriding
normal symbol mangling.
In `SwiftAppLibrary.h`, add a `FOUNDATION_EXPORT` C prototype
for the function, so that its symbol gets marked as public and
is exported from the framework:
(`main`), we'll need to have it call out to Cocoa to start its
main thread. In `SwiftAppLibrary.h`, declare a new function
named `runNSApplication` and mark it as `FOUNDATION_EXPORT` to
indicate that it should be exported from the framework:
```c
FOUNDATION_EXPORT void runNSApplication(void);
```
Implement the function by adding a new Objective-C `.m` file to
the framework target containing
```objective-c
#import "SwiftAppLibrary.h"
@interface AClassInThisFramework : NSObject @end
@implementation AClassInThisFramework @end
void runNSApplication(void) {
NSApplication *app = [NSApplication sharedApplication];
NSBundle *bundle = [NSBundle bundleForClass:[AClassInThisFramework class]];
NSArray *topObjects;
[[[NSNib alloc] initWithNibNamed:@"MainMenu" bundle:bundle]
instantiateWithOwner:app topLevelObjects:&topObjects];
[app run];
}
```
This *is* possible to write in Swift, however as of Swift 3.0.2,
the annotation to export unmangled C symbols (`@_cdecl`) is not
documented as stable. Additionally, whole module optimization
will assume that `@_cdecl` symbols are unused and remove them.
In `Main.hs`, import the foreign function and call it from
the end of `main`:
@@ -280,21 +386,24 @@ main = do
main run loop. Use `Control.Concurrent.forkIO` before calling
`runNSApplication` to run other tasks as needed.
Run `stack build`, and build and run the `SwiftHaskell` app
target in Xcode to launch the app and see the default window
from `MainMenu.xib`:
Build the `SwiftHaskellLibrary` framework in Xcode, then `stack
build`, and then finally build and run the `SwiftHaskell`
app target to launch the app and see the default window from
`MainMenu.xib`:
![A blank window](tutorial/empty-app.png)
## Completing Linking Setup
## Linking to the Executable
Add `$(PROJECT_DIR)/SwiftHaskell/include` to the framework
target's **Swift Compiler - Search Paths, Import Paths** setting
in Xcode,
To tell Xcode where to find our `module.modulemap`, add
`$(PROJECT_DIR)/SwiftHaskell/include` to the framework target's
**Swift Compiler - Search Paths, Import Paths** setting in
Xcode,
![The Swift module import paths](tutorial/xcode-swift-module-search-paths.png)
and `$(PROJECT_DIR)/build/ghc/include` to the framework's **User
and, for the GHC headers the module depends on, add
`$(PROJECT_DIR)/build/ghc/include` to the framework's **User
Header Search Paths** setting:
![The User Header Search Paths](tutorial/xcode-header-search-paths.png)
@@ -303,14 +412,14 @@ In order for the framework to be able to link to symbols in the
Haskell executable, we need to tell the linker to leave symbols
undefined and have them be resolved at runtime.
Add `-undefined dynamic_lookup` to the framework's **Other
Linker Flags** setting.
Add [`-undefined dynamic_lookup`][man-ld] to the framework's
**Other Linker Flags** setting.
Be aware that this means that link errors will occur at runtime
instead of at link time. Also note that the framework linking
to symbols in the executable (and depending on the generated
headers), and the executable linking to the framework, creates
a circular dependency. When initially building the project, you
a circular dependency. When building the project clean, you
will need to build the components in this order:
- `stack build` to generate the Haskell FFI export headers.
@@ -335,6 +444,7 @@ Add the Haskell sources as input files:
```
$(PROJECT_DIR)/src/Main.hs
$(PROJECT_DIR)/SwiftHaskellLibrary.cabal
$(PROJECT_DIR)/stack.yaml
```
And the executable as an output file:
@@ -361,23 +471,39 @@ main = defaultMainWithHooks $ simpleUserHooks
## Calling Haskell from Swift
We're now ready to use exported Haskell functions from Swift.
Import `SwiftHaskell` at the top of `AppDelegate.swift`
Import the module we defined in our `module.modulemap`,
`SwiftHaskell`, at the top of `AppDelegate.swift`:
```swift
import SwiftHaskell
```
Add a new label to the window in `MainMenu.xib` for us to write
the result of our Haskell function `square` into, and add it as
an `@IBOutlet` to the `AppDelegate`:
Let's add a new label to the window for us to write the result
of our Haskell function `square` into. Open `MainMenu.xib` and
select the window object in the left sidebar to bring it into
view. Then drag in a label from the object library in the right
sidebar into the window:
![Add a label](tutorial/xcode-ib-add-label.png)
Now option-click on `AppDelegate.swift` in the file list to open
it in an assistant editor. Holding the control key, drag the
label from the window into the `AppDelegate` class to add and
connect a new `@IBOutlet`:
![Add and connect the label outlet](tutorial/xcode-ib-add-label-outlet.png)
![Name the outlet](tutorial/xcode-ib-label-outlet-dialog.png)
Adding the outlet will add a new property to the `AppDelegate`:
```swift
@IBOutlet weak var label: NSTextField!
```
We already have our Haskell library's header imported, so we
can just call the exported `square` function. Add this to
`applicationDidFinishLaunching`:
With the `SwiftHaskell` module imported and a label connected,
let's call `square` and display its result in the label. Add
this to `applicationDidFinishLaunching`:
```swift
label.stringValue = "\(square(5))"
@@ -401,21 +527,20 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationWillTerminate(_ aNotification: Notification) {
}
}
@_cdecl("swiftAppMain")
func swiftAppMain() {
let app = NSApplication.shared()
var topObjects: NSArray = []
NSNib.init(nibNamed: "MainMenu", bundle: Bundle(for: AppDelegate.self))!
.instantiate(withOwner: app, topLevelObjects: &topObjects)
app.run()
}
```
Running the app,
![5 squared](tutorial/squared.png)
If the build fails with `Use of unresolved identifier 'square'`,
perform a full clean with the *Product » Clean Build Folder...*
⌥⇧⌘K menu command and then rebuild. (Hold ⌥ option to reveal
the menu item.) This appears to be a bug with Xcode (version
8.2 as of writing) caching some intermediate state from before
the `SwiftHaskell` module was fully configured, and should not
occur in future builds.
## Passing Complex Data Types
### Bytes
@@ -743,3 +868,57 @@ class Multiplier {
}
}
```
## Troubleshooting
### `stack build` fails with `ld: framework not found SwiftHaskellLibrary`
Build the SwiftHaskellLibrary framework in Xcode before running
`stack build`.
![Select the SwiftAppLibrary target](tutorial/xcode-select-framework-target.png)
See the discussion about circular dependencies in the *Linking
to the Executable* section. If this still fails, ensure that
`link-deps.sh` is being run before the framework is built as
described at the end of *Linking to the Executable*. Also check
that the `build/` directory contains all three symlinks:
- `SwiftAppLibrary.framework` `-> ~/Library/Developer/Xcode/DerivedData/SwiftHaskell-{hash}/Build/Products/{Debug,Release}/SwiftAppLibrary.framework`
- `SwiftHaskell` `-> ../.stack-work/dist/{arch}/Cabal-{version}/build/SwiftHaskell/SwiftHaskell`
- `ghc`
- `include` `-> ~/.stack/programs/{arch}/ghc-{version}/bin/../lib/ghc-{version}/include`
### Building in Xcode fails with `PBXCp ...build/SwiftHaskell/SwiftHaskell: No such file or directory`
Build the Haskell executable with `stack build`.
### Some Target Membership checkboxes are disabled in Xcode
Add a Compile Sources or Copy Bundle Resources phase, as
appropriate for the file you're modifying, to the target with
the disabled checkbox.
### Building in Xcode fails with `Unable to run command ... - this target might include its own product.`
Ensure that the Copy Files phase for the executable is copying
the executable, and not the app bundle (the product). See the
*App Bundle Configuration* section.
![Copy into Executables](tutorial/xcode-copy-files-swifthaskell-executable.png)
### Running the app fails with `dyld: Library not loaded: @rpath/libswiftAppKit.dylib`
Ensure that **Always Embed Swift Standard Libraries** is set
to **Yes** on the app target, as described in *App Bundle
Configuration*.
![Always Embed Swift Standard Libraries: Yes](tutorial/xcode-embed-swift-standard-libs.png)
### Building in Xcode fails with `Use of unresolved identifier 'square'`
If the module is certainly imported, this is probably from Xcode
incorrectly retaining an expired cache for the `SwiftHaskell`
module. Perform a full clean with the *Product » Clean Build
Folder...* ⌥⇧⌘K menu command and then rebuild. (Hold ⌥ option to
reveal the menu item.)
-9
View File
@@ -37,15 +37,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}
@_cdecl("runNSApplication")
func runNSApplication() {
let app = NSApplication.shared()
var topObjects: NSArray = []
NSNib.init(nibNamed: "MainMenu", bundle: Bundle(for: AppDelegate.self))!
.instantiate(withOwner: app, topLevelObjects: &topObjects)
app.run()
}
// Swift to Haskell ByteString Example
+13
View File
@@ -0,0 +1,13 @@
#import "SwiftAppLibrary.h"
@interface AClassInThisFramework : NSObject @end
@implementation AClassInThisFramework @end
void runNSApplication(void) {
NSApplication *app = [NSApplication sharedApplication];
NSBundle *bundle = [NSBundle bundleForClass:[AClassInThisFramework class]];
NSArray *topObjects;
[[[NSNib alloc] initWithNibNamed:@"MainMenu" bundle:bundle]
instantiateWithOwner:app topLevelObjects:&topObjects];
[app run];
}
+13 -7
View File
@@ -13,6 +13,7 @@
BFABC4E01E4D781D006036C6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BFABC4DF1E4D781D006036C6 /* Assets.xcassets */; };
BFABC4ED1E4D78E5006036C6 /* SwiftHaskell in Copy Files */ = {isa = PBXBuildFile; fileRef = BFABC4EA1E4D78D9006036C6 /* SwiftHaskell */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
BFABC4F01E4D7951006036C6 /* SwiftAppLibrary.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFABC45B1E4C1DD1006036C6 /* SwiftAppLibrary.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BFE4CC421E55553000F232D6 /* SwiftAppLibrary.m in Sources */ = {isa = PBXBuildFile; fileRef = BFE4CC411E55553000F232D6 /* SwiftAppLibrary.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -60,6 +61,7 @@
BFABC4DF1E4D781D006036C6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
BFABC4E41E4D781D006036C6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BFABC4EA1E4D78D9006036C6 /* SwiftHaskell */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = SwiftHaskell; path = build/SwiftHaskell; sourceTree = SOURCE_ROOT; };
BFE4CC411E55553000F232D6 /* SwiftAppLibrary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SwiftAppLibrary.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -76,8 +78,8 @@
BFABC4511E4C1DD1006036C6 = {
isa = PBXGroup;
children = (
BFABC45D1E4C1DD1006036C6 /* SwiftAppLibrary */,
BFABC4D81E4D781D006036C6 /* SwiftHaskell */,
BFABC45D1E4C1DD1006036C6 /* SwiftAppLibrary */,
BFABC45C1E4C1DD1006036C6 /* Products */,
);
sourceTree = "<group>";
@@ -95,6 +97,7 @@
isa = PBXGroup;
children = (
BFABC45E1E4C1DD1006036C6 /* SwiftAppLibrary.h */,
BFE4CC411E55553000F232D6 /* SwiftAppLibrary.m */,
BFABC4CC1E4D627E006036C6 /* AppDelegate.swift */,
BFABC4D01E4D664D006036C6 /* MainMenu.xib */,
BFABC45F1E4C1DD1006036C6 /* Info.plist */,
@@ -197,8 +200,8 @@
projectDirPath = "";
projectRoot = "";
targets = (
BFABC45A1E4C1DD1006036C6 /* SwiftAppLibrary */,
BFABC4D61E4D781D006036C6 /* SwiftHaskell */,
BFABC45A1E4C1DD1006036C6 /* SwiftAppLibrary */,
);
};
/* End PBXProject section */
@@ -229,9 +232,9 @@
files = (
);
inputPaths = (
"$(PROJECT_DIR)/src/Lib.hs",
"$(PROJECT_DIR)/src/Main.hs",
"$(PROJECT_DIR)/SwiftHaskellLibrary.cabal",
"$(PROJECT_DIR)/stack.yaml",
);
name = "stack build and link-deps";
outputPaths = (
@@ -266,6 +269,7 @@
buildActionMask = 2147483647;
files = (
BFABC4CD1E4D627E006036C6 /* AppDelegate.swift in Sources */,
BFE4CC421E55553000F232D6 /* SwiftAppLibrary.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -296,10 +300,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
@@ -348,10 +352,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
@@ -391,7 +395,7 @@
BFABC4641E4C1DD1006036C6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
@@ -419,7 +423,7 @@
BFABC4651E4C1DD1006036C6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
@@ -446,6 +450,7 @@
BFABC4E61E4D781D006036C6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = SwiftHaskell/Info.plist;
@@ -458,6 +463,7 @@
BFABC4E71E4D781D006036C6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = SwiftHaskell/Info.plist;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB