fix cookiecutter project for python3
This commit is contained in:
parent
7c8a2c6c4b
commit
9ad9abf9b6
5 changed files with 84 additions and 23 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -18,3 +18,4 @@ src/ios/iosbuild/
|
||||||
src/ios/ios.c
|
src/ios/ios.c
|
||||||
*.DS_Store*
|
*.DS_Store*
|
||||||
*-ios/
|
*-ios/
|
||||||
|
__pycache__
|
||||||
|
|
|
@ -106,10 +106,10 @@
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
hp*|HP*) DYNLOADFILE="dynload_hpux.o";;
|
hp*|HP*) DYNLOADFILE="dynload_hpux.o";;
|
||||||
+ # Disable dynamic loading on iOS
|
+ # Dynamic loading on iOS
|
||||||
+ iOS/*) DYNLOADFILE="dynload_stub.o";;
|
+ iOS/*) DYNLOADFILE="dynload_shlib.o";;
|
||||||
+ tvOS/*) DYNLOADFILE="dynload_stub.o";;
|
+ tvOS/*) DYNLOADFILE="dynload_shlib.o";;
|
||||||
+ watchOS/*) DYNLOADFILE="dynload_stub.o";;
|
+ watchOS/*) DYNLOADFILE="dynload_shlib.o";;
|
||||||
*)
|
*)
|
||||||
# use dynload_shlib.c and dlopen() if we have it; otherwise stub
|
# use dynload_shlib.c and dlopen() if we have it; otherwise stub
|
||||||
# out any dynamic loading
|
# out any dynamic loading
|
||||||
|
|
12
toolchain.py
12
toolchain.py
|
@ -1096,6 +1096,15 @@ def ensure_dir(filename):
|
||||||
makedirs(filename)
|
makedirs(filename)
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_recipes_loaded(ctx):
|
||||||
|
for recipe in Recipe.list_recipes():
|
||||||
|
key = "{}.build_all".format(recipe)
|
||||||
|
if key not in ctx.state:
|
||||||
|
continue
|
||||||
|
recipe = Recipe.get_recipe(recipe, ctx)
|
||||||
|
recipe.init_with_ctx(ctx)
|
||||||
|
|
||||||
|
|
||||||
def update_pbxproj(filename):
|
def update_pbxproj(filename):
|
||||||
# list all the compiled recipes
|
# list all the compiled recipes
|
||||||
ctx = Context()
|
ctx = Context()
|
||||||
|
@ -1318,6 +1327,7 @@ Xcode:
|
||||||
|
|
||||||
from cookiecutter.main import cookiecutter
|
from cookiecutter.main import cookiecutter
|
||||||
ctx = Context()
|
ctx = Context()
|
||||||
|
ensure_recipes_loaded(ctx)
|
||||||
template_dir = join(curdir, "tools", "templates")
|
template_dir = join(curdir, "tools", "templates")
|
||||||
context = {
|
context = {
|
||||||
"title": args.name,
|
"title": args.name,
|
||||||
|
@ -1327,6 +1337,8 @@ Xcode:
|
||||||
"project_dir": realpath(args.directory),
|
"project_dir": realpath(args.directory),
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dist_dir": ctx.dist_dir,
|
"dist_dir": ctx.dist_dir,
|
||||||
|
"python_version": ctx.python_ver,
|
||||||
|
"python_major": ctx.python_major
|
||||||
}
|
}
|
||||||
cookiecutter(template_dir, no_input=True, extra_context=context)
|
cookiecutter(template_dir, no_input=True, extra_context=context)
|
||||||
filename = join(
|
filename = join(
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#include "{{ cookiecutter.kivy_dir }}/dist/root/python/include/python2.7/Python.h"
|
{%- if cookiecutter.python_major == 2 %}
|
||||||
|
#include "{{ cookiecutter.kivy_dir }}/dist/root/python2/include/python2.7/Python.h"
|
||||||
|
{%- else %}
|
||||||
|
#include "{{ cookiecutter.kivy_dir }}/dist/root/python3/include/python3.7m/Python.h"
|
||||||
|
{%- endif %}
|
||||||
#include "{{ cookiecutter.kivy_dir }}/dist/include/common/sdl2/SDL_main.h"
|
#include "{{ cookiecutter.kivy_dir }}/dist/include/common/sdl2/SDL_main.h"
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
@ -22,11 +26,12 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Special environment to prefer .pyo, and don't write bytecode if .py are found
|
// Special environment to prefer .pyo, and don't write bytecode if .py are found
|
||||||
// because the process will not have a write attribute on the device.
|
// because the process will not have a write attribute on the device.
|
||||||
putenv("PYTHONOPTIMIZE=2");
|
|
||||||
putenv("PYTHONDONTWRITEBYTECODE=1");
|
putenv("PYTHONDONTWRITEBYTECODE=1");
|
||||||
putenv("PYTHONNOUSERSITE=1");
|
putenv("PYTHONNOUSERSITE=1");
|
||||||
putenv("PYTHONPATH=.");
|
putenv("PYTHONPATH=.");
|
||||||
//putenv("PYTHONVERBOSE=1");
|
putenv("PYTHONUNBUFFERED=1");
|
||||||
|
// putenv("PYTHONVERBOSE=1");
|
||||||
|
// putenv("PYOBJUS_DEBUG=1");
|
||||||
|
|
||||||
// Kivy environment to prefer some implementation on iOS platform
|
// Kivy environment to prefer some implementation on iOS platform
|
||||||
putenv("KIVY_BUILD=ios");
|
putenv("KIVY_BUILD=ios");
|
||||||
|
@ -44,12 +49,31 @@ int main(int argc, char *argv[]) {
|
||||||
export_orientation();
|
export_orientation();
|
||||||
|
|
||||||
NSString * resourcePath = [[NSBundle mainBundle] resourcePath];
|
NSString * resourcePath = [[NSBundle mainBundle] resourcePath];
|
||||||
|
#if PY_MAJOR_VERSION == 2
|
||||||
NSLog(@"PythonHome is: %s", (char *)[resourcePath UTF8String]);
|
NSLog(@"PythonHome is: %s", (char *)[resourcePath UTF8String]);
|
||||||
Py_SetPythonHome((char *)[resourcePath UTF8String]);
|
Py_SetPythonHome((char *)[resourcePath UTF8String]);
|
||||||
|
#else
|
||||||
|
NSString *python_home = [NSString stringWithFormat:@"PYTHONHOME=%@", resourcePath, nil];
|
||||||
|
putenv((char *)[python_home UTF8String]);
|
||||||
|
|
||||||
|
NSString *python_path = [NSString stringWithFormat:@"PYTHONPATH=%@:%@/lib/python3.7/:%@/lib/python3.7/site-packages", resourcePath, resourcePath, resourcePath, nil];
|
||||||
|
putenv((char *)[python_path UTF8String]);
|
||||||
|
|
||||||
|
NSString *tmp_path = [NSString stringWithFormat:@"TMP=%@/tmp", resourcePath, nil];
|
||||||
|
putenv((char *)[tmp_path UTF8String]);
|
||||||
|
#endif
|
||||||
|
|
||||||
NSLog(@"Initializing python");
|
NSLog(@"Initializing python");
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION == 2
|
||||||
PySys_SetArgv(argc, argv);
|
PySys_SetArgv(argc, argv);
|
||||||
|
#else
|
||||||
|
wchar_t** python_argv = PyMem_RawMalloc(sizeof(wchar_t *) *argc);
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
python_argv[i] = Py_DecodeLocale(argv[i], NULL);
|
||||||
|
PySys_SetArgv(argc, python_argv);
|
||||||
|
#endif
|
||||||
|
|
||||||
// If other modules are using the thread, we need to initialize them before.
|
// If other modules are using the thread, we need to initialize them before.
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
|
@ -58,14 +82,20 @@ int main(int argc, char *argv[]) {
|
||||||
load_custom_builtin_importer();
|
load_custom_builtin_importer();
|
||||||
|
|
||||||
// Search and start main.py
|
// Search and start main.py
|
||||||
|
#if PY_MAJOR_VERSION == 2
|
||||||
|
#define MAIN_EXT @"pyo"
|
||||||
|
#else
|
||||||
|
#define MAIN_EXT @"pyc"
|
||||||
|
#endif
|
||||||
|
|
||||||
const char * prog = [
|
const char * prog = [
|
||||||
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:@"pyo"] cStringUsingEncoding:
|
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:MAIN_EXT] cStringUsingEncoding:
|
||||||
NSUTF8StringEncoding];
|
NSUTF8StringEncoding];
|
||||||
NSLog(@"Running main.pyo: %s", prog);
|
NSLog(@"Running main.py: %s", prog);
|
||||||
FILE* fd = fopen(prog, "r");
|
FILE* fd = fopen(prog, "r");
|
||||||
if ( fd == NULL ) {
|
if ( fd == NULL ) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
NSLog(@"Unable to open main.pyo, abort.");
|
NSLog(@"Unable to open main.py, abort.");
|
||||||
} else {
|
} else {
|
||||||
ret = PyRun_SimpleFileEx(fd, prog, 1);
|
ret = PyRun_SimpleFileEx(fd, prog, 1);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -117,9 +147,16 @@ void export_orientation() {
|
||||||
|
|
||||||
void load_custom_builtin_importer() {
|
void load_custom_builtin_importer() {
|
||||||
static const char *custom_builtin_importer = \
|
static const char *custom_builtin_importer = \
|
||||||
"import sys, imp\n" \
|
"import sys, imp, types\n" \
|
||||||
"from os import environ\n" \
|
"from os import environ\n" \
|
||||||
"from os.path import exists, join\n" \
|
"from os.path import exists, join\n" \
|
||||||
|
"try:\n" \
|
||||||
|
" # python 3\n"
|
||||||
|
" import _imp\n" \
|
||||||
|
" EXTS = _imp.extension_suffixes()\n" \
|
||||||
|
" sys.modules['subprocess'] = types.ModuleType(name='subprocess')\n" \
|
||||||
|
"except ImportError:\n" \
|
||||||
|
" EXTS = ['.so']\n"
|
||||||
"# Fake redirection to supress console output\n" \
|
"# Fake redirection to supress console output\n" \
|
||||||
"if environ.get('KIVY_NO_CONSOLE', '0') == '1':\n" \
|
"if environ.get('KIVY_NO_CONSOLE', '0') == '1':\n" \
|
||||||
" class fakestd(object):\n" \
|
" class fakestd(object):\n" \
|
||||||
|
@ -130,12 +167,15 @@ void load_custom_builtin_importer() {
|
||||||
"# Custom builtin importer for precompiled modules\n" \
|
"# Custom builtin importer for precompiled modules\n" \
|
||||||
"class CustomBuiltinImporter(object):\n" \
|
"class CustomBuiltinImporter(object):\n" \
|
||||||
" def find_module(self, fullname, mpath=None):\n" \
|
" def find_module(self, fullname, mpath=None):\n" \
|
||||||
|
" # print(f'find_module() fullname={fullname} mpath={mpath}')\n" \
|
||||||
" if '.' not in fullname:\n" \
|
" if '.' not in fullname:\n" \
|
||||||
" return\n" \
|
" return\n" \
|
||||||
" if not mpath:\n" \
|
" if not mpath:\n" \
|
||||||
" return\n" \
|
" return\n" \
|
||||||
" part = fullname.rsplit('.')[-1]\n" \
|
" part = fullname.rsplit('.')[-1]\n" \
|
||||||
" fn = join(mpath[0], '{}.so'.format(part))\n" \
|
" for ext in EXTS:\n" \
|
||||||
|
" fn = join(list(mpath)[0], '{}{}'.format(part, ext))\n" \
|
||||||
|
" # print('find_module() {}'.format(fn))\n" \
|
||||||
" if exists(fn):\n" \
|
" if exists(fn):\n" \
|
||||||
" return self\n" \
|
" return self\n" \
|
||||||
" return\n" \
|
" return\n" \
|
||||||
|
@ -143,16 +183,16 @@ void load_custom_builtin_importer() {
|
||||||
" f = fullname.replace('.', '_')\n" \
|
" f = fullname.replace('.', '_')\n" \
|
||||||
" mod = sys.modules.get(f)\n" \
|
" mod = sys.modules.get(f)\n" \
|
||||||
" if mod is None:\n" \
|
" if mod is None:\n" \
|
||||||
" # print 'LOAD DYNAMIC', f, sys.modules.keys()\n" \
|
" # print('LOAD DYNAMIC', f, sys.modules.keys())\n" \
|
||||||
" try:\n" \
|
" try:\n" \
|
||||||
" mod = imp.load_dynamic(f, f)\n" \
|
" mod = imp.load_dynamic(f, f)\n" \
|
||||||
" except ImportError:\n" \
|
" except ImportError:\n" \
|
||||||
" # import traceback; traceback.print_exc();\n" \
|
" import traceback; traceback.print_exc();\n" \
|
||||||
" # print 'LOAD DYNAMIC FALLBACK', fullname\n" \
|
" # print('LOAD DYNAMIC FALLBACK', fullname)\n" \
|
||||||
" mod = imp.load_dynamic(fullname, fullname)\n" \
|
" mod = imp.load_dynamic(fullname, fullname)\n" \
|
||||||
" sys.modules[fullname] = mod\n" \
|
" sys.modules[fullname] = mod\n" \
|
||||||
" return mod\n" \
|
" return mod\n" \
|
||||||
" return mod\n" \
|
" return mod\n" \
|
||||||
"sys.meta_path.append(CustomBuiltinImporter())";
|
"sys.meta_path.insert(0, CustomBuiltinImporter())";
|
||||||
PyRun_SimpleString(custom_builtin_importer);
|
PyRun_SimpleString(custom_builtin_importer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||||
2CB5F34517D5233A006187AB /* bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = SOURCE_ROOT; };
|
2CB5F34517D5233A006187AB /* bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = SOURCE_ROOT; };
|
||||||
2CB5F34617D5233A006187AB /* bridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bridge.m; sourceTree = SOURCE_ROOT; };
|
2CB5F34617D5233A006187AB /* bridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bridge.m; sourceTree = SOURCE_ROOT; };
|
||||||
59738AB41A8BB5D8001B2C0C /* lib */ = {isa = PBXFileReference; lastKnownFileType = folder; name = lib; path = {{ cookiecutter.dist_dir }}/root/python/lib; sourceTree = "<group>"; };
|
59738AB41A8BB5D8001B2C0C /* lib */ = {isa = PBXFileReference; lastKnownFileType = folder; name = lib; path = {{ cookiecutter.dist_dir }}/root/python{{ cookiecutter.python_major }}/lib; sourceTree = "<group>"; };
|
||||||
59738AB61A8BB71F001B2C0C /* include */ = {isa = PBXFileReference; lastKnownFileType = folder; name = include; path = {{ cookiecutter.dist_dir }}/hostpython/include; sourceTree = "<group>"; };
|
59738AB61A8BB71F001B2C0C /* include */ = {isa = PBXFileReference; lastKnownFileType = folder; name = include; path = {{ cookiecutter.dist_dir }}/hostpython/include; sourceTree = "<group>"; };
|
||||||
59738ABA1A8E19AA001B2C0C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = {{ cookiecutter.project_name }}/Images.xcassets; sourceTree = "<group>"; };
|
59738ABA1A8E19AA001B2C0C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = {{ cookiecutter.project_name }}/Images.xcassets; sourceTree = "<group>"; };
|
||||||
59738AD01A8E62D6001B2C0C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "LaunchImages/Default-568h@2x.png"; sourceTree = "<group>"; };
|
59738AD01A8E62D6001B2C0C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "LaunchImages/Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||||
|
@ -234,7 +234,11 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/bash;
|
shellPath = /bin/bash;
|
||||||
shellScript = "{{ cookiecutter.dist_dir }}/hostpython/bin/python -OO -m compileall \"$PROJECT_DIR\"/YourApp";
|
{%- if cookiecutter.python_major == 2 %}
|
||||||
|
shellScript = "{{ cookiecutter.dist_dir }}/hostpython2/bin/python -OO -m compileall \"$PROJECT_DIR\"/YourApp";
|
||||||
|
{%- else %}
|
||||||
|
shellScript = "{{ cookiecutter.dist_dir }}/hostpython3/bin/python -m compileall -f -b \"$PROJECT_DIR\"/YourApp";
|
||||||
|
{%- endif %}
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
@ -250,7 +254,11 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/bash;
|
shellPath = /bin/bash;
|
||||||
shellScript = "find \"$PROJECT_DIR\"/YourApp/ -iname '*.py' -exec rm {} \\; -or -iname '*.pyc' -exec rm {} \\;";
|
{%- if cookiecutter.python_major == 2 %}
|
||||||
|
shellScript = "find \"$PROJECT_DIR\"/YourApp/ -regex '.*\\.py[c]*' -delete";
|
||||||
|
{%- else %}
|
||||||
|
shellScript = "find \"$PROJECT_DIR\"/YourApp/ -regex '.*\\.py' -delete";
|
||||||
|
{%- endif %}
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
@ -343,8 +351,8 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
DEAD_CODE_STRIPPING = NO;
|
DEAD_CODE_STRIPPING = NO;
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
|
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
|
||||||
VALID_ARCHS = x86_64;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -352,9 +360,9 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
DEAD_CODE_STRIPPING = NO;
|
DEAD_CODE_STRIPPING = NO;
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
||||||
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
|
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
|
||||||
VALID_ARCHS = x86_64;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue