Skip to content

Get latest libmagic from MSYS2 for Windows #10

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

Merged
merged 34 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
bf01ad7
Fix install_source for Windows
ddelange Mar 15, 2025
1b885cc
Attempt build from source on windows
ddelange Mar 15, 2025
3abe23e
Deprecate https://github.com/julian-r/file-windows
ddelange Mar 15, 2025
36db26a
Try msys2
ddelange Mar 16, 2025
0b49a23
Use msys2dl
ddelange Mar 17, 2025
97feee0
Use ddl from msys2
ddelange Mar 18, 2025
0d64054
Typo
ddelange Mar 18, 2025
bf12a03
Fix location
ddelange Mar 18, 2025
7a2153c
Test
ddelange Mar 18, 2025
6428d81
Test
ddelange Mar 18, 2025
987bf02
Add concurrency
ddelange Mar 18, 2025
4e0102e
Fix
ddelange Mar 18, 2025
035fb72
Add pyproject.toml
ddelange Mar 18, 2025
4ee37ec
Move to separate CIBW_BEFORE_BUILD
ddelange Mar 18, 2025
5e0cd20
Add -U
ddelange Mar 18, 2025
91fb055
Remove magic import from setup.py
ddelange Mar 18, 2025
e9787b3
Add more dlls
ddelange Mar 18, 2025
08ce730
Simplify
ddelange Mar 18, 2025
ef35884
Fix
ddelange Mar 18, 2025
a81e874
Fix win32
ddelange Mar 18, 2025
f905a0e
Fix win32
ddelange Mar 18, 2025
09000e2
Add PATH hack
ddelange Mar 18, 2025
7030050
Check dependencies
ddelange Mar 18, 2025
0f47339
Check dependencies v2
ddelange Mar 18, 2025
95e9365
Copy additional win32 dlls
ddelange Mar 18, 2025
50e2040
Copy additional win32 dlls v2
ddelange Mar 18, 2025
1fc6d99
Fix
ddelange Mar 18, 2025
b4002c5
Delete libgcc_s_dw2-1.dll
ddelange Mar 18, 2025
37e21b8
Delete libwinpthread-1.dll
ddelange Mar 18, 2025
e43ac0d
Revert "Delete libwinpthread-1.dll"
ddelange Mar 18, 2025
5a0f592
Delete libiconv-2.dll
ddelange Mar 18, 2025
4709a72
Revert "Delete libiconv-2.dll"
ddelange Mar 18, 2025
1de1913
Test remnant
ddelange Mar 18, 2025
89e94f7
Add comments
ddelange Mar 18, 2025
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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: ci
on: [push, pull_request]
concurrency: # https://stackoverflow.com/questions/66335225#comment133398800_72408109
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
ci:
strategy:
Expand Down
43 changes: 41 additions & 2 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ on:
types: [released, prereleased]
workflow_dispatch: # allows running workflow manually from the Actions tab

jobs:
concurrency: # https://stackoverflow.com/questions/66335225#comment133398800_72408109
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
build-sdist:
runs-on: ubuntu-latest

Expand Down Expand Up @@ -86,14 +89,50 @@ jobs:
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v3

# For Windows, grabbing latest file from MSYS2 is easier than building from source
# It's generally up to date ref https://packages.msys2.org/base/mingw-w64-file
- name: Setup MSYS2 and install file
if: runner.os == 'Windows'
uses: msys2/[email protected]
with:
msystem: ${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}
location: D:\
install: >-
${{ endsWith(matrix.only, '32') && 'mingw-w64-i686-file' || 'mingw-w64-x86_64-file' }}

# The DLL dependency tree flattened out ref "Dependencies" https://packages.msys2.org/packages/mingw-w64-x86_64-file
- name: Copy Windows ddl and mgc
if: runner.os == 'Windows'
run: |
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/share/misc/magic.mgc" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libmagic-1.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libsystre-0.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libtre-5.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libasprintf-0.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libintl-8.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libatomic-1.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libgomp-1.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libquadmath-0.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libstdc++-6.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libcharset-1.dll" "magic"
cp "/msys64/${{ endsWith(matrix.only, '32') && 'mingw32' || 'mingw64' }}/bin/libiconv-2.dll" "magic"

