Last active
April 17, 2022 16:25
-
-
Save sveinse/97411b95d36a6b8c430d4d381b620ecb to your computer and use it in GitHub Desktop.
Scheme for setting up pysndfile and libraries on Windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -x | |
# The purpose of this script is to build a pysndfile wheel. | |
# The main purpose of generating a wheel, is to be able to distribute | |
# the wheel similar to the binary files, not needing to recompiling the | |
# module on every install. | |
disr="dist" | |
binaries="libsndfile_binaries_win32" | |
venv="venv-pysndfile" | |
python="winpty py -3" | |
# Pre cleanup | |
rm -rf "$venv" | |
# Create venv | |
$python -m venv "$venv" | |
pip="winpty "$(readlink -f "$venv/Scripts/pip")"" | |
$pip install wheel numpy cython | |
# Unpack the binaries | |
mkdir -p "$venv/$dist" | |
tar -C "$venv/$dist" -xf "$binaries.tar.xz" | |
dir="$(readlink -f $venv/$dist)" | |
# Alternative 1) Download the official version from pypi | |
#$pip download --no-deps --no-binary=:all: pysndfile | |
#tar -xf pysndfile-*.tar.gz | |
#d=pysndfile-1* | |
# Alternative 2) Fetch the sources | |
git clone https://github.com/roebel/pysndfile.git pysndfile | |
d=pysndfile | |
# Generate the wheel | |
cd $d | |
$pip wheel . --verbose --no-deps \ | |
--global-option=build_ext \ | |
--global-option="-L$dir/lib" \ | |
--global-option="-L$dir/include" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -x | |
# Setup a new venv and install the pysndfile wheel into it. It will | |
# also inject the libsndfile.dll into the venv, making it possible to | |
# use pysndfile | |
dist="dist" | |
binaries="libsndfile_binaries_win32" | |
venv="venv" | |
winpty="winpty" | |
python="py -3" | |
# Pre cleanup | |
rm -rf "$venv" "$dist" | |
# Create venv | |
$winpty $python -m venv "$venv" | |
# Setup new executables | |
python="$(readlink -f "$venv/Scripts/python")" | |
pip="$winpty "$(readlink -f "$venv/Scripts/pip")"" | |
# Location of the python libraries | |
sp="$($python -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())')" | |
mkdir -p "$sp" | |
# Unpack the binary libraries | |
mkdir -p "$dist" | |
tar -C "$dist" -xf "${binaries}.tar.xz" | |
# Install pysndfile and inject dll into it | |
$pip install wheel pysndfile-*.whl | |
cp "$dist/lib/"*.dll "$sp/pysndfile/" | |
# Install the rest of the application here | |
# $pip install myapp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -x | |
# The purpose of this script is to generate a tarball containing the | |
# binary non-python libraries needed to run pysndfile. | |
# | |
# The official libsndfile isn't compiled with flac and ogg support, so another | |
# 3rd party distribution is used for this. Secondly the binary distributions | |
# of libsndfile doesn't come with a .lib file which is required for linking on | |
# Windows. The crude tool used in this script requires Visual Studio 2017 | |
# to generate the required .lib file. | |
dist="dist" | |
binaries="libsndfile_binaries_win32" | |
venv="venv-pysndfile" | |
python="winpty py -3" | |
dll2lib="$(readlink -f win_dll2lib.py)" | |
# Pre cleanup | |
rm -rf "$dist" "$binaries" | |
# Create storage dirs | |
mkdir -p "$dist/lib" "$dist/include" | |
# Download the official windows release. | |
# Copy the headers from it | |
d=libsndfile-1.0.28-w32 | |
url="http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.28-w32.zip" | |
curl -# "$url" -o "$d.zip" | |
unzip "$d.zip" -d "$d" | |
cp -av $d/include/*.h $d/include/*.hh $dist/include/ | |
# Get the non-official windows build that includes support for flac and friends | |
# The library seems statically linked, so only the libsndfile32bit.dll is needed | |
d=libsndfile-binaries | |
git clone https://github.com/bastibe/libsndfile-binaries.git $d | |
( cd $d | |
git checkout 84cb164928f17c7ca0c1e5c40342c20ce2b90e8c) || exit 1 | |
cp -av $d/libsndfile32bit.dll $dist/lib/ | |
# Generate the libsndfile.lib from the dll: | |
# Please note that to be able to execute this, Visual Studio 2017 must be installed | |
( cd $dist/lib | |
$python "$dll2lib" libsndfile32bit.dll sndfile.lib | |
) | |
# Compile the binary | |
tar -C "$dist" -cvJf "${binaries}.tar.xz" . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" A crude tool to generate a .lib from a .dll file """ | |
import os | |
import sys | |
import subprocess | |
import tempfile | |
import re | |
# Bat script to convert DLL to a DEF file input | |
dumpbin = r''' | |
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars32.bat" | |
@ECHO on | |
DUMPBIN /exports "%1" >"%2" | |
''' | |
# Bat script to convert parsed DEF to LIB | |
libbat = r''' | |
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars32.bat" | |
@ECHO on | |
LIB /DEF:"%1" /OUT:"%2" /MACHINE:X86 | |
''' | |
# Rudimentary argument checking | |
print(sys.argv) | |
if len(sys.argv) < 3: | |
raise Exception("Too few arguments") | |
# Get the file | |
infile = sys.argv[1] | |
deffile = infile.replace('.dll', '.def') | |
outfile = sys.argv[2] | |
expfile = outfile.replace('.lib', '.exp') | |
# Ensure the input exists | |
if not os.path.exists(infile): | |
raise FileNotFoundError(infile) | |
# Create a temp working directory | |
with tempfile.TemporaryDirectory() as tmpdirname: | |
# Write the temp bat script for dumping the DLL file and run it | |
bat = os.path.join(tmpdirname, 'run.bat') | |
with open(bat, 'w') as f: | |
f.write(dumpbin) | |
subprocess.check_call([bat, infile, deffile]) | |
# Parse the output from dumpbin and make it into a file with | |
# EXPORTS | |
# method names... | |
out = 'EXPORTS\n' | |
with open(deffile, 'r') as f: | |
mode = 'header' | |
n = 0 | |
i = 1 | |
for line in f: | |
n += 1 | |
l = line.strip() | |
s = re.split(r'\s+', l) | |
if len(s) != 4: | |
continue | |
try: | |
ordinal = int(s[0]) | |
except ValueError: | |
continue | |
if ordinal != i: | |
continue | |
i += 1 | |
out += s[3] + '\n' | |
# Write the def file | |
print(deffile) | |
with open(deffile, 'w') as f: | |
f.write(out) | |
# Write the temp bat script for generating the LIB file and run it | |
bat = os.path.join(tmpdirname, 'run.bat') | |
with open(bat, 'w') as f: | |
f.write(libbat) | |
subprocess.check_call([bat, deffile, outfile]) | |
# Remove the temporary def file | |
os.remove(deffile) | |
os.remove(expfile) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment