Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d0791226a | ||
|
|
f4e9fe6d04 | ||
|
|
23e63b31b6 | ||
|
|
5ccabf268b | ||
|
|
52703c2dc9 | ||
|
|
b545a3ae24 | ||
|
|
8f52ca7cb9 | ||
|
|
624b296fa4 | ||
|
|
b4e8e344e1 | ||
|
|
6e2df7fc73 | ||
|
|
4a6f94a435 | ||
|
|
7f46097382 | ||
|
|
6c24bf8649 | ||
|
|
ab21acac78 | ||
|
|
4e47c437f3 | ||
|
|
163d0d0a6d | ||
|
|
3c0871874d | ||
|
|
fcf526afb1 | ||
|
|
31d3a4771b | ||
|
|
7e9f47e85a | ||
|
|
4f82e89ba9 | ||
|
|
e504bbd81d | ||
|
|
01fd35818c |
@@ -1,5 +1,30 @@
|
|||||||
# Integrating Haskell with Swift Mac Apps
|
# 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
|
To start, create a new Cocoa Application Xcode project
|
||||||
|
|
||||||

|

|
||||||
@@ -8,8 +33,10 @@ with Swift as the default language.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Then `cd` into the directory with the `.xcodeproj` and create a
|
Name the project SwiftHaskell.
|
||||||
new stack project:
|
|
||||||
|
`cd` into the directory with the `.xcodeproj` and create a new
|
||||||
|
stack project:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ cd SwiftHaskell
|
$ cd SwiftHaskell
|
||||||
@@ -137,7 +164,9 @@ create a symlink to the built executable's location for later.
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
|
# Change EXECUTABLE_NAME to the name of your Haskell executable.
|
||||||
EXECUTABLE_NAME=SwiftHaskell
|
EXECUTABLE_NAME=SwiftHaskell
|
||||||
|
|
||||||
DIST_DIR="$(stack path --dist-dir)"
|
DIST_DIR="$(stack path --dist-dir)"
|
||||||
GHC_VERSION="$(stack exec -- ghc --numeric-version)"
|
GHC_VERSION="$(stack exec -- ghc --numeric-version)"
|
||||||
GHC_LIB_DIR="$(stack path --compiler-bin)/../lib/ghc-$GHC_VERSION"
|
GHC_LIB_DIR="$(stack path --compiler-bin)/../lib/ghc-$GHC_VERSION"
|
||||||
@@ -160,55 +189,116 @@ module_map="${module_map} export *${NL}"
|
|||||||
module_map="${module_map}}"
|
module_map="${module_map}}"
|
||||||
echo "${module_map}" > "${STUB_MODULE_MAP}"
|
echo "${module_map}" > "${STUB_MODULE_MAP}"
|
||||||
|
|
||||||
# Symlink to the current GHC's header directory from a more
|
# Symlink to the current GHC's header directory so we can add it
|
||||||
# convenient place for Xcode to find.
|
# to Xcode's include path as $(PROJECT_DIR)/build/ghc/include.
|
||||||
mkdir -p build/ghc
|
mkdir -p build/ghc
|
||||||
ln -sf "${GHC_LIB_DIR}/include" 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/
|
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
|
Save the script as `link-deps.sh`, run `stack build`, and then
|
||||||
run `bash link-deps.sh` to prepare for the next section.
|
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
|
## Converting the Swift App to a Framework
|
||||||
|
|
||||||
Create a new Cocoa Framework target in the Xcode project
|
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:
|
|
||||||
|
with Swift as the default language.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
In the new framework's build settings, set **Always Embed Swift
|
In `AppDelegate.swift`, remove the `@NSApplicationMain`
|
||||||
Standard Libraries** to **Yes**.
|
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
|
Xcode will place the built framework in a temporary directory
|
||||||
Stack into Xcode from the `build/` directory that we symlinked
|
(`~/Library/Developer/Xcode/DerivedData/`) with an unpredictable
|
||||||
it into, but do not add it to any targets when prompted:
|
subpath. So that Cabal will be able to find the framework for
|
||||||
|
linking, add a new **Run Script** build phase
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
In the SwiftHaskell app target's Build Phases, remove the
|
that creates a symlink to the built framework in `build/`:
|
||||||
**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:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
set -u
|
set -u
|
||||||
ln -sf "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}" "${PROJECT_DIR}/build/"
|
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,
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
but do not add it to any targets when prompted:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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**:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Build the SwiftAppLibrary framework in Xcode to prepare for the
|
||||||
|
next sections.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Linking to the Framework
|
## Linking to the Framework
|
||||||
|
|
||||||
Add these options to the executable's section in the `.cabal`
|
Add these options to the executable's section in the `.cabal`
|
||||||
@@ -229,6 +319,12 @@ executable SwiftHaskell
|
|||||||
executable where the dynamic linker should look for shared
|
executable where the dynamic linker should look for shared
|
||||||
libraries.
|
libraries.
|
||||||
|
|
||||||
|
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
|
## Starting Cocoa
|
||||||
|
|
||||||
Because Haskell has control over the program's entry point
|
Because Haskell has control over the program's entry point
|
||||||
@@ -290,21 +386,24 @@ main = do
|
|||||||
main run loop. Use `Control.Concurrent.forkIO` before calling
|
main run loop. Use `Control.Concurrent.forkIO` before calling
|
||||||
`runNSApplication` to run other tasks as needed.
|
`runNSApplication` to run other tasks as needed.
|
||||||
|
|
||||||
Run `stack build`, and build and run the `SwiftHaskell` app
|
Build the `SwiftHaskellLibrary` framework in Xcode, then `stack
|
||||||
target in Xcode to launch the app and see the default window
|
build`, and then finally build and run the `SwiftHaskell`
|
||||||
from `MainMenu.xib`:
|
app target to launch the app and see the default window from
|
||||||
|
`MainMenu.xib`:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Linking to the Executable
|
## Linking to the Executable
|
||||||
|
|
||||||
Add `$(PROJECT_DIR)/SwiftHaskell/include` to the framework
|
To tell Xcode where to find our `module.modulemap`, add
|
||||||
target's **Swift Compiler - Search Paths, Import Paths** setting
|
`$(PROJECT_DIR)/SwiftHaskell/include` to the framework target's
|
||||||
in Xcode,
|
**Swift Compiler - Search Paths, Import Paths** setting in
|
||||||
|
Xcode,
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
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:
|
Header Search Paths** setting:
|
||||||
|
|
||||||

