Open amirrajan opened 6 years ago
For such issues, do you want the community to write somewhere else and then provide a link or is there somewhere official?
If it's written here, it'll make it on to rubymotion.com/rubymotion-applied (when I get that wired up).
For Obj-C:
$ motion create rm-static-lib
Add foo.rb to your RubyMotion project:
class Foo
def foo
NSLog "This is the #foo method written in RubyMotion"
end
end
class NSString
def bar
NSLog "This is the #bar added to NSString extension method, written in RubyMotion"
end
end
$ rake static
Copy rm-static-lib-universal.a into Xcode project directory
Add (drag) rm-static-lib-universal.a into Xcode project
Click on project in Xcode, Target, Build Phases, under Link Binary With Libraries, add:
Rename your AppDelegate class, to eg. RMAppDelegate.
Change main() in main.m to:
int main(int argc, char * argv[]) {
@autoreleasepool {
void RubyMotionInit(int, char **);
RubyMotionInit(argc, argv);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([RMAppDelegate class]));
}
}
Fill it with:
#import <UIKit/UIKit.h>
@interface Foo : NSObject
- (void)foo;
@end
@interface NSString()
- (void)bar;
@end
Add:
#import "RM-Lib.h"
Add:
Foo* f = [Foo new];
[f foo];
[@"abc" bar];
This is the #foo method written in RubyMotion
This is the #bar added to NSString extension method, written in RubyMotion
I am just trying it.
When I execute rake static
, I got an error.
TypeError: no implicit conversion of nil into String
/Users/ISD/.rubymotion/rubymotion-templates/motion/project/template/ios.rb:345:in `+'
/Users/ISD/.rubymotion/rubymotion-templates/motion/project/template/ios.rb:345:in `block (2 levels) in <top (required)>'
/Users/ISD/.rubymotion/rubymotion-templates/motion/project/template/ios.rb:344:in `map'
/Users/ISD/.rubymotion/rubymotion-templates/motion/project/template/ios.rb:344:in `block in <top (required)>'
I found, If I put motion-cocoapods to Gemfile, rake static is failed.
I make a new project.
Put gem 'motion-cocoapods'
to Gemfile.
Then reproduce the error.
do you have a sample? Was there a specific template you used?
I put a sample here.
https://github.com/katsuyoshi/rm-static-lib-error-with-cocoapod
Although I didn't specify any template, it uses ios template.
I'll take a look Monday 👍
I tried @hboon 's steps with Xcode 10.2 (10E125) RM version is 6.1
1. libstdc++.tbd is missing. I used libc++.tbd instead of it.
2. There is an error with building for Simulator.
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_Foo", referenced from:
objc-class-ref in RMAppDelegate.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Although it seems to include x86_64 by lipo command, Foo class is missing.
$ xcrun lipo -info build/rm-static-lib-universal.a
Architectures in the fat file: build/rm-static-lib-universal.a are: i386 armv7 armv7s x86_64 arm64
3. There is an error with building for iOS device.
ld: '/Users/ISD/tmp/RubyMotion/rm-static-lib/build/rm-static-lib-universal.a(init.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
It seems to be required to build with bitcode.
init.mm
from DerivedData:
#import <Foundation/Foundation.h>
extern "C" {
void ruby_init(void);
void ruby_init_loadpath(void);
void ruby_script(const char *);
void *rb_vm_top_self(void);
void rb_define_global_const(const char *, void *);
void rb_rb2oc_exc_handler(void);
void ruby_init_device_repl(void);
void MREP_00DC0AF073824F279AC3FE11C723793D(void *, void *);
int rm_repl_port = 50751;
}
extern "C"
void
RubyMotionInit(int argc, char **argv)
{
static bool initialized = false;
if (!initialized) {
ruby_init();
ruby_init_loadpath();
if (argc > 0) {
const char *progname = argv[0];
ruby_script(progname);
}
#if !__LP64__
try {
#endif
void *self = rb_vm_top_self();
ruby_init_device_repl();
rb_define_global_const("RUBYMOTION_ENV", @"development");
rb_define_global_const("RUBYMOTION_VERSION", @"6.1");
MREP_00DC0AF073824F279AC3FE11C723793D(self, 0);
#if !__LP64__
}
catch (...) {
rb_rb2oc_exc_handler();
}
#endif
initialized = true;
}
}
main.mm from DerivedData:
#import <UIKit/UIKit.h>
extern "C" {
void rb_exit(int);
void RubyMotionInit(int argc, char **argv);
}
int
main(int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retval = 0;
setenv("VM_OPT_LEVEL", "0", true);
RubyMotionInit(argc, argv);
retval = UIApplicationMain(argc, argv, nil, @"AppDelegate");
rb_exit(retval);
[pool release];
return retval;
}
You can compile a single .rb
file like this:
/usr/bin/env RM_DATADIR_PATH="/Users/amiralirajan/RubyMotionSrc/RubyMotion/data/ios/12.2" \
VM_PLATFORM="iPhoneOS" \
VM_KERNEL_PATH="/Users/amiralirajan/RubyMotionSrc/RubyMotion/data/ios/12.2/iPhoneOS/kernel-arm64.bc" \
VM_OPT_LEVEL="0" /usr/bin/arch -arch x86_64 \
"/Users/amiralirajan/RubyMotionSrc/RubyMotion/bin/ruby" --emit-llvm ./main.rb.arm64.s MREP_00DC0AF073824F279AC3FE11C723793D ./main.rb
And then use clang
:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -miphoneos-version-min=12.2 -fexceptions -c -arch arm64 "./build/iPhoneOS-12.2-Development/objs/Users/amiralirajan/RubyMotionSrc/RubyMotion/BridgeSupportApp/app/app_delegate.rb.arm64.s" -o "./build/iPhoneOS-12.2-Development/objs/Users/amiralirajan/RubyMotionSrc/RubyMotion/BridgeSupportApp/app/app_delegate.rb.arm64.o"
/usr/bin/lipo -create "./build/iPhoneOS-12.2-Development/objs/Users/amiralirajan/RubyMotionSrc/RubyMotion/BridgeSupportApp/app/app_delegate.rb.arm64.o" -output "./build/iPhoneOS-12.2-Development/objs/Users/amiralirajan/RubyMotionSrc/RubyMotion/BridgeSupportApp/app/app_delegate.rb.o"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ "./init.mm" -arch arm64 -isysroot "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk" -F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks -miphoneos-version-min=12.2 -O0 -fexceptions -fblocks -fmodules -g -fobjc-legacy-dispatch -fobjc-abi-version=2 -c -o "./build/iPhoneOS-12.2-Development/objs/init.o"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ "./main.mm" -arch arm64 -isysroot "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk" -F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks -miphoneos-version-min=12.2 -O0 -fexceptions -fblocks -fmodules -g -fobjc-legacy-dispatch -fobjc-abi-version=2 -c -o "./build/iPhoneOS-12.2-Development/objs/main.o"
Thank you @amirrajan I tried to follow the description you wrote. But still, it shows undefined symbol:_OBJCCLASS$_Foo
I want to resolve #118.
Then I thought whether to make a static library and build by Xcode.
If #118 is fixed, I don't care about this issue.
I’ll have updates about 118 on Tuesday hopefully
This is possible. Just need to write a tutorial for it.