mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-03 21:32:35 +00:00
- Improved strategy to detect pyenv managed python libraries
- Improved documents on python bridge
This commit is contained in:
parent
e8052a004b
commit
2962b9d52e
@ -4,7 +4,7 @@ This document is a comprehensive guide for writing custom hash modes in Python v
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
The The Assimilation Bridge enables developers to implement complete hash mode logic in languages other than C, most notably Python. Traditionally, customizing Hashcat required writing a module in C and a kernel in OpenCL/CUDA. With the bridge, you can now implement a complete hash mode in Python.
|
||||
The Assimilation Bridge enables developers to implement complete hash mode logic in languages other than C, most notably Python. Traditionally, customizing Hashcat required writing a module in C and a kernel in OpenCL/CUDA. With the bridge, you can now implement a complete hash mode in Python.
|
||||
|
||||
The bridge supports two hash modes to run python code:
|
||||
|
||||
@ -81,7 +81,7 @@ def term(ctx):
|
||||
hcsp.term(ctx)
|
||||
```
|
||||
|
||||
This should be used in case you had open files, open networking connection, or similar. We are good citizen!
|
||||
This should be used in case you had open files, open networking connection, or similar. We are good citizens!
|
||||
|
||||
Here's our main function `kernel_loop()` where we spend almost all our time:
|
||||
|
||||
@ -180,7 +180,7 @@ The `salt` variable is one of the parameters from the calc_hash():
|
||||
def calc_hash(password: bytes, salt: dict) -> str:
|
||||
```
|
||||
|
||||
Note that if fully exhaust the Hashcat keyspace, your function has been called X times Y. X is the number of candidates, and Y is all the salts (except if a salt has been cracked). What's important to realize that within your function, you implement hashing logic only for precisely that situation where you have one password and one salt.
|
||||
Note that if you fully exhaust the Hashcat keyspace, your function has been called X times Y.. X is the number of candidates, and Y is all the salts (except if a salt has been cracked). What's important to realize that within your function, you implement hashing logic only for precisely that situation where you have one password and one salt.
|
||||
|
||||
|
||||
### Merging Salts and Esalts into a Single Object
|
||||
@ -196,7 +196,7 @@ Initially, salts and esalts are unpacked separately from their respective binary
|
||||
|
||||
## 6. Python generic hash mode `-m 72000` and `-m 73000`
|
||||
|
||||
The "generic hash" support in hashcat is using python. The main idea behind "generic" is the goal is to write freely ideal for rapid prototyping.
|
||||
The "generic hash" support in hashcat is using python. The main idea behind "generic" is to write freely. Ideal for rapid prototyping and achieving your goal.
|
||||
|
||||
The most straight-forward way is to edit the following files directly:
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
|
||||
# Hashcat Python Plugin Quickstart
|
||||
|
||||
## Introduction
|
||||
|
||||
This guide walks you through building custom hash modes in **pure Python** using Hashcat v7's Python plugin interface via the new assimilation bridge.
|
||||
Hashcat v7 introduces a `Python plugin bridge` that allows you to write and integrate custom hash-matching algorithms directly in Python. This plugin system fits into the regular cracking workflow by replacing or extending internal kernel routines.
|
||||
|
||||
Whether you're experimenting with a new algorithm, supporting a proprietary format, prototyping a new feature, or simply prefer writing in a high-level language, this plugin interface makes development fast and straightforward.
|
||||
When enabled, Hashcat uses the plugin’s `calc_hash()` function to compute hash candidates for verification, making it easy to experiment with new or obscure algorithms without modifying core C code or writing OpenCL/CUDA kernels.
|
||||
|
||||
No C required. No recompilation. Just write your logic in Python in the `calc_hash()` function.
|
||||
This guide demonstrates how to quickly customize such an algorithm using pure Python. Whether you're prototyping a new hash mode, supporting a proprietary format, or simply prefer high-level development, Python plugins make the process fast and straightforward.
|
||||
|
||||
No C required. No recompilation. Just write your logic in Python using `calc_hash()`, and you're ready to crack.
|
||||
|
||||
You can use any Python modules you like.
|
||||
|
||||
|
@ -191,26 +191,197 @@ static char *DEFAULT_SOURCE_FILENAME = "generic_hash_sp";
|
||||
static char *DEFAULT_SOURCE_FILENAME = "generic_hash_mp";
|
||||
#endif
|
||||
|
||||
#if defined (_WIN)
|
||||
#define DEVNULL "NUL"
|
||||
#else
|
||||
#define DEVNULL "/dev/null"
|
||||
#endif
|
||||
|
||||
static int suppress_stderr (void)
|
||||
{
|
||||
int null_fd = open (DEVNULL, O_WRONLY);
|
||||
|
||||
if (null_fd < 0) return -1;
|
||||
|
||||
int saved_fd = dup (fileno (stderr));
|
||||
|
||||
if (saved_fd < 0)
|
||||
{
|
||||
close (null_fd);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
dup2 (null_fd, fileno (stderr));
|
||||
|
||||
close (null_fd);
|
||||
|
||||
return saved_fd;
|
||||
}
|
||||
|
||||
static void restore_stderr (int saved_fd)
|
||||
{
|
||||
if (saved_fd < 0) return;
|
||||
|
||||
dup2 (saved_fd, fileno (stderr));
|
||||
|
||||
close (saved_fd);
|
||||
}
|
||||
|
||||
static char *expand_pyenv_libpath (const char *prefix, const int maj, const int min)
|
||||
{
|
||||
char *out = NULL;
|
||||
|
||||
#if defined (_WIN)
|
||||
const int len = asprintf (&out, "%s/python%d%d.dll", prefix, maj, min); //untested
|
||||
#elif defined (__MSYS__)
|
||||
const int len = asprintf (&out, "%s/msys-python%d.%d.dll", prefix, maj, min); //untested could be wrong
|
||||
#elif defined (__APPLE__)
|
||||
const int len = asprintf (&out, "%s/lib/libpython%d.%d.dylib", prefix, maj, min); //untested
|
||||
#elif defined (__CYGWIN__)
|
||||
const int len = asprintf (&out, "%s/lib/python%d%d.dll", prefix, maj, min); //untested
|
||||
#else
|
||||
const int len = asprintf (&out, "%s/lib/libpython%d.%d.so", prefix, maj, min);
|
||||
#endif
|
||||
|
||||
if (len == -1) return NULL;
|
||||
|
||||
struct stat st;
|
||||
|
||||
if (stat (out, &st) != 0)
|
||||
{
|
||||
free (out);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static int resolve_pyenv_libpath (char *out_buf, const size_t out_sz)
|
||||
{
|
||||
// prefix
|
||||
|
||||
FILE *fp1 = popen ("pyenv prefix", "r");
|
||||
|
||||
if (fp1 == NULL) return -1;
|
||||
|
||||
char prefix_path[PATH_MAX];
|
||||
|
||||
if (fgets (prefix_path, sizeof (prefix_path), fp1) == NULL)
|
||||
{
|
||||
pclose (fp1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pclose (fp1);
|
||||
|
||||
superchop_with_length (prefix_path, strlen (prefix_path));
|
||||
|
||||
int maj = 0;
|
||||
int min = 0;
|
||||
|
||||
// local
|
||||
|
||||
FILE *fp2 = popen ("pyenv local", "r");
|
||||
|
||||
if (fp2 == NULL) return -1;
|
||||
|
||||
if (fscanf (fp2, "%d.%d", &maj, &min) == 2)
|
||||
{
|
||||
pclose (fp2);
|
||||
|
||||
char *pyenv_libpath = expand_pyenv_libpath (prefix_path, maj, min);
|
||||
|
||||
if (pyenv_libpath != NULL)
|
||||
{
|
||||
strncpy (out_buf, pyenv_libpath, out_sz - 1);
|
||||
|
||||
free (pyenv_libpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pclose (fp2);
|
||||
|
||||
// global
|
||||
|
||||
FILE *fp3 = popen ("pyenv global", "r");
|
||||
|
||||
if (fp3 == NULL) return -1;
|
||||
|
||||
if (fscanf (fp3, "%d.%d", &maj, &min) == 2)
|
||||
{
|
||||
pclose (fp3);
|
||||
|
||||
char *pyenv_libpath = expand_pyenv_libpath (prefix_path, maj, min);
|
||||
|
||||
if (pyenv_libpath != NULL)
|
||||
{
|
||||
strncpy (out_buf, pyenv_libpath, out_sz - 1);
|
||||
|
||||
free (pyenv_libpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pclose (fp3);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool init_python (hc_python_lib_t *python)
|
||||
{
|
||||
char *pythondll_path = NULL;
|
||||
char pythondll_path[PATH_MAX];
|
||||
|
||||
python->lib = NULL;
|
||||
|
||||
// let's see if we have pyenv, that will save us a lot of guessing...
|
||||
|
||||
int saved_stderr = suppress_stderr ();
|
||||
|
||||
const int pyenv_rc = resolve_pyenv_libpath (pythondll_path, sizeof (pythondll_path));
|
||||
|
||||
restore_stderr (saved_stderr);
|
||||
|
||||
if (pyenv_rc == 0)
|
||||
{
|
||||
#if defined (_WIN)
|
||||
python->lib = hc_dlopen (pythondll_path);
|
||||
#elif defined (__MSYS__)
|
||||
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
||||
#elif defined (__APPLE__)
|
||||
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
||||
#elif defined (__CYGWIN__)
|
||||
python->lib = hc_dlopen (pythondll_path);
|
||||
#else
|
||||
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MIN_MAJ 3
|
||||
#define MAX_MAJ 8
|
||||
|
||||
#define MIN_MIN 0
|
||||
#define MAX_MIN 50
|
||||
|
||||
#if defined (_WIN)
|
||||
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
if (python->lib != NULL) break;
|
||||
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
#if defined (_WIN)
|
||||
|
||||
// first try %LocalAppData% default path
|
||||
char expandedPath[MAX_PATH];
|
||||
char expandedPath[MAX_PATH - 1];
|
||||
|
||||
char *libpython_namelocal = NULL;
|
||||
|
||||
@ -224,7 +395,7 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = hcstrdup (expandedPath);
|
||||
strncpy (pythondll_path, expandedPath, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_namelocal);
|
||||
|
||||
@ -245,7 +416,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_namepath;
|
||||
strncpy (pythondll_path, libpython_namepath, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_namepath);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -254,18 +427,8 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_namepath);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#elif defined (__MSYS__)
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#elif defined (__MSYS__)
|
||||
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "msys-python%d.%d.dll", maj, min);
|
||||
@ -274,7 +437,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -283,19 +448,8 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#elif defined (__APPLE__)
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#elif defined (__APPLE__)
|
||||
|
||||
// untested
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "libpython%d.%d.dylib", maj, min);
|
||||
@ -304,7 +458,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -313,19 +469,8 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#elif defined (__CYGWIN__)
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#elif defined (__CYGWIN__)
|
||||
|
||||
// untested
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "python%d%d.dll", maj, min);
|
||||
@ -334,7 +479,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -343,18 +490,8 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#else
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "libpython%d.%d.so", maj, min);
|
||||
@ -363,7 +500,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -372,14 +511,14 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (python->lib == NULL)
|
||||
{
|
||||
fprintf (stderr, "Awww, unable to find Python shared library.\n");
|
||||
|
@ -187,29 +187,200 @@ typedef struct
|
||||
|
||||
static char *DEFAULT_SOURCE_FILENAME = "generic_hash_sp";
|
||||
|
||||
#if defined (_WIN)
|
||||
#define DEVNULL "NUL"
|
||||
#else
|
||||
#define DEVNULL "/dev/null"
|
||||
#endif
|
||||
|
||||
static int suppress_stderr (void)
|
||||
{
|
||||
int null_fd = open (DEVNULL, O_WRONLY);
|
||||
|
||||
if (null_fd < 0) return -1;
|
||||
|
||||
int saved_fd = dup (fileno (stderr));
|
||||
|
||||
if (saved_fd < 0)
|
||||
{
|
||||
close (null_fd);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
dup2 (null_fd, fileno (stderr));
|
||||
|
||||
close (null_fd);
|
||||
|
||||
return saved_fd;
|
||||
}
|
||||
|
||||
static void restore_stderr (int saved_fd)
|
||||
{
|
||||
if (saved_fd < 0) return;
|
||||
|
||||
dup2 (saved_fd, fileno (stderr));
|
||||
|
||||
close (saved_fd);
|
||||
}
|
||||
|
||||
static char *expand_pyenv_libpath (const char *prefix, const int maj, const int min)
|
||||
{
|
||||
char *out = NULL;
|
||||
|
||||
#if defined (_WIN)
|
||||
const int len = asprintf (&out, "%s/python%d%dt.dll", prefix, maj, min); //untested
|
||||
#elif defined (__MSYS__)
|
||||
const int len = asprintf (&out, "%s/msys-python%d.%dt.dll", prefix, maj, min); //untested could be wrong
|
||||
#elif defined (__APPLE__)
|
||||
const int len = asprintf (&out, "%s/lib/libpython%d.%dt.dylib", prefix, maj, min); //untested
|
||||
#elif defined (__CYGWIN__)
|
||||
const int len = asprintf (&out, "%s/lib/python%d%dt.dll", prefix, maj, min); //untested
|
||||
#else
|
||||
const int len = asprintf (&out, "%s/lib/libpython%d.%dt.so", prefix, maj, min);
|
||||
#endif
|
||||
|
||||
if (len == -1) return NULL;
|
||||
|
||||
struct stat st;
|
||||
|
||||
if (stat (out, &st) != 0)
|
||||
{
|
||||
free (out);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static int resolve_pyenv_libpath (char *out_buf, const size_t out_sz)
|
||||
{
|
||||
// prefix
|
||||
|
||||
FILE *fp1 = popen ("pyenv prefix", "r");
|
||||
|
||||
if (fp1 == NULL) return -1;
|
||||
|
||||
char prefix_path[PATH_MAX];
|
||||
|
||||
if (fgets (prefix_path, sizeof (prefix_path), fp1) == NULL)
|
||||
{
|
||||
pclose (fp1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pclose (fp1);
|
||||
|
||||
superchop_with_length (prefix_path, strlen (prefix_path));
|
||||
|
||||
int maj = 0;
|
||||
int min = 0;
|
||||
|
||||
// local
|
||||
|
||||
FILE *fp2 = popen ("pyenv local", "r");
|
||||
|
||||
if (fp2 == NULL) return -1;
|
||||
|
||||
if (fscanf (fp2, "%d.%d", &maj, &min) == 2)
|
||||
{
|
||||
pclose (fp2);
|
||||
|
||||
char *pyenv_libpath = expand_pyenv_libpath (prefix_path, maj, min);
|
||||
|
||||
if (pyenv_libpath != NULL)
|
||||
{
|
||||
strncpy (out_buf, pyenv_libpath, out_sz - 1);
|
||||
|
||||
free (pyenv_libpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pclose (fp2);
|
||||
|
||||
// global
|
||||
|
||||
FILE *fp3 = popen ("pyenv global", "r");
|
||||
|
||||
if (fp3 == NULL) return -1;
|
||||
|
||||
if (fscanf (fp3, "%d.%d", &maj, &min) == 2)
|
||||
{
|
||||
pclose (fp3);
|
||||
|
||||
char *pyenv_libpath = expand_pyenv_libpath (prefix_path, maj, min);
|
||||
|
||||
if (pyenv_libpath != NULL)
|
||||
{
|
||||
strncpy (out_buf, pyenv_libpath, out_sz - 1);
|
||||
|
||||
free (pyenv_libpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pclose (fp3);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool init_python (hc_python_lib_t *python)
|
||||
{
|
||||
char *pythondll_path = NULL;
|
||||
char pythondll_path[PATH_MAX];
|
||||
|
||||
python->lib = NULL;
|
||||
|
||||
if (getenv ("PYTHON_GIL") == NULL)
|
||||
putenv ((char *) "PYTHON_GIL=0");
|
||||
|
||||
// let's see if we have pyenv, that will save us a lot of guessing...
|
||||
|
||||
int saved_stderr = suppress_stderr ();
|
||||
|
||||
const int pyenv_rc = resolve_pyenv_libpath (pythondll_path, sizeof (pythondll_path));
|
||||
|
||||
restore_stderr (saved_stderr);
|
||||
|
||||
if (pyenv_rc == 0)
|
||||
{
|
||||
#if defined (_WIN)
|
||||
python->lib = hc_dlopen (pythondll_path);
|
||||
#elif defined (__MSYS__)
|
||||
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
||||
#elif defined (__APPLE__)
|
||||
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
||||
#elif defined (__CYGWIN__)
|
||||
python->lib = hc_dlopen (pythondll_path);
|
||||
#else
|
||||
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MIN_MAJ 3
|
||||
#define MAX_MAJ 8
|
||||
|
||||
#define MIN_MIN 0
|
||||
#define MAX_MIN 50
|
||||
|
||||
#if defined (_WIN)
|
||||
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
if (python->lib != NULL) break;
|
||||
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
#if defined (_WIN)
|
||||
|
||||
// first try %LocalAppData% default path
|
||||
char expandedPath[MAX_PATH];
|
||||
char expandedPath[MAX_PATH - 1];
|
||||
|
||||
char *libpython_namelocal = NULL;
|
||||
|
||||
@ -223,7 +394,7 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = hcstrdup (expandedPath);
|
||||
strncpy (pythondll_path, expandedPath, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_namelocal);
|
||||
|
||||
@ -244,7 +415,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_namepath;
|
||||
strncpy (pythondll_path, libpython_namepath, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_namepath);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -253,27 +426,19 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_namepath);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#elif defined (__MSYS__)
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#elif defined (__MSYS__)
|
||||
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "msys-python%d.%d.dll", maj, min);
|
||||
hc_asprintf (&libpython_name, "msys-python%d.%dt.dll", maj, min);
|
||||
|
||||
python->lib = dlopen (libpython_name, RTLD_NOW | RTLD_GLOBAL);
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -282,19 +447,8 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#elif defined (__APPLE__)
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#elif defined (__APPLE__)
|
||||
|
||||
// untested
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "libpython%d.%dt.dylib", maj, min);
|
||||
@ -303,7 +457,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -312,19 +468,8 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#elif defined (__CYGWIN__)
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#elif defined (__CYGWIN__)
|
||||
|
||||
// untested
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "python%d%dt.dll", maj, min);
|
||||
@ -333,7 +478,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -342,18 +489,8 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
#else
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
||||
{
|
||||
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
||||
{
|
||||
char *libpython_name = NULL;
|
||||
|
||||
hc_asprintf (&libpython_name, "libpython%d.%dt.so", maj, min);
|
||||
@ -362,7 +499,9 @@ static bool init_python (hc_python_lib_t *python)
|
||||
|
||||
if (python->lib != NULL)
|
||||
{
|
||||
pythondll_path = libpython_name;
|
||||
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
||||
|
||||
hcfree (libpython_name);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -371,14 +510,14 @@ static bool init_python (hc_python_lib_t *python)
|
||||
hcfree (libpython_name);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
if (python->lib != NULL) break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (python->lib == NULL)
|
||||
{
|
||||
fprintf (stderr, "Unable to find suitable Python library for -m 72000.\n\n");
|
||||
@ -403,7 +542,7 @@ static bool init_python (hc_python_lib_t *python)
|
||||
fprintf (stderr, " It seems to be a lot slower, and relevant modules such as cffi are incompatibile.\n");
|
||||
fprintf (stderr, " Since your are on Linux/MacOS we highly recommend to stick to multiprocessing module.\n");
|
||||
fprintf (stderr, " Maybe 'free-threaded' mode will become more mature in the future.\n");
|
||||
fprintf (stderr, " For now, we high recommend to stick to -m 73000 instead.\n");
|
||||
fprintf (stderr, " For now, we high recommend to stick to -m 73000 instead.\n\n");
|
||||
#endif
|
||||
|
||||
#define HC_LOAD_FUNC_PYTHON(ptr,name,pythonname,type,libname,noerr) \
|
||||
|
Loading…
Reference in New Issue
Block a user