|

|
||||||
@@ -313,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
|
Haskell executable, we need to tell the linker to leave symbols
|
||||||
undefined and have them be resolved at runtime.
|
undefined and have them be resolved at runtime.
|
||||||
|
|
||||||
Add `-undefined dynamic_lookup` to the framework's **Other
|
Add [`-undefined dynamic_lookup`][man-ld] to the framework's
|
||||||
Linker Flags** setting.
|
**Other Linker Flags** setting.
|
||||||
|
|
||||||
Be aware that this means that link errors will occur at runtime
|
Be aware that this means that link errors will occur at runtime
|
||||||
instead of at link time. Also note that the framework linking
|
instead of at link time. Also note that the framework linking
|
||||||
to symbols in the executable (and depending on the generated
|
to symbols in the executable (and depending on the generated
|
||||||
headers), and the executable linking to the framework, creates
|
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:
|
will need to build the components in this order:
|
||||||
|
|
||||||
- `stack build` to generate the Haskell FFI export headers.
|
- `stack build` to generate the Haskell FFI export headers.
|
||||||
@@ -372,23 +471,39 @@ main = defaultMainWithHooks $ simpleUserHooks
|
|||||||
## Calling Haskell from Swift
|
## Calling Haskell from Swift
|
||||||
|
|
||||||
We're now ready to use exported Haskell functions 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
|
```swift
|
||||||
import SwiftHaskell
|
import SwiftHaskell
|
||||||
```
|
```
|
||||||
|
|
||||||
Add a new label to the window in `MainMenu.xib` for us to write
|
Let's add a new label to the window for us to write the result
|
||||||
the result of our Haskell function `square` into, and add it as
|
of our Haskell function `square` into. Open `MainMenu.xib` and
|
||||||
an `@IBOutlet` to the `AppDelegate`:
|
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:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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`:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Adding the outlet will add a new property to the `AppDelegate`:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
@IBOutlet weak var label: NSTextField!
|
@IBOutlet weak var label: NSTextField!
|
||||||
```
|
```
|
||||||
|
|
||||||
We already have our Haskell library's header imported, so we
|
With the `SwiftHaskell` module imported and a label connected,
|
||||||
can just call the exported `square` function. Add this to
|
let's call `square` and display its result in the label. Add
|
||||||
`applicationDidFinishLaunching`:
|
this to `applicationDidFinishLaunching`:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
label.stringValue = "\(square(5))"
|
label.stringValue = "\(square(5))"
|
||||||
@@ -412,21 +527,20 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
func applicationWillTerminate(_ aNotification: Notification) {
|
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,
|
Running the app,
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
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
|
## Passing Complex Data Types
|
||||||
|
|
||||||
### Bytes
|
### Bytes
|
||||||
@@ -754,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`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 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*.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 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.)
|
||||||
|
|||||||
@@ -78,8 +78,8 @@
|
|||||||
BFABC4511E4C1DD1006036C6 = {
|
BFABC4511E4C1DD1006036C6 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
BFABC45D1E4C1DD1006036C6 /* SwiftAppLibrary */,
|
|
||||||
BFABC4D81E4D781D006036C6 /* SwiftHaskell */,
|
BFABC4D81E4D781D006036C6 /* SwiftHaskell */,
|
||||||
|
BFABC45D1E4C1DD1006036C6 /* SwiftAppLibrary */,
|
||||||
BFABC45C1E4C1DD1006036C6 /* Products */,
|
BFABC45C1E4C1DD1006036C6 /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -200,8 +200,8 @@
|
|||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
BFABC45A1E4C1DD1006036C6 /* SwiftAppLibrary */,
|
|
||||||
BFABC4D61E4D781D006036C6 /* SwiftHaskell */,
|
BFABC4D61E4D781D006036C6 /* SwiftHaskell */,
|
||||||
|
BFABC45A1E4C1DD1006036C6 /* SwiftAppLibrary */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
@@ -300,10 +300,10 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
@@ -352,10 +352,10 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
|
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
@@ -395,7 +395,7 @@
|
|||||||
BFABC4641E4C1DD1006036C6 /* Debug */ = {
|
BFABC4641E4C1DD1006036C6 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
@@ -423,7 +423,7 @@
|
|||||||
BFABC4651E4C1DD1006036C6 /* Release */ = {
|
BFABC4651E4C1DD1006036C6 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
@@ -450,6 +450,7 @@
|
|||||||
BFABC4E61E4D781D006036C6 /* Debug */ = {
|
BFABC4E61E4D781D006036C6 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
INFOPLIST_FILE = SwiftHaskell/Info.plist;
|
INFOPLIST_FILE = SwiftHaskell/Info.plist;
|
||||||
@@ -462,6 +463,7 @@
|
|||||||
BFABC4E71E4D781D006036C6 /* Release */ = {
|
BFABC4E71E4D781D006036C6 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
INFOPLIST_FILE = SwiftHaskell/Info.plist;
|
INFOPLIST_FILE = SwiftHaskell/Info.plist;
|
||||||
|
|||||||
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |