Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add changes to support building arm64 macos wheels #1383

Merged
merged 45 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
46884d5
Add changes to support building arm64 macos wheels
Oct 24, 2023
8fe741c
Replace before-all by before-build
Oct 24, 2023
b2afb51
Force installing arm64 version for cross-build
Oct 24, 2023
e50b465
Fix toml format
Oct 24, 2023
52250b7
Fix toml format
Oct 24, 2023
12e5895
Fix toml format
Oct 24, 2023
095b7ab
Fix homebrew installation step
palonso Oct 27, 2023
cb30bfe
Fix pyproject-tensorflow
palonso Nov 4, 2023
deb7a6a
Build only arm64 wheels for testing (WIP)
palonso Nov 4, 2023
3dcd419
Reverse dependancy installation order
palonso Nov 4, 2023
7b68a74
Use big_sur version instead of monterey
palonso Nov 4, 2023
57d19a2
Try ventura tag
palonso Nov 4, 2023
2d2a2dc
Do not build Python 3.8 wheel
palonso Nov 5, 2023
31e9de9
Fix workflow file
palonso Nov 5, 2023
5cfff93
Add arch arm64 to CFLAGS
palonso Nov 5, 2023
b99d316
Add arm64 flags to setup.py
palonso Nov 5, 2023
27c2f48
Install arm64 version of the missing libs
palonso Nov 6, 2023
fee770e
Copy SDL2 libs into the Python wheel for Mac arm64
palonso Jan 31, 2024
7fbfc8c
Use native's M1 MacOS runner
palonso Jan 31, 2024
69c4cda
Install pipx before building wheels
palonso Jan 31, 2024
24b670b
link --force ffmpeg before installing chromaprint
palonso Jan 31, 2024
9fc80f2
link --force ffmpeg again after installing chromaprint
palonso Jan 31, 2024
08400b6
Replace --force by --overwrite to force the link and overwrite all co…
palonso Jan 31, 2024
d9c2ed8
Create target contxt folder
palonso Jan 31, 2024
574aefe
install essentia as root
palonso Jan 31, 2024
85f7b10
Control arm64-dependent flags with env var
palonso Jan 31, 2024
7b6b4f5
Fix handling of env vars and resore linux and macos intel workflows
palonso Jan 31, 2024
ae4b0e6
Fix uninitialized variable
palonso Jan 31, 2024
f31324f
Install pipx only in macos-14
palonso Jan 31, 2024
491b2f5
Fix if statement
palonso Jan 31, 2024
c2cf05a
Fix GH Actions syntax
palonso Jan 31, 2024
927f397
Repeat same brew steps in macos-12 as in macos-14
palonso Jan 31, 2024
6b11900
Update Node.js 16 -> 20
palonso Feb 1, 2024
228661e
Build wheels for Python 3.8
palonso Feb 1, 2024
b31399b
Revert #6b11900
palonso Feb 1, 2024
7e7bd58
Update checkout action to use node 20
palonso Feb 1, 2024
0505073
Update cibuildwheel
palonso Feb 1, 2024
4f6fb57
Skip Python 3.12 wheels for linux for now
palonso Feb 1, 2024
8fcf8af
Try to fix skip pattern
palonso Feb 1, 2024
392a6ee
Bump artifact action to v4
palonso Feb 1, 2024
4105c42
Add comment on skipping Python 3.12
palonso Feb 1, 2024
2a156ef
Write artifacts to different files
palonso Feb 1, 2024
34a08b8
Fix Actions syntax
palonso Feb 1, 2024
7d729a5
Fix comment
palonso Feb 1, 2024
480076c
Fix essentia-tensorflow project name
palonso Feb 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions .github/workflows/build-wheels-cibuildwheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,24 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, macos-11]
config: [pyproject-tensorflow.toml, pyproject.toml]
os: [ubuntu-20.04, macos-12, macos-14]
config: [pyproject, pyproject-tensorflow]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Fetch release tags from GitHub
# Workaround for https://github.com/actions/checkout/issues/290
run: git fetch --tags --force

