Skip to content

Commit 676281a

Browse files
committed
kivy-ios
1 parent 8fd413e commit 676281a

File tree

635 files changed

+2978
-273445
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

635 files changed

+2978
-273445
lines changed

Package.swift

+19-13
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,28 @@ let package = Package(
88
products: [
99
.library(
1010
name: "Python-iOS",
11-
targets: ["Symbols", "Python", "BZip2", "SSL", "Crypto", "XZ", "Resources"]),
12-
],
13-
dependencies: [
14-
.package(url: "https://github.com/alloyapple/CSqlite3.git", .branch("master")),
11+
targets: ["Python", "SSL", "Crypto", "FFI", "PythonSupport"]),
1512
],
1613
targets: [
17-
.binaryTarget(name: "Python", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/Python.xcframework.zip", checksum: "7b5b216986a1a81b6d12ae3cab2e8d99ef2cd9e6ad593ed50db48cbb8d68fe0e"),
18-
.binaryTarget(name: "BZip2", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/BZip2.xcframework.zip", checksum: "3ef7ea97370492aba685b1dd03fecc7f19e292e28a303abc43e6324b96cd19ff"),
19-
.binaryTarget(name: "SSL", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/SSL.xcframework.zip", checksum: "373de27ba1c9cc1f35fe38ba98c43c48de1ccef1bcf5cb31e0f6fdaa0171083a"),
20-
.binaryTarget(name: "Crypto", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/Crypto.xcframework.zip", checksum: "98f7d56117430edfe31e7b19af87745e4738a005156c13a82a05950fe3187f60"),
21-
.binaryTarget(name: "XZ", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/XZ.xcframework.zip", checksum: "039fe28d39b6c2217f33cb50032aa8f90673e484e99edf0dbe56be47856f9994"),
22-
.target(name: "Resources", dependencies: ["Symbols"], resources: [.copy("lib")]),
23-
.target(name: "Symbols", dependencies: ["Python", "BZip2", "SSL", "Crypto", "XZ", "CSqlite3", "Clibz"]),
24-
.target(name: "Clibz", linkerSettings: [LinkerSetting.linkedLibrary("z")]),
14+
.binaryTarget(name: "Python", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/libpython3.xcframework.zip", checksum: "245c51a97eda854a7b0c7bd507f24d1dfc2efae38f20aceac91fe0fd99a6eebe"),
15+
.binaryTarget(name: "SSL", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/libssl.xcframework.zip", checksum: "1fc7dd3e95d5152812bc8d74450fdc45539e4ac53d4008b21b7f0a81d2fc52a9"),
16+
.binaryTarget(name: "Crypto", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/libcrypto.xcframework.zip", checksum: "43948ae2aac97bf80445ad0e38dd943b4f903506802633bd82d8b813da0328bf"),
17+
.binaryTarget(name: "FFI", url: "https://github.com/kewlbear/Python-iOS/releases/download/0.0.1/libffi.xcframework.zip", checksum: "0b028a1068f5f085ba1861b73928b99d14970438639d2531c3f31afe4d0e0e3c"),
18+
.target(name: "PythonSupport",
19+
dependencies: [
20+
"Python",
21+
"SSL",
22+
"Crypto",
23+
"FFI",
24+
],
25+
resources: [.copy("lib")],
26+
linkerSettings: [
27+
.linkedLibrary("z"),
28+
.linkedLibrary("sqlite3"),
29+
]
30+
),
2531
.testTarget(
2632
name: "PythonTests",
27-
dependencies: ["Resources"]),
33+
dependencies: ["PythonSupport"]),
2834
]
2935
)

Sources/Clibz/include/shim.h

-13
This file was deleted.

Sources/PythonSupport/PythonSupport.m

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//
2+
// PythonSupport.m
3+
//
4+
// Copyright (c) 2021 Changbeom Ahn
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in
14+
// all copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
// THE SOFTWARE.
23+
//
24+
25+
#import <Python.h>
26+
#include <dlfcn.h>
27+
28+
#import "PythonSupport.h"
29+
30+
static void load_custom_builtin_importer(void);
31+
32+
@implementation Python
33+
34+
- (instancetype)initWithArgc:(int)argc argv:(const char *)argv
35+
{
36+
self = [super init];
37+
38+
int ret = 0;
39+
40+
// Special environment to prefer .pyo, and don't write bytecode if .py are found
41+
// because the process will not have a write attribute on the device.
42+
putenv("PYTHONOPTIMIZE=2");
43+
putenv("PYTHONDONTWRITEBYTECODE=1");
44+
putenv("PYTHONNOUSERSITE=1");
45+
putenv("PYTHONPATH=.");
46+
putenv("PYTHONUNBUFFERED=1");
47+
putenv("LC_CTYPE=UTF-8");
48+
// putenv("PYTHONVERBOSE=1");
49+
// putenv("PYOBJUS_DEBUG=1");
50+
51+
NSString * resourcePath = [[NSBundle bundleForClass:[Python class]] URLForResource:@"python3" withExtension:nil].path;
52+
NSString *python_home = [NSString stringWithFormat:@"PYTHONHOME=%@", resourcePath, nil];
53+
putenv((char *)[python_home UTF8String]);
54+
55+
NSString *python_path = [NSString stringWithFormat:@"PYTHONPATH=%@:%@/lib/python3.8/:%@/lib/python3.8/site-packages:.", resourcePath, resourcePath, resourcePath, nil];
56+
putenv((char *)[python_path UTF8String]);
57+
58+
NSString *tmp_path = [NSString stringWithFormat:@"TMP=%@/tmp", resourcePath, nil];
59+
putenv((char *)[tmp_path UTF8String]);
60+
61+
NSLog(@"Initializing python");
62+
Py_Initialize();
63+
64+
wchar_t** python_argv = PyMem_RawMalloc(sizeof(wchar_t *) *argc);
65+
for (int i = 0; i < argc; i++)
66+
python_argv[i] = Py_DecodeLocale(argv[i], NULL);
67+
PySys_SetArgv(argc, python_argv);
68+
69+
// If other modules are using the thread, we need to initialize them before.
70+
PyEval_InitThreads();
71+
72+
// Add an importer for builtin modules
73+
load_custom_builtin_importer();
74+
75+
return self;
76+
}
77+
78+
- (instancetype)init
79+
{
80+
return [self initWithArgc:0 argv:nil];
81+
}
82+
83+
- (void)dealloc
84+
{
85+
Py_Finalize();
86+
NSLog(@"Leaving");
87+
}
88+
89+
@end
90+
91+
void load_custom_builtin_importer() {
92+
static const char *custom_builtin_importer = \
93+
"import sys, imp, types\n" \
94+
"from os import environ\n" \
95+
"from os.path import exists, join\n" \
96+
"try:\n" \
97+
" # python 3\n"
98+
" import _imp\n" \
99+
" EXTS = _imp.extension_suffixes()\n" \
100+
" sys.modules['subprocess'] = types.ModuleType(name='subprocess')\n" \
101+
" sys.modules['subprocess'].PIPE = None\n" \
102+
" sys.modules['subprocess'].STDOUT = None\n" \
103+
" sys.modules['subprocess'].DEVNULL = None\n" \
104+
" sys.modules['subprocess'].CalledProcessError = Exception\n" \
105+
" sys.modules['subprocess'].check_output = None\n" \
106+
"except ImportError:\n" \
107+
" EXTS = ['.so']\n"
108+
"# Fake redirection to supress console output\n" \
109+
"if environ.get('KIVY_NO_CONSOLE', '0') == '1':\n" \
110+
" class fakestd(object):\n" \
111+
" def write(self, *args, **kw): pass\n" \
112+
" def flush(self, *args, **kw): pass\n" \
113+
" sys.stdout = fakestd()\n" \
114+
" sys.stderr = fakestd()\n" \
115+
"# Custom builtin importer for precompiled modules\n" \
116+
"class CustomBuiltinImporter(object):\n" \
117+
" def find_module(self, fullname, mpath=None):\n" \
118+
" # print(f'find_module() fullname={fullname} mpath={mpath}')\n" \
119+
" if '.' not in fullname:\n" \
120+
" return\n" \
121+
" if not mpath:\n" \
122+
" return\n" \
123+
" part = fullname.rsplit('.')[-1]\n" \
124+
" for ext in EXTS:\n" \
125+
" fn = join(list(mpath)[0], '{}{}'.format(part, ext))\n" \
126+
" # print('find_module() {}'.format(fn))\n" \
127+
" if exists(fn):\n" \
128+
" return self\n" \
129+
" return\n" \
130+
" def load_module(self, fullname):\n" \
131+
" f = fullname.replace('.', '_')\n" \
132+
" mod = sys.modules.get(f)\n" \
133+
" if mod is None:\n" \
134+
" # print('LOAD DYNAMIC', f, sys.modules.keys())\n" \
135+
" try:\n" \
136+
" mod = imp.load_dynamic(f, f)\n" \
137+
" except ImportError:\n" \
138+
" # import traceback; traceback.print_exc();\n" \
139+
" # print('LOAD DYNAMIC FALLBACK', fullname)\n" \
140+
" mod = imp.load_dynamic(fullname, fullname)\n" \
141+
" sys.modules[fullname] = mod\n" \
142+
" return mod\n" \
143+
" return mod\n" \
144+
"sys.meta_path.insert(0, CustomBuiltinImporter())";
145+
PyRun_SimpleString(custom_builtin_importer);
146+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// MyClass.h
3+
//
4+
//
5+
// Created by 안창범 on 2021/02/24.
6+
//
7+
8+
#import <Foundation/Foundation.h>
9+
10+
NS_ASSUME_NONNULL_BEGIN
11+
12+
@interface Python : NSObject
13+
14+
- (instancetype)initWithArgc:(int)argc argv:(const char *_Nullable)argv;
15+
16+
@end
17+
18+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)