mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
add libwinpthread to static linking
This commit is contained in:
@@ -65,6 +65,12 @@ ifneq (,$(findstring MINGW,$(UNAME_S)))
|
|||||||
CORE_LIBS += -lsamplerate
|
CORE_LIBS += -lsamplerate
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(wildcard /mingw64/lib/libwinpthread.a))
|
||||||
|
SYSTEM_LIBS += /mingw64/lib/libwinpthread.a
|
||||||
|
else
|
||||||
|
SYSTEM_LIBS += -lwinpthread
|
||||||
|
endif
|
||||||
|
|
||||||
# Windows system libraries (these provide the missing symbols)
|
# Windows system libraries (these provide the missing symbols)
|
||||||
SYSTEM_LIBS = -lwinmm -lole32 -luuid -lksuser -lsetupapi -lws2_32 -ladvapi32 -luser32 -lgdi32 -lkernel32
|
SYSTEM_LIBS = -lwinmm -lole32 -luuid -lksuser -lsetupapi -lws2_32 -ladvapi32 -luser32 -lgdi32 -lkernel32
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
EXPORTS
|
|
||||||
list_host_apis
|
|
||||||
init_audio_device
|
|
||||||
close_audio_device
|
|
||||||
is_audio_device_ready
|
|
||||||
set_master_volume
|
|
||||||
get_master_volume
|
|
||||||
load_wave
|
|
||||||
is_wave_valid
|
|
||||||
unload_wave
|
|
||||||
load_sound_from_wave
|
|
||||||
load_sound
|
|
||||||
is_sound_valid
|
|
||||||
unload_sound
|
|
||||||
play_sound
|
|
||||||
pause_sound
|
|
||||||
resume_sound
|
|
||||||
stop_sound
|
|
||||||
is_sound_playing
|
|
||||||
set_sound_volume
|
|
||||||
set_sound_pitch
|
|
||||||
set_sound_pan
|
|
||||||
load_audio_stream
|
|
||||||
unload_audio_stream
|
|
||||||
play_audio_stream
|
|
||||||
pause_audio_stream
|
|
||||||
resume_audio_stream
|
|
||||||
is_audio_stream_playing
|
|
||||||
stop_audio_stream
|
|
||||||
set_audio_stream_volume
|
|
||||||
set_audio_stream_pitch
|
|
||||||
set_audio_stream_pan
|
|
||||||
update_audio_stream
|
|
||||||
load_music_stream
|
|
||||||
is_music_valid
|
|
||||||
unload_music_stream
|
|
||||||
play_music_stream
|
|
||||||
pause_music_stream
|
|
||||||
resume_music_stream
|
|
||||||
stop_music_stream
|
|
||||||
seek_music_stream
|
|
||||||
update_music_stream
|
|
||||||
is_music_stream_playing
|
|
||||||
set_music_volume
|
|
||||||
set_music_pitch
|
|
||||||
set_music_pan
|
|
||||||
get_music_time_length
|
|
||||||
get_music_time_played
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Cross-compiling audio library for Windows..."
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
MINGW_PREFIX="x86_64-w64-mingw32"
|
|
||||||
CC="${MINGW_PREFIX}-gcc"
|
|
||||||
WIN_DEPS="win-libs"
|
|
||||||
|
|
||||||
# Check if cross-compiler is available
|
|
||||||
if ! command -v $CC &> /dev/null; then
|
|
||||||
echo "Error: MinGW-w64 cross-compiler not found!"
|
|
||||||
echo "Install it with: sudo apt-get install mingw-w64"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if Windows dependencies exist
|
|
||||||
if [ ! -d "$WIN_DEPS" ]; then
|
|
||||||
echo "Warning: Windows dependencies not found in $WIN_DEPS"
|
|
||||||
echo "You may need to build or download Windows versions of:"
|
|
||||||
echo " - PortAudio"
|
|
||||||
echo " - libsndfile"
|
|
||||||
echo " - libsamplerate"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build command
|
|
||||||
CFLAGS="-O2 -Wall -Wextra"
|
|
||||||
LDFLAGS="-shared -Wl,--out-implib,libaudio.lib -static-libgcc -static-libstdc++"
|
|
||||||
LIBS="-lportaudio -lsndfile -lsamplerate -lwinmm -lole32 -luuid -lksuser -lsetupapi"
|
|
||||||
|
|
||||||
if [ -d "$WIN_DEPS" ]; then
|
|
||||||
CFLAGS="$CFLAGS -I${WIN_DEPS}/include"
|
|
||||||
LDFLAGS="$LDFLAGS -L${WIN_DEPS}/lib"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Compiling with: $CC"
|
|
||||||
$CC $CFLAGS $LDFLAGS audio.c -o libaudio.dll $LIBS
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "Successfully built libaudio.dll"
|
|
||||||
echo "Import library: libaudio.lib"
|
|
||||||
|
|
||||||
# Check if we can get file info
|
|
||||||
if command -v file &> /dev/null; then
|
|
||||||
file libaudio.dll
|
|
||||||
fi
|
|
||||||
|
|
||||||
# List exported functions
|
|
||||||
if command -v ${MINGW_PREFIX}-objdump &> /dev/null; then
|
|
||||||
echo "Exported functions:"
|
|
||||||
${MINGW_PREFIX}-objdump -p libaudio.dll | grep "\\[.*\\]" | head -20
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Build failed!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
import ctypes
|
|
||||||
import ctypes.wintypes
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
import struct
|
|
||||||
|
|
||||||
# Windows API constants
|
|
||||||
LOAD_LIBRARY_AS_DATAFILE = 0x00000002
|
|
||||||
DONT_RESOLVE_DLL_REFERENCES = 0x00000001
|
|
||||||
|
|
||||||
def check_dll_architecture(dll_path):
|
|
||||||
"""Check if DLL is 32-bit or 64-bit"""
|
|
||||||
try:
|
|
||||||
with open(dll_path, 'rb') as f:
|
|
||||||
# Read DOS header
|
|
||||||
dos_header = f.read(64)
|
|
||||||
if dos_header[:2] != b'MZ':
|
|
||||||
return "Not a valid PE file"
|
|
||||||
|
|
||||||
# Get PE header offset
|
|
||||||
pe_offset = struct.unpack('<L', dos_header[60:64])[0]
|
|
||||||
f.seek(pe_offset)
|
|
||||||
|
|
||||||
# Read PE signature and COFF header
|
|
||||||
pe_sig = f.read(4)
|
|
||||||
if pe_sig != b'PE\x00\x00':
|
|
||||||
return "Not a valid PE file"
|
|
||||||
|
|
||||||
machine = struct.unpack('<H', f.read(2))[0]
|
|
||||||
|
|
||||||
if machine == 0x014c:
|
|
||||||
return "32-bit (i386)"
|
|
||||||
elif machine == 0x8664:
|
|
||||||
return "64-bit (AMD64)"
|
|
||||||
else:
|
|
||||||
return f"Unknown architecture (0x{machine:04x})"
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return f"Error reading file: {e}"
|
|
||||||
|
|
||||||
def check_dll_dependencies_windows(dll_path):
|
|
||||||
"""Check DLL dependencies using Windows API"""
|
|
||||||
|
|
||||||
print(f"Analyzing: {dll_path}")
|
|
||||||
|
|
||||||
if not os.path.exists(dll_path):
|
|
||||||
print(f"ERROR: {dll_path} not found!")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Check basic file info
|
|
||||||
size = os.path.getsize(dll_path)
|
|
||||||
arch = check_dll_architecture(dll_path)
|
|
||||||
print(f"DLL Size: {size} bytes")
|
|
||||||
print(f"Architecture: {arch}")
|
|
||||||
|
|
||||||
# Try to load the DLL to check for missing dependencies
|
|
||||||
kernel32 = ctypes.windll.kernel32
|
|
||||||
|
|
||||||
print("\n=== Dependency Check ===")
|
|
||||||
|
|
||||||
# Try loading with DONT_RESOLVE_DLL_REFERENCES to avoid initializing
|
|
||||||
try:
|
|
||||||
handle = kernel32.LoadLibraryExW(
|
|
||||||
ctypes.c_wchar_p(dll_path),
|
|
||||||
None,
|
|
||||||
LOAD_LIBRARY_AS_DATAFILE | DONT_RESOLVE_DLL_REFERENCES
|
|
||||||
)
|
|
||||||
|
|
||||||
if handle:
|
|
||||||
print("✓ DLL can be loaded as data file")
|
|
||||||
kernel32.FreeLibrary(handle)
|
|
||||||
else:
|
|
||||||
error = kernel32.GetLastError()
|
|
||||||
print(f"✗ Failed to load as data file. Error: 0x{error:x}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"✗ Exception during data file load: {e}")
|
|
||||||
|
|
||||||
# Try normal loading
|
|
||||||
try:
|
|
||||||
handle = kernel32.LoadLibraryW(ctypes.c_wchar_p(dll_path))
|
|
||||||
if handle:
|
|
||||||
print("✓ DLL loads successfully with full resolution")
|
|
||||||
kernel32.FreeLibrary(handle)
|
|
||||||
else:
|
|
||||||
error = kernel32.GetLastError()
|
|
||||||
print(f"✗ Failed to load DLL normally. Error: 0x{error:x}")
|
|
||||||
print_windows_error(error)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"✗ Exception during normal load: {e}")
|
|
||||||
|
|
||||||
def print_windows_error(error_code):
|
|
||||||
"""Print human-readable Windows error message"""
|
|
||||||
error_messages = {
|
|
||||||
0x7e: "The specified module could not be found",
|
|
||||||
0x57: "The parameter is incorrect",
|
|
||||||
0x7f: "The specified procedure could not be found",
|
|
||||||
0xc1: "The application cannot run in Win32 mode",
|
|
||||||
0x485: "Attempt to access invalid address",
|
|
||||||
}
|
|
||||||
|
|
||||||
if error_code in error_messages:
|
|
||||||
print(f" Meaning: {error_messages[error_code]}")
|
|
||||||
|
|
||||||
# Try to get system error message
|
|
||||||
try:
|
|
||||||
import ctypes.wintypes
|
|
||||||
kernel32 = ctypes.windll.kernel32
|
|
||||||
|
|
||||||
buffer = ctypes.create_unicode_buffer(512)
|
|
||||||
kernel32.FormatMessageW(
|
|
||||||
0x00001000, # FORMAT_MESSAGE_FROM_SYSTEM
|
|
||||||
None,
|
|
||||||
error_code,
|
|
||||||
0,
|
|
||||||
buffer,
|
|
||||||
512,
|
|
||||||
None
|
|
||||||
)
|
|
||||||
|
|
||||||
if buffer.value:
|
|
||||||
print(f" System message: {buffer.value.strip()}")
|
|
||||||
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def check_python_architecture():
|
|
||||||
"""Check if Python is 32-bit or 64-bit"""
|
|
||||||
import platform
|
|
||||||
return platform.architecture()[0]
|
|
||||||
|
|
||||||
def test_cffi_loading(dll_path):
|
|
||||||
"""Test CFFI loading specifically"""
|
|
||||||
print("\n=== CFFI Loading Test ===")
|
|
||||||
|
|
||||||
try:
|
|
||||||
import cffi
|
|
||||||
ffi = cffi.FFI()
|
|
||||||
|
|
||||||
# Try to load without any function definitions
|
|
||||||
print("Testing CFFI dlopen...")
|
|
||||||
lib = ffi.dlopen(dll_path)
|
|
||||||
print("✓ CFFI can load the DLL")
|
|
||||||
|
|
||||||
# Test with a simple function definition
|
|
||||||
ffi.cdef("void list_host_apis(void);")
|
|
||||||
lib = ffi.dlopen(dll_path)
|
|
||||||
print("✓ CFFI can load with function definition")
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"✗ CFFI loading failed: {e}")
|
|
||||||
print(f" Error type: {type(e).__name__}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
dll_path = "libaudio.dll"
|
|
||||||
if len(sys.argv) > 1:
|
|
||||||
dll_path = sys.argv[1]
|
|
||||||
|
|
||||||
print(f"Python Architecture: {check_python_architecture()}")
|
|
||||||
print()
|
|
||||||
|
|
||||||
check_dll_dependencies_windows(dll_path)
|
|
||||||
test_cffi_loading(dll_path)
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
import cffi
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
def test_dll_loading():
|
|
||||||
"""Test DLL loading with detailed error reporting"""
|
|
||||||
|
|
||||||
ffi = cffi.FFI()
|
|
||||||
|
|
||||||
# Define minimal interface first
|
|
||||||
ffi.cdef("""
|
|
||||||
void list_host_apis(void);
|
|
||||||
bool is_audio_device_ready(void);
|
|
||||||
""")
|
|
||||||
|
|
||||||
dll_path = "./libaudio.dll"
|
|
||||||
|
|
||||||
print(f"Testing DLL: {dll_path}")
|
|
||||||
print(f"DLL exists: {os.path.exists(dll_path)}")
|
|
||||||
|
|
||||||
if os.path.exists(dll_path):
|
|
||||||
print(f"DLL size: {os.path.getsize(dll_path)} bytes")
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Try to load the DLL
|
|
||||||
print("Attempting to load DLL...")
|
|
||||||
lib = ffi.dlopen(dll_path)
|
|
||||||
print("✓ DLL loaded successfully!")
|
|
||||||
|
|
||||||
# Try to call a simple function
|
|
||||||
print("Testing function call...")
|
|
||||||
ready = lib.is_audio_device_ready()
|
|
||||||
print(f"✓ Function call successful: {ready}")
|
|
||||||
|
|
||||||
# Try calling list_host_apis (this initializes PortAudio)
|
|
||||||
print("Testing list_host_apis...")
|
|
||||||
lib.list_host_apis()
|
|
||||||
print("✓ list_host_apis completed")
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"✗ Error: {e}")
|
|
||||||
print(f"Error type: {type(e).__name__}")
|
|
||||||
|
|
||||||
# Additional debugging
|
|
||||||
if "GetLastError" in str(e):
|
|
||||||
import ctypes
|
|
||||||
error_code = ctypes.windll.kernel32.GetLastError()
|
|
||||||
print(f"Windows error code: 0x{error_code:x} ({error_code})")
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
success = test_dll_loading()
|
|
||||||
if not success:
|
|
||||||
print("\nDebugging steps:")
|
|
||||||
print("1. Check DLL dependencies with: python check_deps.py")
|
|
||||||
print("2. Ensure all required DLLs are in PATH or same directory")
|
|
||||||
print("3. Verify DLL architecture matches Python (64-bit)")
|
|
||||||
print("4. Try the minimal test_dll.dll first")
|
|
||||||
Reference in New Issue
Block a user