- name: Build wheels
uses: pypa/cibuildwheel@v2.11.4
uses: pypa/cibuildwheel@v2.16.5
with:
config-file: ${{ matrix.config }}
config-file: ${{ matrix.config }}.toml

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
path: ./wheelhouse/*.whl
name: artifact-${{ matrix.os }}-${{ matrix.config }}
47 changes: 42 additions & 5 deletions pyproject-tensorflow.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ manylinux-x86_64-image = "mtgupf/essentia-builds:manylinux2014_x86_64"

# Only support x86_64 for essentia-tensorflow
build = "cp**-manylinux_x86_64"
skip = ["pp*", "*-musllinux*", "*i686"]
# TODO: skipping Python 3.12 for now until we create manylinux images supporting this version.
skip = ["pp*", "*-musllinux*", "*i686", "*cp312*"]

environment = { PROJECT_NAME="essentia-tensorflow", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1 }

before-all = [
before-build = [
"PYBIN=/opt/python/cp36-cp36m/bin/",
"\"${PYBIN}/python\" waf configure --with-gaia --with-tensorflow --build-static --static-dependencies --pkg-config-path=\"${PKG_CONFIG_PATH}\"",
"\"${PYBIN}/python\" waf",
Expand All @@ -24,11 +25,13 @@ skip = ["pp*"]

environment = { PROJECT_NAME="essentia-tensorflow", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1 }

before-all = [
before-build = [
"brew install pkg-config gcc readline sqlite gdbm freetype libpng",
"brew install eigen libyaml fftw [email protected] libsamplerate libtag chromaprint",
"brew install tensorflow",
"brew install eigen libyaml fftw [email protected] libsamplerate libtag",
"brew link --force [email protected]",
"brew install chromaprint",
"brew link --overwrite [email protected]",
"brew install tensorflow",
#"brew tap MTG/essentia",
#"brew install gaia --HEAD",
"python waf configure --with-tensorflow --pkg-config-path=\"${PKG_CONFIG_PATH}\"",
Expand All @@ -39,6 +42,40 @@ before-all = [
test-command = "python -c 'import essentia; import essentia.standard; import essentia.streaming; from essentia.standard import MonoLoader, MetadataReader, YamlInput, Chromaprinter, TensorflowPredict'"


[[tool.cibuildwheel.overrides]]
select = "*macosx_arm64*"

skip = ["pp*"]

environment = { PROJECT_NAME="essentia", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1, ESSENTIA_MACOSX_ARM64=1 }
palonso marked this conversation as resolved.
Show resolved Hide resolved

before-build = [
"brew install pkg-config gcc readline sqlite gdbm libpng",
"brew install eigen libyaml fftw [email protected] libsamplerate libtag",
"brew link --force [email protected]",
"brew install chromaprint",
"brew link --overwrite [email protected]",
"brew install tensorflow",
"python waf configure --with-tensorflow --pkg-config-path=\"${PKG_CONFIG_PATH}\" --arch arm64 --no-msse",
"python waf",
"sudo python waf install",
]

# On Mac arm64, libavcodec.56.60.100, libavformat.56.40.101 and
# libavutil.54.31.100, depend on libSDL1.2-compat, which is a compatibility
# layer for SDL2. libSDL1.2-compat expects SDL2 to be installed in the default
# brew location (i.e., /opt/homebrew/opt/sdl2/lib), so the user would need to
# install it via brew manually. Alternativelly, we can manualy copy the SDL2
# libs into the wheel. This is a temporary solution, and in the long term we
# should move to FFmpeg > 2.X.
repair-wheel-command = [
"delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
"mkdir -p {dest_dir}/essentia/.dylibs",
"cp /opt/homebrew/opt/sdl2/lib/libSDL2*.dylib {dest_dir}/essentia/.dylibs",
"wheel_rel=$(echo {wheel} | grep -o '[^/]*$')",
"cd {dest_dir} && zip -u {dest_dir}/$wheel_rel essentia/.dylibs/*"
]

[build-system]

requires = ["wheel", "setuptools", "oldest-supported-numpy"]
43 changes: 39 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
manylinux-x86_64-image = "mtgupf/essentia-builds:manylinux2014_x86_64"
manylinux-i686-image = "mtgupf/essentia-builds:manylinux2014_i686"

skip = ["pp*", "*-musllinux*", "*i686"]
# TODO: skipping Python 3.12 for now until we create manylinux images supporting this version.
skip = ["pp*", "*-musllinux*", "*i686", "*cp312*"]

environment = { PROJECT_NAME="essentia", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1 }

before-all = [
before-build = [
"PYBIN=/opt/python/cp36-cp36m/bin/",
"\"${PYBIN}/python\" waf configure --with-gaia --build-static --static-dependencies --pkg-config-path=\"${PKG_CONFIG_PATH}\"",
"\"${PYBIN}/python\" waf",
Expand All @@ -24,10 +25,12 @@ skip = ["pp*"]

environment = { PROJECT_NAME="essentia", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1 }

before-all = [
before-build = [
"brew install pkg-config gcc readline sqlite gdbm freetype libpng",
"brew install eigen libyaml fftw [email protected] libsamplerate libtag chromaprint",
"brew install eigen libyaml fftw [email protected] libsamplerate libtag",
"brew link --force [email protected]",
"brew install chromaprint",
"brew link --overwrite [email protected]",
#"brew tap MTG/essentia",
#"brew install gaia --HEAD",
"python waf configure --pkg-config-path=\"${PKG_CONFIG_PATH}\"",
Expand All @@ -37,6 +40,38 @@ before-all = [

test-command = "python -c 'import essentia; import essentia.standard; import essentia.streaming; from essentia.standard import MonoLoader, MetadataReader, YamlInput, Chromaprinter'"

[[tool.cibuildwheel.overrides]]
select = "*macosx_arm64*"

skip = ["pp*"]

environment = { PROJECT_NAME="essentia", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1, ESSENTIA_MACOSX_ARM64=1 }

before-build = [
"brew install pkg-config gcc readline sqlite gdbm libpng",
"brew install eigen libyaml fftw [email protected] libsamplerate libtag",
"brew link --force [email protected]",
"brew install chromaprint",
"brew link --overwrite [email protected]",
"python waf configure --pkg-config-path=\"${PKG_CONFIG_PATH}\" --arch arm64 --no-msse",
"python waf",
"sudo python waf install",
]

# On Mac arm64, libavcodec.56.60.100, libavformat.56.40.101 and
# libavutil.54.31.100, depend on libSDL1.2-compat, which is a compatibility
# layer for SDL2. libSDL1.2-compat expects SDL2 to be installed in the default
# brew location (i.e., /opt/homebrew/opt/sdl2/lib), so the user would need to
# install it via brew manually. Alternativelly, we can manualy copy the SDL2
# libs into the wheel. This is a temporary solution, and in the long term we
# should move to FFmpeg > 2.X.
repair-wheel-command = [
"delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
"mkdir -p {dest_dir}/essentia/.dylibs",
"cp /opt/homebrew/opt/sdl2/lib/libSDL2*.dylib {dest_dir}/essentia/.dylibs",
"wheel_rel=$(echo {wheel} | grep -o '[^/]*$')",
"cd {dest_dir} && zip -u {dest_dir}/$wheel_rel essentia/.dylibs/*"
]

[build-system]

Expand Down
20 changes: 13 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import shutil
import os
import glob
import subprocess
import sys
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext
Expand Down Expand Up @@ -36,20 +37,25 @@ def run(self):
var_skip_3rdparty = 'ESSENTIA_WHEEL_SKIP_3RDPARTY'
var_only_python = 'ESSENTIA_WHEEL_ONLY_PYTHON'

var_macos_arm64 = os.getenv('ESSENTIA_MACOSX_ARM64')
macos_arm64_flags = []
if var_macos_arm64 == '1':
macos_arm64_flags = ['--arch=arm64', '--no-msse']

if var_skip_3rdparty in os.environ and os.environ[var_skip_3rdparty]=='1':
print('Skipping building static 3rdparty dependencies (%s=1)' % var_skip_3rdparty)
else:
os.system('./packaging/build_3rdparty_static_debian.sh')
subprocess.run('./packaging/build_3rdparty_static_debian.sh', check=True)

if var_only_python in os.environ and os.environ[var_only_python]=='1':
print('Skipping building the core libessentia library (%s=1)' % var_only_python)
os.system('%s waf configure --only-python --static-dependencies '
'--prefix=tmp' % PYTHON)
subprocess.run([PYTHON, 'waf', 'configure', '--only-python', '--static-dependencies',
'--prefix=tmp'] + macos_arm64_flags, check=True)
else:
os.system('%s waf configure --build-static --static-dependencies '
'--with-python --prefix=tmp' % PYTHON)
os.system('%s waf' % PYTHON)
os.system('%s waf install' % PYTHON)
subprocess.run([PYTHON, 'waf', 'configure', '--build-static', '--static-dependencies'
'--with-python --prefix=tmp'] + macos_arm64_flags, check=True)
subprocess.run([PYTHON, 'waf'], check=True)
subprocess.run([PYTHON, 'waf', 'install'], check=True)

library = glob.glob('tmp/lib/python*/*-packages/essentia')[0]

Expand Down
6 changes: 6 additions & 0 deletions wscript
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ def configure(ctx):
ctx.env.LINKFLAGS += ['-arch', 'i386', '-arch', 'x86_64']
ctx.env.LDFLAGS = ['-arch', 'i386', '-arch', 'x86_64']

if ctx.options.ARCH == 'arm64':
ctx.env.CFLAGS += ['-arch', 'arm64']
ctx.env.CXXFLAGS += ['-arch', 'arm64']
ctx.env.LINKFLAGS += ['-arch', 'arm64']
ctx.env.LDFLAGS += ['-arch', 'arm64']

elif sys.platform.startswith('linux'):
# include -pthread flag because not all versions of gcc provide it automatically
ctx.env.CXXFLAGS += ['-pthread']
Expand Down
Loading