mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
deploy-ng: changes to make it work on Windows
This commit is contained in:
parent
0002030e86
commit
bae19a203b
@ -1616,7 +1616,10 @@ class Freezer:
|
|||||||
'-x %s to exclude the entire package.' % (moduleName, moduleName.split('.')[0]))
|
'-x %s to exclude the entire package.' % (moduleName, moduleName.split('.')[0]))
|
||||||
|
|
||||||
# Build from pre-built binary stub
|
# Build from pre-built binary stub
|
||||||
stub_path = os.path.join(os.path.dirname(ExecutionEnvironment.get_dtool_name()), '..', 'bin', 'deploy-stub')
|
dtool_path = Filename(ExecutionEnvironment.get_dtool_name()).to_os_specific()
|
||||||
|
stub_path = os.path.join(os.path.dirname(dtool_path), '..', 'bin', 'deploy-stub')
|
||||||
|
if sys.platform in ('win32', 'cygwin'):
|
||||||
|
stub_path += '.exe'
|
||||||
with open(stub_path, 'rb') as f:
|
with open(stub_path, 'rb') as f:
|
||||||
stubbin = f.read()
|
stubbin = f.read()
|
||||||
|
|
||||||
|
@ -45,9 +45,9 @@ class build(distutils.command.build.build):
|
|||||||
freezer.generateRuntimeFromStub(basename)
|
freezer.generateRuntimeFromStub(basename)
|
||||||
|
|
||||||
# Copy Panda3D libs
|
# Copy Panda3D libs
|
||||||
dtool_dir = os.path.dirname(p3d.ExecutionEnvironment.get_dtool_name())
|
dtool_fn = p3d.Filename(p3d.ExecutionEnvironment.get_dtool_name())
|
||||||
libdir = os.path.join(dtool_dir, '..', 'lib')
|
libdir = os.path.dirname(dtool_fn.to_os_specific())
|
||||||
src = os.path.join(libdir, '..', 'panda3d')
|
src = os.path.normpath(os.path.join(libdir, '..', 'panda3d'))
|
||||||
dst = os.path.join(builddir, 'panda3d')
|
dst = os.path.join(builddir, 'panda3d')
|
||||||
distutils.dir_util.copy_tree(src, dst)
|
distutils.dir_util.copy_tree(src, dst)
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ class build(distutils.command.build.build):
|
|||||||
distutils.file_util.copy_file(source_path, target_path)
|
distutils.file_util.copy_file(source_path, target_path)
|
||||||
|
|
||||||
# Copy etc
|
# Copy etc
|
||||||
src = os.path.join(dtool_dir, '..', 'etc')
|
src = os.path.join(libdir, '..', 'etc')
|
||||||
dst = os.path.join(builddir, 'etc')
|
dst = os.path.join(builddir, 'etc')
|
||||||
distutils.dir_util.copy_tree(src, dst)
|
distutils.dir_util.copy_tree(src, dst)
|
||||||
|
|
||||||
|
@ -6358,12 +6358,17 @@ if (PkgSkip("CONTRIB")==0 and not RUNTIME):
|
|||||||
if True: # TODO
|
if True: # TODO
|
||||||
OPTS=['DIR:pandatool/src/deploy-stub', 'BUILDING:DEPLOYSTUB', 'PYTHON']
|
OPTS=['DIR:pandatool/src/deploy-stub', 'BUILDING:DEPLOYSTUB', 'PYTHON']
|
||||||
TargetAdd('deploy-stub.obj', opts=OPTS, input='deploy-stub.c')
|
TargetAdd('deploy-stub.obj', opts=OPTS, input='deploy-stub.c')
|
||||||
|
if GetTarget() == 'windows':
|
||||||
|
TargetAdd('frozen_dllmain.obj', opts=OPTS, input='frozen_dllmain.c')
|
||||||
|
|
||||||
if GetTarget() == 'linux':
|
if GetTarget() == 'linux':
|
||||||
# Setup rpath so libs can be found in the same directory as the deployed game
|
# Setup rpath so libs can be found in the same directory as the deployed game
|
||||||
LibName('DEPLOYSTUB', "-Wl,-rpath,\$ORIGIN")
|
LibName('DEPLOYSTUB', "-Wl,-rpath,\$ORIGIN")
|
||||||
LibName('DEPLOYSTUB', "-Wl,-z,origin")
|
LibName('DEPLOYSTUB', "-Wl,-z,origin")
|
||||||
TargetAdd('deploy-stub.exe', input='deploy-stub.obj')
|
TargetAdd('deploy-stub.exe', input='deploy-stub.obj')
|
||||||
TargetAdd('deploy-stub.exe', opts=['PYTHON', 'DEPLOYSTUB'])
|
if GetTarget() == 'windows':
|
||||||
|
TargetAdd('deploy-stub.exe', input='frozen_dllmain.obj')
|
||||||
|
TargetAdd('deploy-stub.exe', opts=['PYTHON', 'DEPLOYSTUB', 'NOICON'])
|
||||||
|
|
||||||
#
|
#
|
||||||
# Generate the models directory and samples directory
|
# Generate the models directory and samples directory
|
||||||
|
@ -20,6 +20,10 @@ extern void PyWinFreeze_ExeInit(void);
|
|||||||
extern void PyWinFreeze_ExeTerm(void);
|
extern void PyWinFreeze_ExeTerm(void);
|
||||||
|
|
||||||
extern DL_IMPORT(int) PyImport_ExtendInittab(struct _inittab *newtab);
|
extern DL_IMPORT(int) PyImport_ExtendInittab(struct _inittab *newtab);
|
||||||
|
|
||||||
|
static struct _inittab extensions[] = {
|
||||||
|
{0, 0},
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static unsigned char *modblob = NULL;
|
static unsigned char *modblob = NULL;
|
||||||
@ -165,7 +169,8 @@ main(int argc, char *argv[]) {
|
|||||||
for (modidx = 0; modidx < nummods; ++modidx) {
|
for (modidx = 0; modidx < nummods; ++modidx) {
|
||||||
struct _frozen *moddef = &_PyImport_FrozenModules[modidx];
|
struct _frozen *moddef = &_PyImport_FrozenModules[modidx];
|
||||||
char *name = NULL, namebuf[256] = {0};
|
char *name = NULL, namebuf[256] = {0};
|
||||||
unsigned int nsize, codeptr;
|
size_t nsize;
|
||||||
|
unsigned int codeptr;
|
||||||
int codesize;
|
int codesize;
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
|
134
pandatool/src/deploy-stub/frozen_dllmain.c
Normal file
134
pandatool/src/deploy-stub/frozen_dllmain.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* FreezeDLLMain.cpp
|
||||||
|
|
||||||
|
This is a DLLMain suitable for frozen applications/DLLs on
|
||||||
|
a Windows platform.
|
||||||
|
|
||||||
|
The general problem is that many Python extension modules may define
|
||||||
|
DLL main functions, but when statically linked together to form
|
||||||
|
a frozen application, this DLLMain symbol exists multiple times.
|
||||||
|
|
||||||
|
The solution is:
|
||||||
|
* Each module checks for a frozen build, and if so, defines its DLLMain
|
||||||
|
function as "__declspec(dllexport) DllMain%module%"
|
||||||
|
(eg, DllMainpythoncom, or DllMainpywintypes)
|
||||||
|
|
||||||
|
* The frozen .EXE/.DLL links against this module, which provides
|
||||||
|
the single DllMain.
|
||||||
|
|
||||||
|
* This DllMain attempts to locate and call the DllMain for each
|
||||||
|
of the extension modules.
|
||||||
|
|
||||||
|
* This code also has hooks to "simulate" DllMain when used from
|
||||||
|
a frozen .EXE.
|
||||||
|
|
||||||
|
At this stage, there is a static table of "possibly embedded modules".
|
||||||
|
This should change to something better, but it will work OK for now.
|
||||||
|
|
||||||
|
Note that this scheme does not handle dependencies in the order
|
||||||
|
of DllMain calls - except it does call pywintypes first :-)
|
||||||
|
|
||||||
|
As an example of how an extension module with a DllMain should be
|
||||||
|
changed, here is a snippet from the pythoncom extension module.
|
||||||
|
|
||||||
|
// end of example code from pythoncom's DllMain.cpp
|
||||||
|
#ifndef BUILD_FREEZE
|
||||||
|
#define DLLMAIN DllMain
|
||||||
|
#define DLLMAIN_DECL
|
||||||
|
#else
|
||||||
|
#define DLLMAIN DllMainpythoncom
|
||||||
|
#define DLLMAIN_DECL __declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" DLLMAIN_DECL
|
||||||
|
BOOL WINAPI DLLMAIN(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
||||||
|
// end of example code from pythoncom's DllMain.cpp
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
#include "windows.h"
|
||||||
|
|
||||||
|
static char *possibleModules[] = {
|
||||||
|
"pywintypes",
|
||||||
|
"pythoncom",
|
||||||
|
"win32ui",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOL CallModuleDllMain(char *modName, DWORD dwReason);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Called by a frozen .EXE only, so that built-in extension
|
||||||
|
modules are initialized correctly
|
||||||
|
*/
|
||||||
|
void PyWinFreeze_ExeInit(void)
|
||||||
|
{
|
||||||
|
char **modName;
|
||||||
|
for (modName = possibleModules;*modName;*modName++) {
|
||||||
|
/* printf("Initialising '%s'\n", *modName); */
|
||||||
|
CallModuleDllMain(*modName, DLL_PROCESS_ATTACH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Called by a frozen .EXE only, so that built-in extension
|
||||||
|
modules are cleaned up
|
||||||
|
*/
|
||||||
|
void PyWinFreeze_ExeTerm(void)
|
||||||
|
{
|
||||||
|
// Must go backwards
|
||||||
|
char **modName;
|
||||||
|
for (modName = possibleModules+(sizeof(possibleModules) / sizeof(char *))-2;
|
||||||
|
modName >= possibleModules;
|
||||||
|
*modName--) {
|
||||||
|
/* printf("Terminating '%s'\n", *modName);*/
|
||||||
|
CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
||||||
|
{
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
switch (dwReason) {
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
{
|
||||||
|
char **modName;
|
||||||
|
for (modName = possibleModules;*modName;*modName++) {
|
||||||
|
BOOL ok = CallModuleDllMain(*modName, dwReason);
|
||||||
|
if (!ok)
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
{
|
||||||
|
// Must go backwards
|
||||||
|
char **modName;
|
||||||
|
for (modName = possibleModules+(sizeof(possibleModules) / sizeof(char *))-2;
|
||||||
|
modName >= possibleModules;
|
||||||
|
*modName--)
|
||||||
|
CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CallModuleDllMain(char *modName, DWORD dwReason)
|
||||||
|
{
|
||||||
|
BOOL (WINAPI * pfndllmain)(HINSTANCE, DWORD, LPVOID);
|
||||||
|
|
||||||
|
char funcName[255];
|
||||||
|
HMODULE hmod = GetModuleHandleW(NULL);
|
||||||
|
strcpy(funcName, "_DllMain");
|
||||||
|
strcat(funcName, modName);
|
||||||
|
strcat(funcName, "@12"); // stdcall convention.
|
||||||
|
pfndllmain = (BOOL (WINAPI *)(HINSTANCE, DWORD, LPVOID))GetProcAddress(hmod, funcName);
|
||||||
|
if (pfndllmain==NULL) {
|
||||||
|
/* No function by that name exported - then that module does
|
||||||
|
not appear in our frozen program - return OK
|
||||||
|
*/
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return (*pfndllmain)(hmod, dwReason, NULL);
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user