Browse Source

initial commit

master
boB Rudis 5 years ago
parent
commit
655d86c777
No known key found for this signature in database GPG Key ID: 1D7529BE14E2BBA9
  1. 32
      README.md
  2. 5
      rin-bridge-code/rin-test-Bridging-Header.h
  3. 26
      rin-bridge-code/rin-test-main.hpp
  4. 32
      rin-bridge-code/rin-test-main.mm
  5. 5
      rin-swift/AppDelegate.swift
  6. 0
      rin-swift/Assets.xcassets/AppIcon.appiconset/Contents.json
  7. 0
      rin-swift/Assets.xcassets/Contents.json
  8. 0
      rin-swift/Base.lproj/Main.storyboard
  9. 2
      rin-swift/ContentView.swift
  10. 2
      rin-swift/Info.plist
  11. 0
      rin-swift/Preview Content/Preview Assets.xcassets/Contents.json
  12. 5
      rin-swift/rin_test.entitlements
  13. 104
      rin-test.xcodeproj/project.pbxproj

32
README.md

@ -0,0 +1,32 @@
# Test of RInside with R 3.6, Xcode 11 & Swift 5 on macOS Catalina
This is a sample Xcode 11 project (a nigh vanilla/default SwiftUI project) which has:
- R 3.6
- [RInside](http://dirk.eddelbuettel.com/code/rinside.html)
- [Rcpp](http://www.rcpp.org/)
all setup including sample bridging code to enable function execution and data exchange between Swift 5 and R.
A few key things are included/set:
- Search paths:
- `/Library/Frameworks/R.framework/Headers/`
- `/Library/Frameworks/R.framework/Versions/3.6/Resources/library/RInside/include/`
- `/Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rcpp/include/`
- Frameworks, Libraries and Embedded Content:
- `/Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libR.dylib`
- `/Library/Frameworks/R.framework/Versions/3.6/Resources/library/RInside/lib/libRInside.dylib`
- Hardened Runtime is enabled with an entitlement of "Disable Library Validation" because the RInside and R shared libraries aren't codesigned (see `rin-swift/rin_test.entitlements`)
- one `.mm` file which lets Xcode know we're using Objective-C++. This is where you include things like `R.h`, `Rcpp.h`, and `RInside.h` or other C/C++ libraries
- one ^^ corresponding `.hpp` file that has *no* imports or includes of anything R/Rcpp-ish and defines the functions you're going to expose to Swift
- one bridging header (setup as as an "Objective C Bridging Header" under "Swift Compiler" in the General settings. This should just include ^^
- R (RInside) is initialized in the `AppDelegate.swift` and an example of calling functions with and without parameters is in `ContentView.swift`
There are quite a number of post-compilation yellow flags due to the R-ish headers but it builds and runs fine.
Built on the shoulders of:
- Brian Hall's old-ish (2015) [example](http://www.brianrhall.net/rss/linkingxcodecandrtocreateplots) of getting R to play nice with Xcode
- Ben Gorman's more recent (March, 2019) [example](https://www.gormanalysis.com/blog/using-rcpp-in-xcode/) of getting R 3.5 & RInside to play nice with Xcode
- Patrick Wardle's [example](https://github.com/objective-see/ProcInfo/) of getting C-ish things to work with Objective C)

5
rin-bridge-code/rin-test-Bridging-Header.h

@ -0,0 +1,5 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#include "rin-test-main.hpp"

26
rin-bridge-code/rin-test-main.hpp

@ -0,0 +1,26 @@
//
// rin-test-main.hpp
// rin-test
//
// Created by hrbrmstr on 8/26/19.
// Copyright © 2019 Bob Rudis. All rights reserved.
//
#ifndef rin_test_main_hpp
#define rin_test_main_hpp
#import <Foundation/Foundation.h>
#if defined(__cplusplus)
extern "C" {
#endif
void r_init();
double rcpp_mean(double one_more_val);
NSString *cpp_hello_world();
#if defined(__cplusplus)
}
#endif
#endif /* rin_test_main_hpp */

32
rin-bridge-code/rin-test-main.mm

@ -0,0 +1,32 @@
//
// rin-test-main.cpp
// rin-test
//
// Created by hrbrmstr on 8/26/19.
// Copyright © 2019 Bob Rudis. All rights reserved.
//
#include "rin-test-main.hpp"
#include <string>
#include <R.h>
#include <Rcpp.h>
#include <RInside.h>
void r_init() {
RInside R(0, NULL);
}
NSString *cpp_hello_world() {
std::string hw = "Hello, world!";
return([NSString stringWithUTF8String:hw.c_str()]);
}
double rcpp_mean(double one_more_val) {
Rcpp::NumericVector x = Rcpp::NumericVector::create(1, 2, 3, one_more_val);
return(Rcpp::mean(x));
}

5
rin-test/AppDelegate.swift → rin-swift/AppDelegate.swift

@ -17,6 +17,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
r_init() // INITIALIZE RInside!
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
@ -27,6 +30,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
window.contentView = NSHostingView(rootView: ContentView())
window.makeKeyAndOrderFront(nil)
}
func applicationWillTerminate(_ aNotification: Notification) {
@ -35,4 +39,3 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

0
rin-test/Assets.xcassets/AppIcon.appiconset/Contents.json → rin-swift/Assets.xcassets/AppIcon.appiconset/Contents.json

0
rin-test/Preview Content/Preview Assets.xcassets/Contents.json → rin-swift/Assets.xcassets/Contents.json

0
rin-test/Base.lproj/Main.storyboard → rin-swift/Base.lproj/Main.storyboard

2
rin-test/ContentView.swift → rin-swift/ContentView.swift

@ -10,7 +10,7 @@ import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello World")
Text((cpp_hello_world() as String) + " " + String(rcpp_mean(10.0)))
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}

2
rin-test/Info.plist → rin-swift/Info.plist

@ -20,6 +20,8 @@
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>

0
rin-test/Assets.xcassets/Contents.json → rin-swift/Preview Content/Preview Assets.xcassets/Contents.json

5
rin-test/rin_test.entitlements → rin-swift/rin_test.entitlements

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

104
rin-test.xcodeproj/project.pbxproj

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
@ -12,8 +12,28 @@
012D7DD2231416110083A67E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 012D7DD1231416110083A67E /* Assets.xcassets */; };
012D7DD5231416110083A67E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 012D7DD4231416110083A67E /* Preview Assets.xcassets */; };
012D7DD8231416110083A67E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 012D7DD6231416110083A67E /* Main.storyboard */; };
012D7DEF2314182D0083A67E /* rin-test-main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 012D7DED2314182D0083A67E /* rin-test-main.mm */; };
012D7DF02314188C0083A67E /* libR.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 012D7DE5231417F80083A67E /* libR.dylib */; };
012D7DF12314188C0083A67E /* libR.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 012D7DE5231417F80083A67E /* libR.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
012D7DF32314189A0083A67E /* libRInside.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 012D7DE9231418080083A67E /* libRInside.dylib */; };
012D7DF42314189A0083A67E /* libRInside.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 012D7DE9231418080083A67E /* libRInside.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
012D7DF22314188C0083A67E /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
012D7DF12314188C0083A67E /* libR.dylib in Embed Libraries */,
012D7DF42314189A0083A67E /* libRInside.dylib in Embed Libraries */,
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
012D7DCA2314160F0083A67E /* rin-test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "rin-test.app"; sourceTree = BUILT_PRODUCTS_DIR; };
012D7DCD2314160F0083A67E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -23,6 +43,13 @@
012D7DD7231416110083A67E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
012D7DD9231416110083A67E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
012D7DDA231416110083A67E /* rin_test.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = rin_test.entitlements; sourceTree = "<group>"; };
012D7DE1231417830083A67E /* libR.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libR.dylib; path = ../../../../Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libR.dylib; sourceTree = "<group>"; };
012D7DE5231417F80083A67E /* libR.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libR.dylib; path = ../../../../Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libR.dylib; sourceTree = "<group>"; };
012D7DE9231418080083A67E /* libRInside.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libRInside.dylib; path = ../../../../Library/Frameworks/R.framework/Versions/3.6/Resources/library/RInside/lib/libRInside.dylib; sourceTree = "<group>"; };
012D7DEC2314182D0083A67E /* rin-test-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "rin-test-Bridging-Header.h"; sourceTree = "<group>"; };
012D7DED2314182D0083A67E /* rin-test-main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "rin-test-main.mm"; sourceTree = "<group>"; };
012D7DEE2314182D0083A67E /* rin-test-main.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "rin-test-main.hpp"; sourceTree = "<group>"; };
012D7DF6231426DA0083A67E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -30,6 +57,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
012D7DF02314188C0083A67E /* libR.dylib in Frameworks */,
012D7DF32314189A0083A67E /* libRInside.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -39,8 +68,11 @@
012D7DC12314160F0083A67E = {
isa = PBXGroup;
children = (
012D7DCC2314160F0083A67E /* rin-test */,
012D7DF6231426DA0083A67E /* README.md */,
012D7DF5231426700083A67E /* rin-bridge-code */,
012D7DCC2314160F0083A67E /* rin-swift */,
012D7DCB2314160F0083A67E /* Products */,
012D7DE0231417830083A67E /* Frameworks */,
);
sourceTree = "<group>";
};
@ -52,18 +84,18 @@
name = Products;
sourceTree = "<group>";
};
012D7DCC2314160F0083A67E /* rin-test */ = {
012D7DCC2314160F0083A67E /* rin-swift */ = {
isa = PBXGroup;
children = (
012D7DCD2314160F0083A67E /* AppDelegate.swift */,
012D7DCF2314160F0083A67E /* ContentView.swift */,
012D7DD9231416110083A67E /* Info.plist */,
012D7DD1231416110083A67E /* Assets.xcassets */,
012D7DD6231416110083A67E /* Main.storyboard */,
012D7DD9231416110083A67E /* Info.plist */,
012D7DDA231416110083A67E /* rin_test.entitlements */,
012D7DD3231416110083A67E /* Preview Content */,
);
path = "rin-test";
path = "rin-swift";
sourceTree = "<group>";
};
012D7DD3231416110083A67E /* Preview Content */ = {
@ -74,6 +106,26 @@
path = "Preview Content";
sourceTree = "<group>";
};
012D7DE0231417830083A67E /* Frameworks */ = {
isa = PBXGroup;
children = (
012D7DE9231418080083A67E /* libRInside.dylib */,
012D7DE5231417F80083A67E /* libR.dylib */,
012D7DE1231417830083A67E /* libR.dylib */,
);
name = Frameworks;
sourceTree = "<group>";
};
012D7DF5231426700083A67E /* rin-bridge-code */ = {
isa = PBXGroup;
children = (
012D7DEC2314182D0083A67E /* rin-test-Bridging-Header.h */,
012D7DEE2314182D0083A67E /* rin-test-main.hpp */,
012D7DED2314182D0083A67E /* rin-test-main.mm */,
);
path = "rin-bridge-code";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -84,6 +136,7 @@
012D7DC62314160F0083A67E /* Sources */,
012D7DC72314160F0083A67E /* Frameworks */,
012D7DC82314160F0083A67E /* Resources */,
012D7DF22314188C0083A67E /* Embed Libraries */,
);
buildRules = (
);
@ -106,11 +159,12 @@
TargetAttributes = {
012D7DC92314160F0083A67E = {
CreatedOnToolsVersion = 11.0;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 012D7DC52314160F0083A67E /* Build configuration list for PBXProject "rin-test" */;
compatibilityVersion = "Xcode 9.3";
compatibilityVersion = "Xcode 10.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@ -147,6 +201,7 @@
files = (
012D7DD02314160F0083A67E /* ContentView.swift in Sources */,
012D7DCE2314160F0083A67E /* AppDelegate.swift in Sources */,
012D7DEF2314182D0083A67E /* rin-test-main.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -281,21 +336,34 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "rin-test/rin_test.entitlements";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "rin-swift/rin_test.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_ASSET_PATHS = "\"rin-test/Preview Content\"";
DEVELOPMENT_ASSET_PATHS = "\"rin-swift/Preview Content\"";
DEVELOPMENT_TEAM = CBY22P58G8;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "rin-test/Info.plist";
"HEADER_SEARCH_PATHS[arch=*]" = (
/Library/Frameworks/R.framework/Headers/,
/Library/Frameworks/R.framework/Versions/3.6/Resources/library/RInside/include/,
/Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rcpp/include/,
);
INFOPLIST_FILE = "rin-swift/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(LOCAL_LIBRARY_DIR)/Frameworks/R.framework/Versions/3.6/Resources/lib",
"$(LOCAL_LIBRARY_DIR)/Frameworks/R.framework/Versions/3.6/Resources/library/RInside/lib",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_BUNDLE_IDENTIFIER = "is.rud.bob.rin-test";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "rin-bridge-code/rin-test-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
@ -304,21 +372,33 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "rin-test/rin_test.entitlements";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "rin-swift/rin_test.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_ASSET_PATHS = "\"rin-test/Preview Content\"";
DEVELOPMENT_ASSET_PATHS = "\"rin-swift/Preview Content\"";
DEVELOPMENT_TEAM = CBY22P58G8;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = "rin-test/Info.plist";
"HEADER_SEARCH_PATHS[arch=*]" = (
/Library/Frameworks/R.framework/Headers/,
/Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rcpp/include/,
/Library/Frameworks/R.framework/Versions/3.6/Resources/library/RInside/include/,
);
INFOPLIST_FILE = "rin-swift/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(LOCAL_LIBRARY_DIR)/Frameworks/R.framework/Versions/3.6/Resources/lib",
"$(LOCAL_LIBRARY_DIR)/Frameworks/R.framework/Versions/3.6/Resources/library/RInside/lib",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_BUNDLE_IDENTIFIER = "is.rud.bob.rin-test";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "rin-bridge-code/rin-test-Bridging-Header.h";
SWIFT_VERSION = 5.0;
};
name = Release;

Loading…
Cancel
Save