[Bf-blender-cvs] [5e2d139ee30] master: Fix Blender as a Python module for WIN32

Campbell Barton noreply at git.blender.org
Thu Sep 8 12:34:12 CEST 2022


Commit: 5e2d139ee30d88b474d3e7d65d5ff37d0be086b6
Author: Campbell Barton
Date:   Thu Sep 8 20:27:03 2022 +1000
Branches: master
https://developer.blender.org/rB5e2d139ee30d88b474d3e7d65d5ff37d0be086b6

Fix Blender as a Python module for WIN32

BKE_appdir_program_path_init would override the module path extracted
from the Python module, replacing it with the Python executable.

This caused the data files not to be found and the module not to load.

===================================================================

M	source/blender/blenkernel/BKE_appdir.h
M	source/blender/blenkernel/intern/appdir.c
M	source/creator/creator.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
index dcacc2ca7b3..16488bdbf09 100644
--- a/source/blender/blenkernel/BKE_appdir.h
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -105,8 +105,11 @@ void BKE_appdir_app_templates(struct ListBase *templates);
 
 /**
  * Initialize path to program executable.
+ *
+ * \param strict: When true, use `argv0` unmodified (besides making absolute & normalizing).
+ * Otherwise other methods may be used to find the program path, including searching `$PATH`.
  */
-void BKE_appdir_program_path_init(const char *argv0);
+void BKE_appdir_program_path_init(const char *argv0, bool strict);
 
 /**
  * Path to executable
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 031d3647878..c19afdb4fb8 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -794,11 +794,11 @@ const char *BKE_appdir_folder_id_version(const int folder_id,
  * (must be #FILE_MAX minimum)
  * \param name: The name of the executable (usually `argv[0]`) to be checked
  */
-static void where_am_i(char *fullname, const size_t maxlen, const char *name)
+static void where_am_i(char *fullname, const size_t maxlen, const char *name, const bool strict)
 {
 #ifdef WITH_BINRELOC
   /* Linux uses `binreloc` since `argv[0]` is not reliable, call `br_init(NULL)` first. */
-  {
+  if (!strict) {
     const char *path = NULL;
     path = br_find_exe(NULL);
     if (path) {
@@ -810,7 +810,7 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
 #endif
 
 #ifdef _WIN32
-  {
+  if (!strict) {
     wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath");
     if (GetModuleFileNameW(0, fullname_16, maxlen)) {
       conv_utf_16_to_8(fullname_16, fullname, maxlen);
@@ -834,18 +834,24 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
     if (name[0] == '.') {
       BLI_path_abs_from_cwd(fullname, maxlen);
 #ifdef _WIN32
-      BLI_path_program_extensions_add_win32(fullname, maxlen);
+      if (!strict) {
+        BLI_path_program_extensions_add_win32(fullname, maxlen);
+      }
 #endif
     }
     else if (BLI_path_slash_rfind(name)) {
       /* Full path. */
       BLI_strncpy(fullname, name, maxlen);
 #ifdef _WIN32
-      BLI_path_program_extensions_add_win32(fullname, maxlen);
+      if (!strict) {
+        BLI_path_program_extensions_add_win32(fullname, maxlen);
+      }
 #endif
     }
     else {
-      BLI_path_program_search(fullname, maxlen, name);
+      if (!strict) {
+        BLI_path_program_search(fullname, maxlen, name);
+      }
     }
     /* Remove "/./" and "/../" so string comparisons can be used on the path. */
     BLI_path_normalize(NULL, fullname);
@@ -858,9 +864,9 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
   }
 }
 
-void BKE_appdir_program_path_init(const char *argv0)
+void BKE_appdir_program_path_init(const char *argv0, const bool strict)
 {
-  where_am_i(g_app.program_filepath, sizeof(g_app.program_filepath), argv0);
+  where_am_i(g_app.program_filepath, sizeof(g_app.program_filepath), argv0, strict);
   BLI_split_dir_part(g_app.program_filepath, g_app.program_dirname, sizeof(g_app.program_dirname));
 }
 
diff --git a/source/creator/creator.c b/source/creator/creator.c
index e7a803d383f..e7e9eeed79a 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -233,6 +233,12 @@ void gmp_blender_init_allocator()
 /** \name Main Function
  * \{ */
 
+/* When building as a Python module, don't use special argument handling
+ * so the module loading logic can control the `argv` & `argc`. */
+#if defined(WIN32) && !defined(WITH_PYTHON_MODULE)
+#  define USE_WIN32_UNICODE_ARGS
+#endif
+
 /**
  * Blender's main function responsibilities are:
  * - setup subsystems.
@@ -241,7 +247,7 @@ void gmp_blender_init_allocator()
  *   or exit immediately when running in background-mode.
  */
 int main(int argc,
-#ifdef WIN32
+#ifdef USE_WIN32_UNICODE_ARGS
          const char **UNUSED(argv_c)
 #else
          const char **argv
@@ -254,7 +260,7 @@ int main(int argc,
   bArgs *ba;
 #endif
 
-#ifdef WIN32
+#ifdef USE_WIN32_UNICODE_ARGS
   char **argv;
   int argv_num;
 #endif
@@ -284,6 +290,7 @@ int main(int argc,
   /* NOTE: cannot use `guardedalloc` allocation here, as it's not yet initialized
    *       (it depends on the arguments passed in, which is what we're getting here!)
    */
+#  ifdef USE_WIN32_UNICODE_ARGS
   {
     wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
     argv = malloc(argc * sizeof(char *));
@@ -296,7 +303,8 @@ int main(int argc,
     app_init_data.argv = argv;
     app_init_data.argv_num = argv_num;
   }
-#endif /* WIN32 */
+#  endif /* USE_WIN32_UNICODE_ARGS */
+#endif   /* WIN32 */
 
   /* NOTE: Special exception for guarded allocator type switch:
    *       we need to perform switch from lock-free to fully
@@ -388,7 +396,17 @@ int main(int argc,
 #endif
 
   /* Initialize path to executable. */
-  BKE_appdir_program_path_init(argv[0]);
+  {
+#ifdef WITH_PYTHON_MODULE
+    /* NOTE(@campbellbarton): Always use `argv[0]` as is, when building as a Python module.
+     * Otherwise other methods of detecting the binary that override this argument
+     * which must point to the Python module for data-files to be detected. */
+    const bool strict = true;
+#else
+    const bool strict = false;
+#endif
+    BKE_appdir_program_path_init(argv[0], strict);
+  }
 
   BLI_threadapi_init();



More information about the Bf-blender-cvs mailing list