mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
dist: Remove Python 2 code from deployment system
Closes #892 Co-authored-by: rdb <git@rdb.name>
This commit is contained in:
parent
d799a09002
commit
929202bd9b
53
direct/src/dist/FreezeTool.py
vendored
53
direct/src/dist/FreezeTool.py
vendored
@ -36,14 +36,9 @@ isDebugBuild = (python.lower().endswith('_d'))
|
|||||||
# NB. if encodings are removed, be sure to remove them from the shortcut in
|
# NB. if encodings are removed, be sure to remove them from the shortcut in
|
||||||
# deploy-stub.c.
|
# deploy-stub.c.
|
||||||
startupModules = [
|
startupModules = [
|
||||||
'imp', 'encodings', 'encodings.*',
|
'imp', 'encodings', 'encodings.*', 'io', 'marshal', 'importlib.machinery',
|
||||||
|
'importlib.util',
|
||||||
]
|
]
|
||||||
if sys.version_info >= (3, 0):
|
|
||||||
# Modules specific to Python 3
|
|
||||||
startupModules += ['io', 'marshal', 'importlib.machinery', 'importlib.util']
|
|
||||||
else:
|
|
||||||
# Modules specific to Python 2
|
|
||||||
startupModules += []
|
|
||||||
|
|
||||||
# These are some special init functions for some built-in Python modules that
|
# These are some special init functions for some built-in Python modules that
|
||||||
# deviate from the standard naming convention. A value of None means that a
|
# deviate from the standard naming convention. A value of None means that a
|
||||||
@ -75,6 +70,7 @@ hiddenImports = {
|
|||||||
'datetime': ['_strptime'],
|
'datetime': ['_strptime'],
|
||||||
'keyring.backends': ['keyring.backends.*'],
|
'keyring.backends': ['keyring.backends.*'],
|
||||||
'matplotlib.font_manager': ['encodings.mac_roman'],
|
'matplotlib.font_manager': ['encodings.mac_roman'],
|
||||||
|
'matplotlib.backends._backend_tk': ['tkinter'],
|
||||||
'direct.particles': ['direct.particles.ParticleManagerGlobal'],
|
'direct.particles': ['direct.particles.ParticleManagerGlobal'],
|
||||||
'numpy.core._multiarray_umath': [
|
'numpy.core._multiarray_umath': [
|
||||||
'numpy.core._internal',
|
'numpy.core._internal',
|
||||||
@ -83,12 +79,6 @@ hiddenImports = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
if sys.version_info >= (3,):
|
|
||||||
hiddenImports['matplotlib.backends._backend_tk'] = ['tkinter']
|
|
||||||
else:
|
|
||||||
hiddenImports['matplotlib.backends._backend_tk'] = ['Tkinter']
|
|
||||||
|
|
||||||
|
|
||||||
# These are overrides for specific modules.
|
# These are overrides for specific modules.
|
||||||
overrideModules = {
|
overrideModules = {
|
||||||
# Used by the warnings module, among others, to get line numbers. Since
|
# Used by the warnings module, among others, to get line numbers. Since
|
||||||
@ -1310,11 +1300,7 @@ class Freezer:
|
|||||||
|
|
||||||
def __addPyc(self, multifile, filename, code, compressionLevel):
|
def __addPyc(self, multifile, filename, code, compressionLevel):
|
||||||
if code:
|
if code:
|
||||||
data = imp.get_magic() + b'\0\0\0\0'
|
data = imp.get_magic() + b'\0\0\0\0\0\0\0\0'
|
||||||
|
|
||||||
if sys.version_info >= (3, 0):
|
|
||||||
data += b'\0\0\0\0'
|
|
||||||
|
|
||||||
data += marshal.dumps(code)
|
data += marshal.dumps(code)
|
||||||
|
|
||||||
stream = StringStream(data)
|
stream = StringStream(data)
|
||||||
@ -1671,10 +1657,7 @@ class Freezer:
|
|||||||
# initmodule or PyInit_module function.
|
# initmodule or PyInit_module function.
|
||||||
modname = mod.split('.')[-1]
|
modname = mod.split('.')[-1]
|
||||||
libfile = modname + '.lib'
|
libfile = modname + '.lib'
|
||||||
if sys.version_info >= (3, 0):
|
symbolName = 'PyInit_' + modname
|
||||||
symbolName = 'PyInit_' + modname
|
|
||||||
else:
|
|
||||||
symbolName = 'init' + modname
|
|
||||||
os.system('lib /nologo /def /export:%s /name:%s.pyd /out:%s' % (symbolName, modname, libfile))
|
os.system('lib /nologo /def /export:%s /name:%s.pyd /out:%s' % (symbolName, modname, libfile))
|
||||||
extraLink.append(libfile)
|
extraLink.append(libfile)
|
||||||
cleanFiles += [libfile, modname + '.exp']
|
cleanFiles += [libfile, modname + '.exp']
|
||||||
@ -1778,10 +1761,7 @@ class Freezer:
|
|||||||
code = 'import sys;del sys.modules["%s"];import sys,os,imp;imp.load_dynamic("%s",os.path.join(sys.path[0], "%s%s"))' % (moduleName, moduleName, moduleName, modext)
|
code = 'import sys;del sys.modules["%s"];import sys,os,imp;imp.load_dynamic("%s",os.path.join(sys.path[0], "%s%s"))' % (moduleName, moduleName, moduleName, modext)
|
||||||
else:
|
else:
|
||||||
code = 'import sys;del sys.modules["%s"];import sys,os,imp;imp.load_dynamic("%s",os.path.join(os.path.dirname(sys.executable), "%s%s"))' % (moduleName, moduleName, moduleName, modext)
|
code = 'import sys;del sys.modules["%s"];import sys,os,imp;imp.load_dynamic("%s",os.path.join(os.path.dirname(sys.executable), "%s%s"))' % (moduleName, moduleName, moduleName, modext)
|
||||||
if sys.version_info >= (3, 2):
|
code = compile(code, moduleName, 'exec', optimize=2)
|
||||||
code = compile(code, moduleName, 'exec', optimize=2)
|
|
||||||
else:
|
|
||||||
code = compile(code, moduleName, 'exec')
|
|
||||||
code = marshal.dumps(code)
|
code = marshal.dumps(code)
|
||||||
moduleList.append((moduleName, len(pool), len(code)))
|
moduleList.append((moduleName, len(pool), len(code)))
|
||||||
pool += code
|
pool += code
|
||||||
@ -2273,7 +2253,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if sys.version_info >= (3, 0) and 'b' not in mode:
|
if 'b' not in mode:
|
||||||
return io.TextIOWrapper(fp, encoding='utf8')
|
return io.TextIOWrapper(fp, encoding='utf8')
|
||||||
return fp
|
return fp
|
||||||
|
|
||||||
@ -2358,27 +2338,14 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
co = marshal.loads(memoryview(data)[16:])
|
co = marshal.loads(memoryview(data)[16:])
|
||||||
elif sys.version_info >= (3, 4):
|
else:
|
||||||
try:
|
try:
|
||||||
if sys.version_info >= (3, 5):
|
marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read())
|
||||||
marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read())
|
|
||||||
else:
|
|
||||||
marshal_data = importlib._bootstrap._validate_bytecode_header(fp.read())
|
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
self.msgout(2, "raise ImportError: " + str(exc), pathname)
|
self.msgout(2, "raise ImportError: " + str(exc), pathname)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
co = marshal.loads(marshal_data)
|
co = marshal.loads(marshal_data)
|
||||||
else:
|
|
||||||
if fp.read(4) != imp.get_magic():
|
|
||||||
self.msgout(2, "raise ImportError: Bad magic number", pathname)
|
|
||||||
raise ImportError("Bad magic number in %s" % pathname)
|
|
||||||
|
|
||||||
fp.read(4)
|
|
||||||
if sys.version_info >= (3, 3):
|
|
||||||
fp.read(4)
|
|
||||||
|
|
||||||
co = marshal.load(fp)
|
|
||||||
else:
|
else:
|
||||||
co = None
|
co = None
|
||||||
|
|
||||||
@ -2488,7 +2455,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|||||||
|
|
||||||
# If we found folders on the path with this module name without an
|
# If we found folders on the path with this module name without an
|
||||||
# __init__.py file, we should consider this a namespace package.
|
# __init__.py file, we should consider this a namespace package.
|
||||||
if ns_dirs and sys.version_info >= (3, 3):
|
if ns_dirs:
|
||||||
return (None, ns_dirs, ('', '', _PKG_NAMESPACE_DIRECTORY))
|
return (None, ns_dirs, ('', '', _PKG_NAMESPACE_DIRECTORY))
|
||||||
|
|
||||||
raise ImportError(name)
|
raise ImportError(name)
|
||||||
|
54
direct/src/dist/commands.py
vendored
54
direct/src/dist/commands.py
vendored
@ -119,45 +119,7 @@ PACKAGE_LIB_DIRS = {
|
|||||||
'scipy': ['scipy/extra-dll'],
|
'scipy': ['scipy/extra-dll'],
|
||||||
}
|
}
|
||||||
|
|
||||||
# site.py for Python 2.
|
SITE_PY = u"""
|
||||||
SITE_PY2 = u"""
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.frozen = True
|
|
||||||
|
|
||||||
# Override __import__ to set __file__ for frozen modules.
|
|
||||||
prev_import = __import__
|
|
||||||
def __import__(*args, **kwargs):
|
|
||||||
mod = prev_import(*args, **kwargs)
|
|
||||||
if mod:
|
|
||||||
mod.__file__ = sys.executable
|
|
||||||
return mod
|
|
||||||
|
|
||||||
# Add our custom __import__ version to the global scope, as well as a builtin
|
|
||||||
# definition for __file__ so that it is available in the module itself.
|
|
||||||
import __builtin__
|
|
||||||
__builtin__.__import__ = __import__
|
|
||||||
__builtin__.__file__ = sys.executable
|
|
||||||
del __builtin__
|
|
||||||
|
|
||||||
# Set the TCL_LIBRARY directory to the location of the Tcl/Tk/Tix files.
|
|
||||||
import os
|
|
||||||
tcl_dir = os.path.join(os.path.dirname(sys.executable), 'tcl')
|
|
||||||
if os.path.isdir(tcl_dir):
|
|
||||||
for dir in os.listdir(tcl_dir):
|
|
||||||
sub_dir = os.path.join(tcl_dir, dir)
|
|
||||||
if os.path.isdir(sub_dir):
|
|
||||||
if dir.startswith('tcl'):
|
|
||||||
os.environ['TCL_LIBRARY'] = sub_dir
|
|
||||||
if dir.startswith('tk'):
|
|
||||||
os.environ['TK_LIBRARY'] = sub_dir
|
|
||||||
if dir.startswith('tix'):
|
|
||||||
os.environ['TIX_LIBRARY'] = sub_dir
|
|
||||||
del os
|
|
||||||
"""
|
|
||||||
|
|
||||||
# site.py for Python 3.
|
|
||||||
SITE_PY3 = u"""
|
|
||||||
import sys
|
import sys
|
||||||
from _frozen_importlib import _imp, FrozenImporter
|
from _frozen_importlib import _imp, FrozenImporter
|
||||||
|
|
||||||
@ -205,8 +167,6 @@ if os.path.isdir(tcl_dir):
|
|||||||
del os
|
del os
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SITE_PY = SITE_PY3 if sys.version_info >= (3,) else SITE_PY2
|
|
||||||
|
|
||||||
|
|
||||||
class build_apps(setuptools.Command):
|
class build_apps(setuptools.Command):
|
||||||
description = 'build Panda3D applications'
|
description = 'build Panda3D applications'
|
||||||
@ -798,11 +758,10 @@ class build_apps(setuptools.Command):
|
|||||||
basename = module.rsplit('.', 1)[0] + '.' + basename
|
basename = module.rsplit('.', 1)[0] + '.' + basename
|
||||||
|
|
||||||
# Remove python version string
|
# Remove python version string
|
||||||
if sys.version_info >= (3, 0):
|
parts = basename.split('.')
|
||||||
parts = basename.split('.')
|
if len(parts) >= 3 and '-' in parts[-2]:
|
||||||
if len(parts) >= 3 and '-' in parts[-2]:
|
parts = parts[:-2] + parts[-1:]
|
||||||
parts = parts[:-2] + parts[-1:]
|
basename = '.'.join(parts)
|
||||||
basename = '.'.join(parts)
|
|
||||||
else:
|
else:
|
||||||
# Builtin module, but might not be builtin in wheel libs, so double check
|
# Builtin module, but might not be builtin in wheel libs, so double check
|
||||||
if module in whl_modules:
|
if module in whl_modules:
|
||||||
@ -821,9 +780,8 @@ class build_apps(setuptools.Command):
|
|||||||
#TODO: get this to work on non-Windows platforms.
|
#TODO: get this to work on non-Windows platforms.
|
||||||
if sys.platform == "win32" and platform.startswith('win'):
|
if sys.platform == "win32" and platform.startswith('win'):
|
||||||
tcl_dir = os.path.join(sys.prefix, 'tcl')
|
tcl_dir = os.path.join(sys.prefix, 'tcl')
|
||||||
tkinter_name = 'tkinter' if sys.version_info >= (3, 0) else 'Tkinter'
|
|
||||||
|
|
||||||
if os.path.isdir(tcl_dir) and tkinter_name in freezer_modules:
|
if os.path.isdir(tcl_dir) and 'tkinter' in freezer_modules:
|
||||||
self.announce('Copying Tcl files', distutils.log.INFO)
|
self.announce('Copying Tcl files', distutils.log.INFO)
|
||||||
os.makedirs(os.path.join(builddir, 'tcl'))
|
os.makedirs(os.path.join(builddir, 'tcl'))
|
||||||
|
|
||||||
|
@ -22,13 +22,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#include <locale.h>
|
||||||
# include <locale.h>
|
|
||||||
|
|
||||||
# if PY_MINOR_VERSION < 5
|
|
||||||
# define Py_DecodeLocale _Py_char2wchar
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Leave room for future expansion. We only read pointer 0, but there are
|
/* Leave room for future expansion. We only read pointer 0, but there are
|
||||||
other pointers that are being read by configPageManager.cxx. */
|
other pointers that are being read by configPageManager.cxx. */
|
||||||
@ -70,10 +64,8 @@ static struct _inittab extensions[] = {
|
|||||||
{0, 0},
|
{0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
# define WIN_UNICODE
|
# define WIN_UNICODE
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static wchar_t *log_pathw = NULL;
|
static wchar_t *log_pathw = NULL;
|
||||||
@ -356,7 +348,7 @@ int Py_FrozenMain(int argc, char **argv)
|
|||||||
int inspect = 0;
|
int inspect = 0;
|
||||||
int unbuffered = 0;
|
int unbuffered = 0;
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
|
#ifndef WIN_UNICODE
|
||||||
int i;
|
int i;
|
||||||
char *oldloc;
|
char *oldloc;
|
||||||
wchar_t **argv_copy = NULL;
|
wchar_t **argv_copy = NULL;
|
||||||
@ -397,7 +389,7 @@ int Py_FrozenMain(int argc, char **argv)
|
|||||||
setbuf(stderr, (char *)NULL);
|
setbuf(stderr, (char *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
|
#ifndef WIN_UNICODE
|
||||||
oldloc = setlocale(LC_ALL, NULL);
|
oldloc = setlocale(LC_ALL, NULL);
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
@ -418,7 +410,7 @@ int Py_FrozenMain(int argc, char **argv)
|
|||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
|
||||||
if (argc >= 1) {
|
if (argc >= 1) {
|
||||||
#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
|
#ifndef WIN_UNICODE
|
||||||
Py_SetProgramName(argv_copy[0]);
|
Py_SetProgramName(argv_copy[0]);
|
||||||
#else
|
#else
|
||||||
Py_SetProgramName(argv[0]);
|
Py_SetProgramName(argv[0]);
|
||||||
@ -430,64 +422,11 @@ int Py_FrozenMain(int argc, char **argv)
|
|||||||
PyWinFreeze_ExeInit();
|
PyWinFreeze_ExeInit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MS_WINDOWS) && PY_VERSION_HEX < 0x03040000
|
|
||||||
/* We can't rely on our overriding of the standard I/O to work on older
|
|
||||||
* versions of Python, since they are compiled with an incompatible CRT.
|
|
||||||
* The best solution I've found was to just replace sys.stdout/stderr with
|
|
||||||
* the log file reopened in append mode (which requires not locking it for
|
|
||||||
* write, and also passing in _O_APPEND above, and disabling buffering).
|
|
||||||
* It's not the most elegant solution, but it's better than crashing. */
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
if (log_pathw != NULL) {
|
|
||||||
PyObject *uniobj = PyUnicode_FromWideChar(log_pathw, (Py_ssize_t)wcslen(log_pathw));
|
|
||||||
PyObject *file = PyObject_CallFunction((PyObject*)&PyFile_Type, "Nsi", uniobj, "a", 0);
|
|
||||||
|
|
||||||
if (file != NULL) {
|
|
||||||
PyFile_SetEncodingAndErrors(file, "utf-8", NULL);
|
|
||||||
|
|
||||||
PySys_SetObject("stdout", file);
|
|
||||||
PySys_SetObject("stderr", file);
|
|
||||||
PySys_SetObject("__stdout__", file);
|
|
||||||
PySys_SetObject("__stderr__", file);
|
|
||||||
|
|
||||||
/* Be sure to disable buffering, otherwise we'll get overlap */
|
|
||||||
setbuf(stdout, (char *)NULL);
|
|
||||||
setbuf(stderr, (char *)NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (!supports_code_page(GetConsoleOutputCP()) ||
|
|
||||||
!supports_code_page(GetConsoleCP())) {
|
|
||||||
/* Same hack as before except for Python 2.7, which doesn't seem to have
|
|
||||||
* a way to set the encoding ahead of time, and setting PYTHONIOENCODING
|
|
||||||
* doesn't seem to work. Fortunately, Python 2.7 doesn't usually start
|
|
||||||
* causing codec errors until the first print statement. */
|
|
||||||
PyObject *sys_stream;
|
|
||||||
UINT acp = GetACP();
|
|
||||||
SetConsoleCP(acp);
|
|
||||||
SetConsoleOutputCP(acp);
|
|
||||||
|
|
||||||
sys_stream = PySys_GetObject("stdin");
|
|
||||||
if (sys_stream && PyFile_Check(sys_stream)) {
|
|
||||||
PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL);
|
|
||||||
}
|
|
||||||
sys_stream = PySys_GetObject("stdout");
|
|
||||||
if (sys_stream && PyFile_Check(sys_stream)) {
|
|
||||||
PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL);
|
|
||||||
}
|
|
||||||
sys_stream = PySys_GetObject("stderr");
|
|
||||||
if (sys_stream && PyFile_Check(sys_stream)) {
|
|
||||||
PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Py_VerboseFlag)
|
if (Py_VerboseFlag)
|
||||||
fprintf(stderr, "Python %s\n%s\n",
|
fprintf(stderr, "Python %s\n%s\n",
|
||||||
Py_GetVersion(), Py_GetCopyright());
|
Py_GetVersion(), Py_GetCopyright());
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
|
#ifndef WIN_UNICODE
|
||||||
PySys_SetArgv(argc, argv_copy);
|
PySys_SetArgv(argc, argv_copy);
|
||||||
#else
|
#else
|
||||||
PySys_SetArgv(argc, argv);
|
PySys_SetArgv(argc, argv);
|
||||||
@ -510,11 +449,7 @@ int Py_FrozenMain(int argc, char **argv)
|
|||||||
sprintf(buffer, "%s/../Frameworks", dir);
|
sprintf(buffer, "%s/../Frameworks", dir);
|
||||||
|
|
||||||
PyObject *sys_path = PyList_New(1);
|
PyObject *sys_path = PyList_New(1);
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
PyList_SET_ITEM(sys_path, 0, PyUnicode_FromString(buffer));
|
PyList_SET_ITEM(sys_path, 0, PyUnicode_FromString(buffer));
|
||||||
#else
|
|
||||||
PyList_SET_ITEM(sys_path, 0, PyString_FromString(buffer));
|
|
||||||
#endif
|
|
||||||
PySys_SetObject("path", sys_path);
|
PySys_SetObject("path", sys_path);
|
||||||
Py_DECREF(sys_path);
|
Py_DECREF(sys_path);
|
||||||
|
|
||||||
@ -546,15 +481,11 @@ int Py_FrozenMain(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
|
#ifndef WIN_UNICODE
|
||||||
error:
|
error:
|
||||||
if (argv_copy2) {
|
if (argv_copy2) {
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
#if PY_MINOR_VERSION >= 4
|
|
||||||
PyMem_RawFree(argv_copy2[i]);
|
PyMem_RawFree(argv_copy2[i]);
|
||||||
#else
|
|
||||||
PyMem_Free(argv_copy2[i]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -643,7 +574,7 @@ static void unmap_blob(void *blob) {
|
|||||||
/**
|
/**
|
||||||
* Main entry point to deploy-stub.
|
* Main entry point to deploy-stub.
|
||||||
*/
|
*/
|
||||||
#if defined(_WIN32) && PY_MAJOR_VERSION >= 3
|
#ifdef _WIN32
|
||||||
int wmain(int argc, wchar_t *argv[]) {
|
int wmain(int argc, wchar_t *argv[]) {
|
||||||
#else
|
#else
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user