mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -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]))
|
||||
|
||||
# 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:
|
||||
stubbin = f.read()
|
||||
|
||||
|
@ -45,9 +45,9 @@ class build(distutils.command.build.build):
|
||||
freezer.generateRuntimeFromStub(basename)
|
||||
|
||||
# Copy Panda3D libs
|
||||
dtool_dir = os.path.dirname(p3d.ExecutionEnvironment.get_dtool_name())
|
||||
libdir = os.path.join(dtool_dir, '..', 'lib')
|
||||
src = os.path.join(libdir, '..', 'panda3d')
|
||||
dtool_fn = p3d.Filename(p3d.ExecutionEnvironment.get_dtool_name())
|
||||
libdir = os.path.dirname(dtool_fn.to_os_specific())
|
||||
src = os.path.normpath(os.path.join(libdir, '..', 'panda3d'))
|
||||
dst = os.path.join(builddir, 'panda3d')
|
||||
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)
|
||||
|
||||
# Copy etc
|
||||
src = os.path.join(dtool_dir, '..', 'etc')
|
||||
src = os.path.join(libdir, '..', 'etc')
|
||||
dst = os.path.join(builddir, 'etc')
|
||||
distutils.dir_util.copy_tree(src, dst)
|
||||
|
||||
|
@ -6358,12 +6358,17 @@ if (PkgSkip("CONTRIB")==0 and not RUNTIME):
|
||||
if True: # TODO
|
||||
OPTS=['DIR:pandatool/src/deploy-stub', 'BUILDING:DEPLOYSTUB', 'PYTHON']
|
||||
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':
|
||||
# Setup rpath so libs can be found in the same directory as the deployed game
|
||||
LibName('DEPLOYSTUB', "-Wl,-rpath,\$ORIGIN")
|
||||
LibName('DEPLOYSTUB', "-Wl,-z,origin")
|
||||
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
|
||||
|
@ -20,6 +20,10 @@ extern void PyWinFreeze_ExeInit(void);
|
||||
extern void PyWinFreeze_ExeTerm(void);
|
||||
|
||||
extern DL_IMPORT(int) PyImport_ExtendInittab(struct _inittab *newtab);
|
||||
|
||||
static struct _inittab extensions[] = {
|
||||
{0, 0},
|
||||
};
|
||||
#endif
|
||||
|
||||
static unsigned char *modblob = NULL;
|
||||
@ -165,7 +169,8 @@ main(int argc, char *argv[]) {
|
||||
for (modidx = 0; modidx < nummods; ++modidx) {
|
||||
struct _frozen *moddef = &_PyImport_FrozenModules[modidx];
|
||||
char *name = NULL, namebuf[256] = {0};
|
||||
unsigned int nsize, codeptr;
|
||||
size_t nsize;
|
||||
unsigned int codeptr;
|
||||
int codesize;
|
||||
|
||||
// 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