summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlando <du33169@qq.com>2024-05-20 11:54:32 +0800
committerlando <du33169@qq.com>2024-05-20 16:42:19 +0800
commitf327b4c6584278c5206e720da9494006d20c94f4 (patch)
tree6e14f044a76a3244194436cf8db64a40032d18ef
parentb98fcab20459cc2a8da32ed87679ddc249a3414b (diff)
add support for building wheel on windows (mingw)
-rw-r--r--.github/workflows/build.yml43
-rw-r--r--build_jq.mk29
-rw-r--r--setup.py8
-rw-r--r--tests/jq_old_tests.py4
-rw-r--r--tests/jq_tests.py4
5 files changed, 80 insertions, 8 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c544db7..5f15d5f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -95,7 +95,9 @@ jobs:
cibuildwheel --print-build-identifiers --platform linux \
| sed 's/.*/{"cibw-only": "&", "os": "ubuntu-20.04"}/' \
&& cibuildwheel --print-build-identifiers --platform macos \
- | sed 's/.*/{"cibw-only": "&", "os": "macos-13" }/'
+ | sed 's/.*/{"cibw-only": "&", "os": "macos-13" }/' \
+ && cibuildwheel --print-build-identifiers --platform windows \
+ | sed 's/.*/{"cibw-only": "&", "os": "windows-latest" }/'
} | jq --slurp --compact-output '{"include": .}'
)
echo matrix="$MATRIX" >> $GITHUB_OUTPUT
@@ -125,19 +127,52 @@ jobs:
with:
platforms: all
+ - name: Set up MSYS
+ if: runner.os == 'Windows'
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: UCRT64
+ update: true
+ install: mingw-w64-ucrt-x86_64-gcc make
+
+ - name: Setup windows build environment
+ id: setup-build-win
+ if: runner.os == 'Windows'
+ shell: msys2 {0}
+ run: |
+ JQ_VERSION=$(ls deps/jq-*.tar.gz | grep -oP 'jq-\K[\d.]+(?=.tar.gz)')
+ echo jq-lib-version="$JQ_VERSION" >> $GITHUB_OUTPUT
+ echo use-prebuilt-jq=1 >>$GITHUB_OUTPUT
+ printf "[build]\ncompiler=mingw32" > setup.cfg
+
+ - name: Cache pre-built jq lib
+ if: runner.os == 'Windows'
+ id: cache-prebuilt-jq
+ uses: actions/cache@v4
+ with:
+ path: _deps/build
+ key: ${{ runner.os }}-prebuilt-jq-${{steps.setup-build-win.outputs.jq-lib-version}}
+
+ - name: Build jq lib
+ if: runner.os == 'Windows' && steps.cache-prebuilt-jq.outputs.cache-hit != 'true'
+ shell: msys2 {0}
+ run: |
+ make -f build_jq.mk
+
- name: Print build identifiers
run: |
python -m pip install cibuildwheel==2.17.0
python -m cibuildwheel --only ${{ matrix.cibw-only }} --print-build-identifiers
- name: Build wheels
- if: ${{ (github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/')) || matrix.cibw-only == 'cp310-manylinux_x86_64' }}
+ if: ${{ (github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/')) || matrix.cibw-only == 'cp310-manylinux_x86_64' || matrix.cibw-only == 'cp311-win_amd64' }}
uses: pypa/cibuildwheel@v2.17.0
with:
only: ${{ matrix.cibw-only }}
-
+ env:
+ CIBW_ENVIRONMENT: JQPY_USE_PREBUILT_LIBS="${{steps.setup-build-win.outputs.use-prebuilt-jq }}"
- uses: actions/upload-artifact@v3
- if: ${{ (github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/')) || matrix.cibw-only == 'cp310-manylinux_x86_64' }}
+ if: ${{ (github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/')) || matrix.cibw-only == 'cp310-manylinux_x86_64' || matrix.cibw-only == 'cp311-win_amd64' }}
with:
path: ./wheelhouse/*.whl
diff --git a/build_jq.mk b/build_jq.mk
new file mode 100644
index 0000000..66e7711
--- /dev/null
+++ b/build_jq.mk
@@ -0,0 +1,29 @@
+# makefile for building jq
+
+.PHONY: jq_tarball jq_src jq_lib
+
+jq_build_parent:=_deps/build
+jq_version=$(shell echo $(shell ls deps/jq-*.tar.gz) | grep -oP 'jq-\K[\d.]+(?=.tar.gz)')
+jq_tarball_path:=deps/jq-$(jq_version).tar.gz
+jq_build_path:=$(jq_build_parent)/jq-$(jq_version)
+
+all: $(jq_build_path)/.libs/libjq.a $(jq_build_path)/modules/oniguruma/src/.libs/libonig.a
+
+jq_tarball: $(jq_tarball_path)
+ echo "found jq tarball: $(jq_tarball_path)"
+
+jq_src: jq_tarball
+ # extract tarball to jq_build_path
+ mkdir -p $(jq_build_path)
+ tar -xf $(jq_tarball_path) -C $(jq_build_parent)
+
+$(jq_build_path)/.libs/libjq.a $(jq_build_path)/modules/oniguruma/src/.libs/libonig.a: jq_lib
+
+jq_lib: jq_src
+ # build jq
+ cd $(jq_build_path) ; \
+ ./configure CFLAGS="-fPIC -pthread" --disable-maintainer-mode --with-oniguruma=builtin; \
+ make
+
+clean:
+ rm -rf $(jq_build_parent) \ No newline at end of file
diff --git a/setup.py b/setup.py
index 9eaa51f..acc95a8 100644
--- a/setup.py
+++ b/setup.py
@@ -65,16 +65,15 @@ class jq_with_deps_build_ext(build_ext):
shutil.rmtree(lib_dir)
tarfile.open(tarball_path, "r:gz").extractall(_dep_build_path("."))
-
use_system_libs = bool(os.environ.get("JQPY_USE_SYSTEM_LIBS"))
-
+use_prebuilt_libs = bool(os.environ.get("JQPY_USE_PREBUILT_LIBS"))
if use_system_libs:
jq_build_ext = build_ext
link_args_deps = ["-ljq", "-lonig"]
extra_objects = []
else:
- jq_build_ext = jq_with_deps_build_ext
+ jq_build_ext = build_ext if use_prebuilt_libs else jq_with_deps_build_ext
link_args_deps = []
extra_objects = [
os.path.join(jq_lib_dir, ".libs/libjq.a"),
@@ -85,8 +84,9 @@ else:
jq_extension = Extension(
"jq",
sources=["jq.c"],
+ define_macros=[("MS_WIN64", 1)] if os.name == 'nt' else [],
include_dirs=[os.path.join(jq_lib_dir, "src")],
- extra_link_args=["-lm"] + link_args_deps,
+ extra_link_args=["-lm"] + (["-Wl,-Bstatic", "-lpthread", "-lshlwapi", "-static-libgcc"] if os.name == 'nt' else []) + link_args_deps,
extra_objects=extra_objects,
)
diff --git a/tests/jq_old_tests.py b/tests/jq_old_tests.py
index 9393cce..1beafcf 100644
--- a/tests/jq_old_tests.py
+++ b/tests/jq_old_tests.py
@@ -79,6 +79,10 @@ def test_value_error_is_raised_if_program_is_invalid():
"jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
# jq 1.7
"jq: error: syntax error, unexpected INVALID_CHARACTER, expecting end of file (Unix shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
+ # jq 1.6 -win
+ "jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Windows cmd shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
+ # jq 1.7 -win
+ "jq: error: syntax error, unexpected INVALID_CHARACTER, expecting end of file (Windows cmd shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
]
assert str(error) in expected_error_strs
diff --git a/tests/jq_tests.py b/tests/jq_tests.py
index 62b3ae0..81eb79b 100644
--- a/tests/jq_tests.py
+++ b/tests/jq_tests.py
@@ -199,6 +199,10 @@ def test_value_error_is_raised_if_program_is_invalid():
"jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
# jq 1.7
"jq: error: syntax error, unexpected INVALID_CHARACTER, expecting end of file (Unix shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
+ # jq 1.6 -win
+ "jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Windows cmd shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
+ # jq 1.7 -win
+ "jq: error: syntax error, unexpected INVALID_CHARACTER, expecting end of file (Windows cmd shell quoting issues?) at <top-level>, line 1:\n!\njq: 1 compile error",
]
assert str(error) in expected_error_strs