# These are needed additionally in the win32 wheel ref https://packages.msys2.org/packages/mingw-w64-i686-file
- name: Copy additional 32-bit runtime DLLs
if: runner.os == 'Windows' && endsWith(matrix.only, '32')
run: |
cp "/msys64/mingw32/bin/libgcc_s_dw2-1.dll" "magic"
cp "/msys64/mingw32/bin/libwinpthread-1.dll" "magic"

- uses: pypa/[email protected] # sync version with pip install cibuildwheel above
timeout-minutes: 10
with:
only: ${{ matrix.only }}
env:
CIBW_BUILD_VERBOSITY: 1
# add compiled libmagic to the build directory (to include in the wheel)
CIBW_BEFORE_BUILD: ${{ ( startsWith( matrix.os, 'macos' ) && 'sudo -E bash add_libmagic.sh' ) || 'bash add_libmagic.sh' }}
CIBW_BEFORE_BUILD_MACOS: sudo -E bash add_libmagic.sh
CIBW_BEFORE_BUILD_LINUX: bash add_libmagic.sh
# build macos wheels with maximum backwards compatibility (gcc -mmacosx-version-min flag)
MACOSX_DEPLOYMENT_TARGET: ${{ ( endsWith( matrix.only, 'arm64' ) && '11.0' ) || '10.9' }}
# simple smoke test run on each wheel: this is an HLS MP4 video, only recognised in recent versions of libmagic
Expand Down
21 changes: 3 additions & 18 deletions add_libmagic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
set -euxo pipefail

install_source() {
# skip on Windows for now
python -c 'import platform; assert platform.system() != "Windows"' || exit 1
# install from source
# https://www.darwinsys.com/file/
# https://github.com/file/file/blob/FILE5_46/INSTALL#L51
Expand All @@ -28,7 +26,6 @@ install_precompiled() {
# Debian https://packages.ubuntu.com/libmagic1
# Alpine https://pkgs.alpinelinux.org/package/libmagic
# RHEL https://git.almalinux.org/rpms/file
# Windows https://github.com/julian-r/file-windows
if [ -n "$(which brew)" ]; then
brew install libmagic
elif [ -n "$(which apt-get)" ]; then
Expand All @@ -38,20 +35,6 @@ install_precompiled() {
apk add --update libmagic
elif [ -n "$(which dnf)" ]; then
dnf --setopt install_weak_deps=false -y install file-libs
else
# windows (no install, just download into current working directory)
# could also consider install using `pacman`: https://packages.msys2.org/base/mingw-w64-file
# which would require an update of copy_libmagic below to account for new magic.mgc paths
python <<EOF
import platform, sysconfig, io, zipfile, urllib.request
assert platform.system() == "Windows"
machine = "x86" if sysconfig.get_platform() == "win32" else "x64"
url = f"https://github.com/julian-r/file-windows/releases/download/v5.44/file_5.44-build104-vs2022-{machine}.zip"
print("Downloading", url)
zipfile.ZipFile(io.BytesIO(urllib.request.urlopen(url).read())).extractall(".")
EOF
# check what was copied
ls -ltra
fi
}

Expand All @@ -61,12 +44,14 @@ copy_libmagic() {
# this python command relies on current working directory containing `./magic/loader.py`
libmagic_path="$(python -c 'from magic.loader import load_lib; print(load_lib()._name)')" &&
cp "${libmagic_path}" "magic" &&
# only on linux/macos: additionally copy compiled db into magic dir (prefer the one installed by install_source)
# additionally copy compiled db into magic dir (prefer the one installed by install_source)
( ( cp "/usr/local/share/misc/magic.mgc" "magic" || cp "/usr/share/misc/magic.mgc" "magic" ) || true ) &&
# check what was copied
ls -ltra magic
}

# skip windows (taken care of separately in wheels.yml)
python -c 'import platform; assert platform.system() != "Windows"' || ( echo "skipping on windows" && exit 0 )
# prefer a recent build from source
install_source || install_precompiled
# files to be copied into the wheel
Expand Down
5 changes: 0 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
import os
import sys

# python packages should not install succesfully if libraries are missing
from magic.loader import load_lib

load_lib()._name


def read(file_name):
"""Read a text file and return the content as a string."""
Expand Down