From cb713385247fdd23f00b804609cb8324c2035c7e Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 08:59:35 -0500 Subject: [PATCH 01/12] Add LOCAL_PANDA_BUILD envvar to cmake paths --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2b6820..b1471fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,6 +163,11 @@ if (WIN32) link_directories("${PANDA_LIBRARY_DIRS}") else() + if(EXISTS "${LOCAL_PANDA_BUILD}") + set(PANDA_LIBRARY_DIRS "${LOCAL_PANDA_BUILD}/lib") + set(PANDA_INCLUDE_DIR "${LOCAL_PANDA_BUILD}/include") + endif() + set(PYTHONVERDOT CACHE STRING "2.7") set(Python_ADDITIONAL_VERSIONS ${PYTHONVERDOT}) find_package(PythonLibs REQUIRED) @@ -202,7 +207,7 @@ else() find_path(PANDA_INCLUDE_DIR dtoolbase.h PATH_SUFFIXES panda3d) # Locate the Panda3D libraries - set(REQ_LIBRARIES p3framework panda pandaexpress p3dtool p3dtoolconfig p3direct ${INTERROGATE_LIB}) + set(REQ_LIBRARIES p3framework panda pandaexpress p3dtool p3dtoolconfig p3direct "${INTERROGATE_LIB}") if(HAVE_LIB_BULLET) set(REQ_LIBRARIES pandabullet ${REQ_LIBRARIES}) endif() @@ -218,7 +223,6 @@ else() if (NOT EXISTS ${PANDA_INCLUDE_DIR}) # Okay, the standard package handling failed. Try finding a local panda3d installation - # Find panda path execute_process( COMMAND "${PYTHON_EXECUTABLE}" "-B" "scripts/common.py" "--print-sdk-path" From 23f2b1c4834c4e30ad53a98202cb27e7f49a1613 Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 09:06:52 -0500 Subject: [PATCH 02/12] Unnecessary change removed to clean up PR --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1471fc..7ada139 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,7 +207,7 @@ else() find_path(PANDA_INCLUDE_DIR dtoolbase.h PATH_SUFFIXES panda3d) # Locate the Panda3D libraries - set(REQ_LIBRARIES p3framework panda pandaexpress p3dtool p3dtoolconfig p3direct "${INTERROGATE_LIB}") + set(REQ_LIBRARIES p3framework panda pandaexpress p3dtool p3dtoolconfig p3direct ${INTERROGATE_LIB}) if(HAVE_LIB_BULLET) set(REQ_LIBRARIES pandabullet ${REQ_LIBRARIES}) endif() From e66ffd54a9d8894ea95b29f0f5c4f4e3f324e60b Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 11:53:21 -0500 Subject: [PATCH 03/12] Start of logging and debug and best practices --- scripts/common.py | 8 +++++++- scripts/interrogate.py | 23 ++++++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/scripts/common.py b/scripts/common.py index 7729469..3beaadf 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -6,16 +6,20 @@ from __future__ import print_function +import logging +logger = logging.getLogger(__name__) + import locale import sys import subprocess import platform from os.path import dirname, realpath, join, isdir, isfile -from os import makedirs +from os import makedirs, environ from sys import argv, stdout, stderr, exit from panda3d.core import PandaSystem, Filename, ExecutionEnvironment +build_path_envvar = 'LOCAL_PANDA_BUILD' class MSVCVersion(object): def __init__(self, msc_ver, cmake_str, suffix): @@ -66,6 +70,8 @@ def get_output_dir(): def get_panda_sdk_path(): """ Returns the path of the panda3d sdk, under windows """ + if build_path_envvar in environ: + return environ[build_path_envvar] # Import the base panda3d module import panda3d diff --git a/scripts/interrogate.py b/scripts/interrogate.py index 0fbd824..e35bac4 100644 --- a/scripts/interrogate.py +++ b/scripts/interrogate.py @@ -8,6 +8,8 @@ import sys from os import listdir, chdir from os.path import join, isfile, isdir +import logging +logger = logging.getLogger(__name__) from panda3d.core import PandaSystem from common import debug_out, get_panda_bin_path, get_panda_include_path @@ -19,8 +21,9 @@ # Parameters -MODULE_NAME = sys.argv[1] -VERBOSE_LVL = int(sys.argv[2]) # Assume the user did specify something valid +#set with __main__ or caller, don't default +MODULE_NAME = None +VERBOSE_LVL = None def check_ignore(source): @@ -128,8 +131,22 @@ def interrogate_module(): if __name__ == "__main__": + # Parameters + # TODO: add reall param processing + loglevel = logging.INFO + param_offset = 0 + if sys.argv[1] == '-d' or sys.argv[1] == '--debug': + loglevel = logging.DEBUG + param_offset+=1 + logging.basicConfig(level=loglevel) + + MODULE_NAME = sys.argv[1+param_offset] + VERBOSE_LVL = int(sys.argv[2+param_offset]) + # Change into the source directory - source_dir = join(get_script_dir(), "../source/") + import pudb + pu.db + source_dir = join(get_script_dir(), '..', 'source') chdir(source_dir) interrogate() From 7c3b0588a89a6aaef24545a6771b563f4e703620 Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 12:10:48 -0500 Subject: [PATCH 04/12] Add local build environment override envvar --- scripts/common.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/common.py b/scripts/common.py index 3beaadf..b9499e9 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -88,12 +88,18 @@ def get_panda_sdk_path(): def get_panda_core_lib_path(): """ Returns of the path of the core panda3d module, either core.pyd on windows or core.so on linux. This is an absolute path """ + # NOTE: this may be completely different than the local build + # but even if it is the local build core and the import core + # **should** be identical. If they aren't then the developer + # should get a warning so s/he knows about it. import panda3d.core return panda3d.core.__file__ def get_panda_bin_path(): """ Returns the path to the panda3d binaries """ + if build_path_envvar in environ: + return join(environ[build_path_envvar], 'bin') if is_windows(): return first_existing_path([join(get_panda_sdk_path(), "bin")], "interrogate.exe") elif is_linux() or is_freebsd(): @@ -111,6 +117,8 @@ def get_panda_bin_path(): def get_panda_lib_path(): """ Returns the path to the panda3d libraries """ + if build_path_envvar in environ: + return join(environ[build_path_envvar], 'lib') if is_windows(): return first_existing_path([join(get_panda_sdk_path(), "lib")], "libpanda.lib") elif is_linux() or is_macos() or is_freebsd(): @@ -120,6 +128,8 @@ def get_panda_lib_path(): def get_panda_include_path(): """ Returns the path to the panda3d includes """ + if build_path_envvar in environ: + return join(environ[build_path_envvar], 'include') if is_windows() or is_macos(): return first_existing_path([join(get_panda_sdk_path(), "include")], "dtoolbase.h") elif is_linux() or is_freebsd(): From 8d03da36a00ac3d2592502e775615cae01fd896a Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 12:32:12 -0500 Subject: [PATCH 05/12] Remove breakpoints from copied code --- scripts/interrogate.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/interrogate.py b/scripts/interrogate.py index e35bac4..29a9a4e 100644 --- a/scripts/interrogate.py +++ b/scripts/interrogate.py @@ -144,8 +144,6 @@ def interrogate_module(): VERBOSE_LVL = int(sys.argv[2+param_offset]) # Change into the source directory - import pudb - pu.db source_dir = join(get_script_dir(), '..', 'source') chdir(source_dir) From 5f19e70f767b4eac4e0ec8eed75c968a26365d8b Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 13:18:29 -0500 Subject: [PATCH 06/12] remove sys.exit, add FatalError exception, raise exception, add loggging based control of error handling --- scripts/common.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/scripts/common.py b/scripts/common.py index b9499e9..d43afcd 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -21,6 +21,15 @@ build_path_envvar = 'LOCAL_PANDA_BUILD' +class FatalError(Exception): + """FatalError + Exception to raise fatal errors instead of calling exit + """ + msgs = None + def __init__(self, *msgs): + super().__init__(msgs[0]) + self.msgs = msgs + class MSVCVersion(object): def __init__(self, msc_ver, cmake_str, suffix): self.version = msc_ver @@ -197,19 +206,18 @@ def decode_str(s): def fatal_error(*args): """ Prints an error to stderr and then exits with a nonzero status code """ - - print("\n\n[!] FATAL ERROR:", *[decode_str(i) for i in args], file=stderr) - exit(1) + logger.error(' '.join('FATAL: ', *[decode_str(i) for i in args])) + raise FatalError(args) def debug_out(*args): """ Prints a debug output string """ - print(*[decode_str(i) for i in args]) + logger.debug(''.join(*[decode_str(i) for i in args])) def print_error(*args): """ Prints a debug output string """ - print(*[decode_str(i) for i in args], file=sys.stderr) + logger.error(' '.join(*[decode_str(i) for i in args])) def try_makedir(dirname): @@ -277,13 +285,12 @@ def get_panda_mscv_version(): if msvc_version.compiler_search_string in compiler: return msvc_version - print("FATAL ERROR: Unable to detect visual studio version of your Panda3D Build!", file=sys.stderr) - print("Unkown compiler string was: '" + compiler + "'", file=sys.stderr) - print("", file=sys.stderr) - print("Known visual studio versions are:", file=sys.stderr) + logger.error("FATAL ERROR: Unable to detect visual studio version of your Panda3D Build!") + logger.error("Unkown compiler string was: '" + compiler + "'") + logger.error("Known visual studio versions are:") for msvc_version in MSVC_VERSIONS: - print("-", msvc_version.cmake_str, "(" + msvc_version.compiler_search_string + ")", file=sys.stderr) - print("", file=sys.stderr) + logger.error("-", msvc_version.cmake_str, "(" + msvc_version.compiler_search_string + ")") + logger.error("") fatal_error("Unable to determine compiler") def get_panda_short_version(): From 802c263026ac7de989d51f0e8581c867243e6721 Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 13:22:57 -0500 Subject: [PATCH 07/12] remove array unpack on join call --- scripts/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/common.py b/scripts/common.py index d43afcd..d2669a1 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -212,12 +212,12 @@ def fatal_error(*args): def debug_out(*args): """ Prints a debug output string """ - logger.debug(''.join(*[decode_str(i) for i in args])) + logger.debug(''.join([decode_str(i) for i in args])) def print_error(*args): """ Prints a debug output string """ - logger.error(' '.join(*[decode_str(i) for i in args])) + logger.error(' '.join([decode_str(i) for i in args])) def try_makedir(dirname): From 5869f50dfce953d578be5de724e4c1329474e900 Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 15:55:42 -0500 Subject: [PATCH 08/12] pass the envvar to cmake as option --- scripts/setup.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/setup.py b/scripts/setup.py index 8d3d9ac..9cc8357 100644 --- a/scripts/setup.py +++ b/scripts/setup.py @@ -2,7 +2,7 @@ import shutil import sys import multiprocessing -from os import chdir, _exit +from os import chdir, _exit, environ from os.path import isdir, isfile from panda3d.core import PandaSystem @@ -10,7 +10,7 @@ from .common import is_linux, join_abs, get_panda_lib_path, is_64_bit from .common import try_execute, get_script_dir, get_panda_mscv_version from .common import have_eigen, have_bullet, have_freetype, print_error -from .common import is_macos, is_freebsd +from .common import is_macos, is_freebsd, build_path_envvar def make_output_dir(clean=False): @@ -86,6 +86,10 @@ def run_cmake(config, args): # Panda is 64-bit only on macOS. cmake_args += ["-DCMAKE_CL_64:STRING=1"] + if build_path_envvar in environ: + cmake_args.append("-D{}:STRING={}".format(build_path_envvar, + environ[build_path_envvar]) + # Specify python version, once as integer, once seperated by a dot pyver = "{}{}".format(sys.version_info.major, sys.version_info.minor) pyver_dot = "{}.{}".format(sys.version_info.major, sys.version_info.minor) @@ -109,12 +113,12 @@ def is_required(lib): """ # Eigen is always included in 1.9.1 and up cmake_args += ["-DHAVE_LIB_EIGEN=TRUE"] - + if is_required("bullet"): if not have_bullet(): fatal_error("Your Panda3D build was not compiled with bullet support, but it is required!") cmake_args += ["-DHAVE_LIB_BULLET=TRUE"] - + if is_required("freetype"): if not have_freetype(): fatal_error("Your Panda3D build was not compiled with freetype support, but it is required!") From 489b545f57ac124366843bffd877ada0e587aad0 Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 16:28:59 -0500 Subject: [PATCH 09/12] missing closing parenthesis --- scripts/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup.py b/scripts/setup.py index 9cc8357..18b42e6 100644 --- a/scripts/setup.py +++ b/scripts/setup.py @@ -88,7 +88,7 @@ def run_cmake(config, args): if build_path_envvar in environ: cmake_args.append("-D{}:STRING={}".format(build_path_envvar, - environ[build_path_envvar]) + environ[build_path_envvar])) # Specify python version, once as integer, once seperated by a dot pyver = "{}{}".format(sys.version_info.major, sys.version_info.minor) From 66fb9e3ec410d81da80342ba6a6f9eb179e670a4 Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 16:39:59 -0500 Subject: [PATCH 10/12] logging and --debug option --- build.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/build.py b/build.py index fdadbbe..9db5f92 100755 --- a/build.py +++ b/build.py @@ -7,6 +7,8 @@ import os import argparse from os.path import join, realpath, dirname +import logging +logger = logging.getLogger(__name__) # Change into the current directory os.chdir(dirname(realpath(__file__))) @@ -15,7 +17,7 @@ from scripts.setup import make_output_dir, run_cmake, run_cmake_build if __name__ == "__main__": - + loglevel = logging.WARN # Arguments parser = argparse.ArgumentParser(description="P3DModuleBuilder") parser.add_argument( @@ -23,7 +25,15 @@ help="Optimize level, should match the one used for the Panda3D build",) parser.add_argument( "--clean", action="store_true", help="Forces a clean rebuild") + parser.add_argument('--debug', action='store_true') + parser.add_argument('--verbose', action='store_true') args = parser.parse_args() + if args.debug: + loglevel = logging.DEBUG + elif args.verbose: + loglevel = logging.INFO + # set loging default basic configuration and loglevel + logging.basicConfig(level=loglevel) # Python 2 compatibility if sys.version_info.major > 2: @@ -40,7 +50,7 @@ # Check for outdated parameters for outdated_param in ["vc_version", "use_lib_eigen", "use_lib_bullet", "use_lib_freetype"]: if outdated_param in config: - print("WARNING: Removing obsolete parameter '" + outdated_param + "', is now auto-detected.") + logger.warn("Removing obsolete parameter '" + outdated_param + "', is now auto-detected.") del config[outdated_param] # Write back config From 578b3932352360a1872637f3a46ee57f550c6264 Mon Sep 17 00:00:00 2001 From: magregor Date: Tue, 27 Feb 2018 20:08:28 -0500 Subject: [PATCH 11/12] Add envvar to the cmake library path --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ada139..d5fea96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,6 +166,7 @@ else() if(EXISTS "${LOCAL_PANDA_BUILD}") set(PANDA_LIBRARY_DIRS "${LOCAL_PANDA_BUILD}/lib") set(PANDA_INCLUDE_DIR "${LOCAL_PANDA_BUILD}/include") + set(CMAKE_LIBRARY_PATH "${CMAKE_LIBRARY_PATH};${PANDA_LIBRARY_DIRS}") endif() set(PYTHONVERDOT CACHE STRING "2.7") From fc92c5aadf288187aa6d8623faa7e3656d3cf030 Mon Sep 17 00:00:00 2001 From: magregor Date: Fri, 2 Mar 2018 00:06:13 -0500 Subject: [PATCH 12/12] Add custom logging --- build.py | 51 +++++++++++++++++++++++++++++++++++++++++------- scripts/setup.py | 5 ++++- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/build.py b/build.py index 9db5f92..7ffa13a 100755 --- a/build.py +++ b/build.py @@ -7,7 +7,47 @@ import os import argparse from os.path import join, realpath, dirname + +# Configure Logging Module import logging + +# Custom logging formatter +VERBOSE = logging.INFO - 1 # INFO== for verbose logging + +class CustomLogFormatter(logging.Formatter): + err_fmt = "ERROR: %(message)s" + dbg_fmt = "DEBUG: %(module)s: %(lineno)d: %(message)s" + info_fmt = "%(message)s" + + def __init__(self, fmt="%(msg)s"): + logging.Formatter.__init__(self, fmt) + + def format(self, record): + format_orig = self._fmt + if record.levelno == logging.DEBUG: + self._fmt = CustomLogFormatter.dbg_fmt +# elif record.levelno in (logging.INFO, VERBOSE): +# self._fmt = CustomLogFormatter.info_fmt + elif record.levelno == logging.ERROR: + self._fmt = CustomLogFormatter.err_fmt + result = super().format(record) + self._fmt = format_orig + return result + +logging.addLevelName(VERBOSE, 'VERBOSE') +# -logger - add custom loglevel +def verbose(self, message, *args, **kwargs): + # Yes, logger takes its '*args' as 'args'. + if self.isEnabledFor(VERBOSE): + self._log(VERBOSE, message, args, **kwargs) +#add method for verbose logging +logging.Logger.verbose = verbose +custom_log_format = CustomLogFormatter() +handler_hook = logging.StreamHandler() +handler_hook.setFormatter(custom_log_format) +logging.basicConfig(level=logging.DEBUG, + format='%(message)s', + handlers=[handler_hook]) logger = logging.getLogger(__name__) # Change into the current directory @@ -17,7 +57,6 @@ from scripts.setup import make_output_dir, run_cmake, run_cmake_build if __name__ == "__main__": - loglevel = logging.WARN # Arguments parser = argparse.ArgumentParser(description="P3DModuleBuilder") parser.add_argument( @@ -28,12 +67,11 @@ parser.add_argument('--debug', action='store_true') parser.add_argument('--verbose', action='store_true') args = parser.parse_args() + if args.debug: - loglevel = logging.DEBUG + logger.setLevel(logging.DEBUG) elif args.verbose: - loglevel = logging.INFO - # set loging default basic configuration and loglevel - logging.basicConfig(level=loglevel) + logger.setLevel(VERBOSE) # Python 2 compatibility if sys.version_info.major > 2: @@ -61,5 +99,4 @@ run_cmake(config, args) run_cmake_build(config, args) - print("Success!") - sys.exit(0) + logger.info("Success!") diff --git a/scripts/setup.py b/scripts/setup.py index 94dc063..3e831ca 100644 --- a/scripts/setup.py +++ b/scripts/setup.py @@ -4,6 +4,9 @@ import multiprocessing from os import chdir, _exit, environ from os.path import isdir, isfile +import logging +logger = logging.getLogger(__name__) + from panda3d.core import PandaSystem from .common import get_output_dir, try_makedir, fatal_error, is_windows @@ -21,7 +24,7 @@ def make_output_dir(clean=False): # Cleanup output directory in case clean is specified if isdir(output_dir) and clean: - print("Cleaning up output directory ..") + logger.info("Cleaning up output directory ..") shutil.rmtree(output_dir) try_makedir(output_dir)