mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
deploy-ng: support logging via log_filename (and log_append) setting
This commit is contained in:
parent
f5932bf070
commit
742c143a01
@ -1642,7 +1642,8 @@ class Freezer:
|
|||||||
|
|
||||||
return target
|
return target
|
||||||
|
|
||||||
def generateRuntimeFromStub(self, target, stub_file, use_console, fields={}):
|
def generateRuntimeFromStub(self, target, stub_file, use_console, fields={},
|
||||||
|
log_append=False):
|
||||||
# We must have a __main__ module to make an exe file.
|
# We must have a __main__ module to make an exe file.
|
||||||
if not self.__writingModule('__main__'):
|
if not self.__writingModule('__main__'):
|
||||||
message = "Can't generate an executable without a __main__ module."
|
message = "Can't generate an executable without a __main__ module."
|
||||||
@ -1735,7 +1736,7 @@ class Freezer:
|
|||||||
|
|
||||||
# Determine the format of the header and module list entries depending
|
# Determine the format of the header and module list entries depending
|
||||||
# on the platform.
|
# on the platform.
|
||||||
num_pointers = 11
|
num_pointers = 12
|
||||||
stub_data = bytearray(stub_file.read())
|
stub_data = bytearray(stub_file.read())
|
||||||
bitnesses = self._get_executable_bitnesses(stub_data)
|
bitnesses = self._get_executable_bitnesses(stub_data)
|
||||||
|
|
||||||
@ -1808,6 +1809,10 @@ class Freezer:
|
|||||||
# A null entry marks the end of the module table.
|
# A null entry marks the end of the module table.
|
||||||
blob += struct.pack(entry_layout, 0, 0, 0)
|
blob += struct.pack(entry_layout, 0, 0, 0)
|
||||||
|
|
||||||
|
flags = 0
|
||||||
|
if log_append:
|
||||||
|
flags |= 1
|
||||||
|
|
||||||
# Compose the header we will be writing to the stub, to tell it
|
# Compose the header we will be writing to the stub, to tell it
|
||||||
# where to find the module data blob, as well as other variables.
|
# where to find the module data blob, as well as other variables.
|
||||||
header = struct.pack(header_layout,
|
header = struct.pack(header_layout,
|
||||||
@ -1816,7 +1821,7 @@ class Freezer:
|
|||||||
1, # Version number
|
1, # Version number
|
||||||
num_pointers, # Number of pointers that follow
|
num_pointers, # Number of pointers that follow
|
||||||
0, # Codepage, not yet used
|
0, # Codepage, not yet used
|
||||||
0, # Flags, not yet used
|
flags,
|
||||||
table_offset, # Module table pointer.
|
table_offset, # Module table pointer.
|
||||||
# The following variables need to be set before static init
|
# The following variables need to be set before static init
|
||||||
# time. See configPageManager.cxx, where they are read.
|
# time. See configPageManager.cxx, where they are read.
|
||||||
@ -1830,6 +1835,7 @@ class Freezer:
|
|||||||
field_offsets.get('prc_executable_patterns', 0),
|
field_offsets.get('prc_executable_patterns', 0),
|
||||||
field_offsets.get('prc_executable_args_envvar', 0),
|
field_offsets.get('prc_executable_args_envvar', 0),
|
||||||
field_offsets.get('main_dir', 0),
|
field_offsets.get('main_dir', 0),
|
||||||
|
field_offsets.get('log_filename', 0),
|
||||||
0)
|
0)
|
||||||
|
|
||||||
# Now, find the location of the 'blobinfo' symbol in the binary,
|
# Now, find the location of the 'blobinfo' symbol in the binary,
|
||||||
|
@ -11,6 +11,7 @@ import shutil
|
|||||||
import struct
|
import struct
|
||||||
import io
|
import io
|
||||||
import imp
|
import imp
|
||||||
|
import string
|
||||||
|
|
||||||
import distutils.core
|
import distutils.core
|
||||||
import distutils.log
|
import distutils.log
|
||||||
@ -86,6 +87,8 @@ class build_apps(distutils.core.Command):
|
|||||||
self.extra_prc_files = []
|
self.extra_prc_files = []
|
||||||
self.extra_prc_data = ''
|
self.extra_prc_data = ''
|
||||||
self.default_prc_dir = None
|
self.default_prc_dir = None
|
||||||
|
self.log_filename = None
|
||||||
|
self.log_append = False
|
||||||
self.requirements_path = './requirements.txt'
|
self.requirements_path = './requirements.txt'
|
||||||
self.pypi_extra_indexes = []
|
self.pypi_extra_indexes = []
|
||||||
self.file_handlers= {
|
self.file_handlers= {
|
||||||
@ -382,7 +385,9 @@ class build_apps(distutils.core.Command):
|
|||||||
'prc_encryption_key': None,
|
'prc_encryption_key': None,
|
||||||
'prc_executable_patterns': None,
|
'prc_executable_patterns': None,
|
||||||
'prc_executable_args_envvar': None,
|
'prc_executable_args_envvar': None,
|
||||||
})
|
'main_dir': None,
|
||||||
|
'log_filename': self.expand_path(self.log_filename, platform),
|
||||||
|
}, self.log_append)
|
||||||
stub_file.close()
|
stub_file.close()
|
||||||
|
|
||||||
# Copy the dependencies.
|
# Copy the dependencies.
|
||||||
@ -818,6 +823,20 @@ class build_apps(distutils.core.Command):
|
|||||||
|
|
||||||
return deps
|
return deps
|
||||||
|
|
||||||
|
def expand_path(self, path, platform):
|
||||||
|
"Substitutes variables in the given path string."
|
||||||
|
|
||||||
|
if path is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
t = string.Template(path)
|
||||||
|
if platform.startswith('win'):
|
||||||
|
return t.substitute(HOME='~', USER_APPDATA='~/AppData/Local')
|
||||||
|
elif platform.startswith('macosx'):
|
||||||
|
return t.substitute(HOME='~', USER_APPDATA='~/Documents')
|
||||||
|
else:
|
||||||
|
return t.substitute(HOME='~', USER_APPDATA='~/.local/share')
|
||||||
|
|
||||||
|
|
||||||
class bdist_apps(distutils.core.Command):
|
class bdist_apps(distutils.core.Command):
|
||||||
DEFAULT_INSTALLERS = {
|
DEFAULT_INSTALLERS = {
|
||||||
|
@ -115,6 +115,7 @@ reload_implicit_pages() {
|
|||||||
const char *prc_executable_patterns;
|
const char *prc_executable_patterns;
|
||||||
const char *prc_executable_args_envvar;
|
const char *prc_executable_args_envvar;
|
||||||
const char *main_dir;
|
const char *main_dir;
|
||||||
|
const char *log_filename;
|
||||||
};
|
};
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
const BlobInfo *blobinfo = (const BlobInfo *)GetProcAddress(GetModuleHandle(NULL), "blobinfo");
|
const BlobInfo *blobinfo = (const BlobInfo *)GetProcAddress(GetModuleHandle(NULL), "blobinfo");
|
||||||
|
@ -6712,12 +6712,12 @@ if PkgSkip("PYTHON") == 0:
|
|||||||
TargetAdd('deploy-stub.exe', input='deploy-stub.obj')
|
TargetAdd('deploy-stub.exe', input='deploy-stub.obj')
|
||||||
if GetTarget() == 'windows':
|
if GetTarget() == 'windows':
|
||||||
TargetAdd('deploy-stub.exe', input='frozen_dllmain.obj')
|
TargetAdd('deploy-stub.exe', input='frozen_dllmain.obj')
|
||||||
TargetAdd('deploy-stub.exe', opts=['PYTHON', 'DEPLOYSTUB', 'NOICON'])
|
TargetAdd('deploy-stub.exe', opts=['WINSHELL', 'PYTHON', 'DEPLOYSTUB', 'NOICON'])
|
||||||
|
|
||||||
if GetTarget() == 'windows':
|
if GetTarget() == 'windows':
|
||||||
TargetAdd('deploy-stubw.exe', input='deploy-stub.obj')
|
TargetAdd('deploy-stubw.exe', input='deploy-stub.obj')
|
||||||
TargetAdd('deploy-stubw.exe', input='frozen_dllmain.obj')
|
TargetAdd('deploy-stubw.exe', input='frozen_dllmain.obj')
|
||||||
TargetAdd('deploy-stubw.exe', opts=['SUBSYSTEM:WINDOWS', 'PYTHON', 'DEPLOYSTUB', 'NOICON'])
|
TargetAdd('deploy-stubw.exe', opts=['SUBSYSTEM:WINDOWS', 'WINSHELL', 'PYTHON', 'DEPLOYSTUB', 'NOICON'])
|
||||||
elif GetTarget() == 'darwin':
|
elif GetTarget() == 'darwin':
|
||||||
DefSymbol('MACOS_APP_BUNDLE', 'MACOS_APP_BUNDLE')
|
DefSymbol('MACOS_APP_BUNDLE', 'MACOS_APP_BUNDLE')
|
||||||
OPTS = OPTS + ['MACOS_APP_BUNDLE']
|
OPTS = OPTS + ['MACOS_APP_BUNDLE']
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include "malloc.h"
|
# include "malloc.h"
|
||||||
|
# include <Shlobj.h>
|
||||||
#else
|
#else
|
||||||
# include <sys/mman.h>
|
# include <sys/mman.h>
|
||||||
|
# include <pwd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
@ -18,6 +20,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
# include <locale.h>
|
# include <locale.h>
|
||||||
@ -31,6 +34,11 @@
|
|||||||
other pointers that are being read by configPageManager.cxx. */
|
other pointers that are being read by configPageManager.cxx. */
|
||||||
#define MAX_NUM_POINTERS 24
|
#define MAX_NUM_POINTERS 24
|
||||||
|
|
||||||
|
/* Stored in the flags field of the blobinfo structure below. */
|
||||||
|
enum Flags {
|
||||||
|
F_log_append = 1,
|
||||||
|
};
|
||||||
|
|
||||||
/* Define an exposed symbol where we store the offset to the module data. */
|
/* Define an exposed symbol where we store the offset to the module data. */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
@ -113,6 +121,206 @@ static void set_main_dir(char *main_dir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the parent directories of the given path. Returns 1 on success.
|
||||||
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
static int mkdir_parent(const wchar_t *path) {
|
||||||
|
// Copy the path to a temporary buffer.
|
||||||
|
wchar_t buffer[4096];
|
||||||
|
size_t buflen = wcslen(path);
|
||||||
|
if (buflen + 1 >= _countof(buffer)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
wcscpy_s(buffer, _countof(buffer), path);
|
||||||
|
|
||||||
|
// Seek back to find the last path separator.
|
||||||
|
while (buflen-- > 0) {
|
||||||
|
if (buffer[buflen] == '/' || buffer[buflen] == '\\') {
|
||||||
|
buffer[buflen] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buflen == 0) {
|
||||||
|
// There was no path separator.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CreateDirectoryW(buffer, NULL) != 0) {
|
||||||
|
// Success!
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed.
|
||||||
|
DWORD last_error = GetLastError();
|
||||||
|
if (last_error == ERROR_ALREADY_EXISTS) {
|
||||||
|
// Not really an error: the directory is already there.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_error == ERROR_PATH_NOT_FOUND) {
|
||||||
|
// We need to make the parent directory first.
|
||||||
|
if (mkdir_parent(buffer)) {
|
||||||
|
// Parent successfully created. Try again to make the child.
|
||||||
|
if (CreateDirectoryW(buffer, NULL) != 0) {
|
||||||
|
// Got it!
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int mkdir_parent(const char *path) {
|
||||||
|
// Copy the path to a temporary buffer.
|
||||||
|
char buffer[4096];
|
||||||
|
size_t buflen = strlen(path);
|
||||||
|
if (buflen + 1 >= sizeof(buffer)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strcpy(buffer, path);
|
||||||
|
|
||||||
|
// Seek back to find the last path separator.
|
||||||
|
while (buflen-- > 0) {
|
||||||
|
if (buffer[buflen] == '/') {
|
||||||
|
buffer[buflen] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buflen == 0) {
|
||||||
|
// There was no path separator.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (mkdir(buffer, 0755) == 0) {
|
||||||
|
// Success!
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed.
|
||||||
|
if (errno == EEXIST) {
|
||||||
|
// Not really an error: the directory is already there.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno == ENOENT || errno == EACCES) {
|
||||||
|
// We need to make the parent directory first.
|
||||||
|
if (mkdir_parent(buffer)) {
|
||||||
|
// Parent successfully created. Try again to make the child.
|
||||||
|
if (mkdir(buffer, 0755) == 0) {
|
||||||
|
// Got it!
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects the output streams to point to the log file with the given path.
|
||||||
|
*
|
||||||
|
* @param path specifies the location of log file, may start with ~
|
||||||
|
* @param append should be nonzero if it should not truncate the log file.
|
||||||
|
*/
|
||||||
|
static int setup_logging(const char *path, int append) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Does it start with a tilde? Perform tilde expansion if so.
|
||||||
|
wchar_t pathw[MAX_PATH * 2];
|
||||||
|
size_t offset = 0;
|
||||||
|
if (path[0] == '~' && (path[1] == 0 || path[1] == '/' || path[1] == '\\')) {
|
||||||
|
// Strip off the tilde.
|
||||||
|
++path;
|
||||||
|
|
||||||
|
// Get the home directory path for the current user.
|
||||||
|
if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, pathw))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
offset = wcslen(pathw);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to convert the rest of the path from UTF-8 to UTF-16.
|
||||||
|
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, pathw + offset,
|
||||||
|
(int)(_countof(pathw) - offset)) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD access = append ? FILE_APPEND_DATA : (GENERIC_READ | GENERIC_WRITE);
|
||||||
|
int creation = append ? OPEN_ALWAYS : CREATE_ALWAYS;
|
||||||
|
HANDLE handle = CreateFileW(pathw, access, FILE_SHARE_DELETE | FILE_SHARE_READ,
|
||||||
|
NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
|
// Make the parent directories first.
|
||||||
|
mkdir_parent(pathw);
|
||||||
|
handle = CreateFileW(pathw, access, FILE_SHARE_DELETE | FILE_SHARE_READ,
|
||||||
|
NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (append) {
|
||||||
|
SetFilePointer(handle, 0, NULL, FILE_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
|
int fd = _open_osfhandle((intptr_t)handle, _O_WRONLY | _O_TEXT | (append ? _O_APPEND : 0));
|
||||||
|
SetStdHandle(STD_OUTPUT_HANDLE, handle);
|
||||||
|
_dup2(fd, 1);
|
||||||
|
|
||||||
|
SetStdHandle(STD_ERROR_HANDLE, handle);
|
||||||
|
_dup2(fd, 2);
|
||||||
|
|
||||||
|
_close(fd);
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
// Does it start with a tilde? Perform tilde expansion if so.
|
||||||
|
char buffer[PATH_MAX * 2];
|
||||||
|
size_t offset = 0;
|
||||||
|
if (path[0] == '~' && (path[1] == 0 || path[1] == '/')) {
|
||||||
|
// Strip off the tilde.
|
||||||
|
++path;
|
||||||
|
|
||||||
|
// Get the home directory path for the current user.
|
||||||
|
const char *home_dir = getenv("HOME");
|
||||||
|
if (home_dir == NULL) {
|
||||||
|
home_dir = getpwuid(getuid())->pw_dir;
|
||||||
|
}
|
||||||
|
offset = strlen(home_dir);
|
||||||
|
assert(offset < sizeof(buffer));
|
||||||
|
strncpy(buffer, home_dir, sizeof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy over the rest of the path.
|
||||||
|
strcpy(buffer + offset, path);
|
||||||
|
|
||||||
|
mode_t mode = O_CREAT | O_WRONLY | (append ? O_APPEND : O_TRUNC);
|
||||||
|
int fd = open(buffer, mode, 0644);
|
||||||
|
if (fd == -1) {
|
||||||
|
// Make the parent directories first.
|
||||||
|
mkdir_parent(buffer);
|
||||||
|
fd = open(buffer, mode, 0644);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == -1) {
|
||||||
|
perror(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
|
dup2(fd, 1);
|
||||||
|
dup2(fd, 2);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Main program */
|
/* Main program */
|
||||||
|
|
||||||
#ifdef WIN_UNICODE
|
#ifdef WIN_UNICODE
|
||||||
@ -389,7 +597,9 @@ int main(int argc, char *argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
int retval;
|
int retval;
|
||||||
struct _frozen *moddef;
|
struct _frozen *moddef;
|
||||||
|
const char *log_filename;
|
||||||
void *blob = NULL;
|
void *blob = NULL;
|
||||||
|
log_filename = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
printf("blob_offset: %d\n", (int)blobinfo.blob_offset);
|
printf("blob_offset: %d\n", (int)blobinfo.blob_offset);
|
||||||
@ -418,6 +628,9 @@ int main(int argc, char *argv[]) {
|
|||||||
blobinfo.pointers[i] = (void *)((uintptr_t)blobinfo.pointers[i] + (uintptr_t)blob);
|
blobinfo.pointers[i] = (void *)((uintptr_t)blobinfo.pointers[i] + (uintptr_t)blob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (blobinfo.num_pointers >= 12) {
|
||||||
|
log_filename = blobinfo.pointers[11];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
blobinfo.pointers[0] = blob;
|
blobinfo.pointers[0] = blob;
|
||||||
}
|
}
|
||||||
@ -434,6 +647,10 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (log_filename != NULL) {
|
||||||
|
setup_logging(log_filename, (blobinfo.flags & F_log_append) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (blobinfo.codepage != 0) {
|
if (blobinfo.codepage != 0) {
|
||||||
SetConsoleCP(blobinfo.codepage);
|
SetConsoleCP(blobinfo.codepage);
|
||||||
|
@ -12,6 +12,8 @@ setup(
|
|||||||
'gui_apps': {
|
'gui_apps': {
|
||||||
'asteroids': 'main.py',
|
'asteroids': 'main.py',
|
||||||
},
|
},
|
||||||
|
'log_filename': '$USER_APPDATA/Asteroids/output.log',
|
||||||
|
'log_append': False,
|
||||||
'plugins': [
|
'plugins': [
|
||||||
'pandagl',
|
'pandagl',
|
||||||
'p3openal_audio',
|
'p3openal_audio',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user