libpng 1.6.58.5 → 1.6.58.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +92 -27
- data/.github/workflows/release.yml +74 -21
- data/CHANGELOG.md +50 -0
- data/CLAUDE.md +29 -2
- data/README.adoc +1 -1
- data/TODO.ohos/01-architecture.md +105 -0
- data/TODO.ohos/02-close-pr-12-and-branch.md +30 -0
- data/TODO.ohos/03-setup-ndk-sh.md +54 -0
- data/TODO.ohos/04-ohos-module-and-ndk.md +65 -0
- data/TODO.ohos/05-zlib-builder.md +65 -0
- data/TODO.ohos/06-recipe-factory-and-ohos-recipe.md +126 -0
- data/TODO.ohos/07-code-signer.md +53 -0
- data/TODO.ohos/08-smoke-test-and-verify-prepare.md +79 -0
- data/TODO.ohos/09-ci-workflow.md +101 -0
- data/TODO.ohos/10-specs.md +170 -0
- data/TODO.ohos/11-docs.md +91 -0
- data/TODO.ohos/12-pr.md +152 -0
- data/ext/extconf.rb +1 -1
- data/ext/ohos/setup-ndk.sh +140 -0
- data/ext/ohos/smoke-test.c +73 -0
- data/ext/ohos/verify-prepare.sh +56 -0
- data/lib/libpng/ohos/code_signer.rb +38 -0
- data/lib/libpng/ohos/ndk.rb +83 -0
- data/lib/libpng/ohos/recipe.rb +76 -0
- data/lib/libpng/ohos/zlib_builder.rb +57 -0
- data/lib/libpng/ohos.rb +28 -0
- data/lib/libpng/recipe.rb +19 -0
- data/lib/libpng/version.rb +1 -1
- data/lib/libpng.rb +6 -0
- metadata +21 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fda67e6ac3b6280ed407565fc08a8166668093554afd534e33cf041d47900ecd
|
|
4
|
+
data.tar.gz: 060045bc45e2dc049d5957063a2dd045283b01f821666247b6a789638d35b277
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 253211e3494d116f6cf13e78b5688cf171b0c4f85817b2f818fb3d69cffaa4e025687c7e086885b27ea57c2083555097a99732f188464f786676224987e4a08c
|
|
7
|
+
data.tar.gz: adc29322d89eb94d2f978f57e82be6f59d2a9691c233cefc09552d0c021e11f3f438fe1a8aebb6da2df56db5acbc9b7e8c0a1ff9697815489505f80b2ddc592b
|
data/.github/workflows/build.yml
CHANGED
|
@@ -143,12 +143,6 @@ jobs:
|
|
|
143
143
|
platform: x86_64-linux-musl
|
|
144
144
|
- os: ubuntu-24.04-arm
|
|
145
145
|
platform: aarch64-linux-musl
|
|
146
|
-
# OHOS (OpenHarmony / Huawei HarmonyOS PC) is musl-based arm64.
|
|
147
|
-
# Built inside the same Alpine container as aarch64-linux-musl;
|
|
148
|
-
# the resulting binary is byte-compatible. Only the gem's
|
|
149
|
-
# platform label differs so RubyGems on OHOS selects it.
|
|
150
|
-
- os: ubuntu-24.04-arm
|
|
151
|
-
platform: aarch64-linux-ohos
|
|
152
146
|
|
|
153
147
|
steps:
|
|
154
148
|
- uses: actions/checkout@v4
|
|
@@ -174,27 +168,12 @@ jobs:
|
|
|
174
168
|
git config --global --add safe.directory /work
|
|
175
169
|
bundle install --jobs 4
|
|
176
170
|
bundle exec rake "gem:native:${PLATFORM}"
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
# the binary works without going through RubyGems install.
|
|
184
|
-
mkdir -p /tmp/ohos-smoke
|
|
185
|
-
gem unpack pkg/libpng-*.gem --target /tmp/ohos-smoke
|
|
186
|
-
(cd /tmp/ohos-smoke/libpng-* && \
|
|
187
|
-
ruby -Ilib -e 'require "libpng"; png = Libpng.encode(2, 2, "\xff" * 16, pixel_format: "RGBA"); puts Libpng.decode(png, pixel_format: "RGBA").inspect')
|
|
188
|
-
;;
|
|
189
|
-
*)
|
|
190
|
-
gem install -b pkg/libpng-*.gem
|
|
191
|
-
# Smoke test from /tmp so bundler's source-tree LOAD_PATH doesn't
|
|
192
|
-
# shadow the installed gem. Activate via `gem` so RubyGems resolves
|
|
193
|
-
# the platform-specific binary gem (Alpine Ruby's platform string
|
|
194
|
-
# is *-linux-musl, which must match the gem's platform suffix).
|
|
195
|
-
(cd /tmp && ruby -e 'gem "libpng"; require "libpng"; png = Libpng.encode(2, 2, "\xff" * 16, pixel_format: "RGBA"); File.binwrite("test.png", png); puts Libpng.decode(png, pixel_format: "RGBA").inspect')
|
|
196
|
-
;;
|
|
197
|
-
esac
|
|
171
|
+
gem install -b pkg/libpng-*.gem
|
|
172
|
+
# Smoke test from /tmp so bundler's source-tree LOAD_PATH doesn't
|
|
173
|
+
# shadow the installed gem. Activate via `gem` so RubyGems resolves
|
|
174
|
+
# the platform-specific binary gem (Alpine Ruby's platform string
|
|
175
|
+
# is *-linux-musl, which must match the gem's platform suffix).
|
|
176
|
+
(cd /tmp && ruby -e 'gem "libpng"; require "libpng"; png = Libpng.encode(2, 2, "\xff" * 16, pixel_format: "RGBA"); File.binwrite("test.png", png); puts Libpng.decode(png, pixel_format: "RGBA").inspect')
|
|
198
177
|
BUILD_EOF
|
|
199
178
|
chmod +x /tmp/alpine-build.sh
|
|
200
179
|
docker run --rm \
|
|
@@ -208,4 +187,90 @@ jobs:
|
|
|
208
187
|
- uses: actions/upload-artifact@v4
|
|
209
188
|
with:
|
|
210
189
|
name: pkg-${{ matrix.platform }}
|
|
190
|
+
path: pkg/*.gem
|
|
191
|
+
|
|
192
|
+
# OHOS (OpenHarmony / Huawei HarmonyOS PC) requires the official OHOS
|
|
193
|
+
# NDK to cross-compile. The NDK's clang and binary-sign-tool are x86_64
|
|
194
|
+
# ELF binaries; on this arm64 runner they run transparently via
|
|
195
|
+
# binfmt_misc + qemu-user-static. Verification (dockerharmony) runs
|
|
196
|
+
# natively because the arm64 rootfs matches the host architecture.
|
|
197
|
+
build_ohos:
|
|
198
|
+
name: build aarch64-linux-ohos (NDK)
|
|
199
|
+
runs-on: ubuntu-24.04-arm
|
|
200
|
+
needs: prepare
|
|
201
|
+
steps:
|
|
202
|
+
- uses: actions/checkout@v4
|
|
203
|
+
|
|
204
|
+
- name: Install host-side tools
|
|
205
|
+
# These are used for: NDK setup (curl/jq/unzip), artifact prep
|
|
206
|
+
# (file), and dockerharmony verification (docker is preinstalled).
|
|
207
|
+
run: |
|
|
208
|
+
sudo apt-get update
|
|
209
|
+
sudo apt-get install -y curl jq unzip file
|
|
210
|
+
|
|
211
|
+
- name: Register binfmt for amd64 docker emulation
|
|
212
|
+
# The OHOS NDK is x86_64-only. We run the entire build inside an
|
|
213
|
+
# amd64 docker container on this arm64 host -- docker's binfmt_misc
|
|
214
|
+
# registration handles the emulation transparently inside the
|
|
215
|
+
# container, with no library juggling on the host side.
|
|
216
|
+
run: docker run --privileged --rm tonistiigi/binfmt --install amd64
|
|
217
|
+
|
|
218
|
+
- name: Cache OHOS NDK
|
|
219
|
+
id: cache-ndk
|
|
220
|
+
uses: actions/cache@v4
|
|
221
|
+
with:
|
|
222
|
+
path: ext/ohos/ndk
|
|
223
|
+
key: ohos-ndk-${{ hashFiles('ext/ohos/setup-ndk.sh') }}
|
|
224
|
+
|
|
225
|
+
- name: Setup OHOS NDK (host-side; only curl/jq/unzip needed)
|
|
226
|
+
if: steps.cache-ndk.outputs.cache-hit != 'true'
|
|
227
|
+
run: sh ext/ohos/setup-ndk.sh --prefix ext/ohos/ndk
|
|
228
|
+
|
|
229
|
+
- name: Build OHOS gem in amd64 container
|
|
230
|
+
# The entire build (libpng + static zlib + signing) runs inside an
|
|
231
|
+
# amd64 docker container so the NDK's x86_64 clang + binary-sign-tool
|
|
232
|
+
# run natively (no qemu at the process level; docker's binfmt handles
|
|
233
|
+
# the container emulation as a whole).
|
|
234
|
+
run: |
|
|
235
|
+
docker run --rm --platform linux/amd64 \
|
|
236
|
+
-v "$PWD:/work" -w /work \
|
|
237
|
+
-e target_platform=aarch64-linux-ohos \
|
|
238
|
+
ruby:3.3 \
|
|
239
|
+
sh -c '
|
|
240
|
+
set -e
|
|
241
|
+
apt-get update
|
|
242
|
+
apt-get install -y --no-install-recommends cmake ninja-build zlib1g-dev
|
|
243
|
+
bundle install --jobs 4
|
|
244
|
+
bundle exec rake gem:native:aarch64-linux-ohos
|
|
245
|
+
# Confirm the .so was produced and is arm64 ELF (sanity).
|
|
246
|
+
file lib/libpng/libpng16.so
|
|
247
|
+
'
|
|
248
|
+
|
|
249
|
+
- name: Prepare dockerharmony artifacts (host-side)
|
|
250
|
+
# verify-prepare.sh cross-compiles smoke-test.c using the NDK clang.
|
|
251
|
+
# We run it inside the same amd64 container for the same reason.
|
|
252
|
+
run: |
|
|
253
|
+
docker run --rm --platform linux/amd64 \
|
|
254
|
+
-v "$PWD:/work" -w /work \
|
|
255
|
+
-e NDK_ROOT=/work/ext/ohos/ndk \
|
|
256
|
+
ruby:3.3 \
|
|
257
|
+
sh -c '
|
|
258
|
+
set -e
|
|
259
|
+
apt-get update
|
|
260
|
+
apt-get install -y --no-install-recommends file
|
|
261
|
+
sh ext/ohos/verify-prepare.sh
|
|
262
|
+
'
|
|
263
|
+
|
|
264
|
+
- name: Verify in dockerharmony (real OHOS userland, arm64-native)
|
|
265
|
+
run: |
|
|
266
|
+
docker pull ghcr.io/hqzing/dockerharmony:latest
|
|
267
|
+
docker run --rm \
|
|
268
|
+
-v "$PWD/ohos-verify:/work" \
|
|
269
|
+
-w /work \
|
|
270
|
+
ghcr.io/hqzing/dockerharmony:latest \
|
|
271
|
+
sh -c 'LD_LIBRARY_PATH=. ./smoke-test'
|
|
272
|
+
|
|
273
|
+
- uses: actions/upload-artifact@v4
|
|
274
|
+
with:
|
|
275
|
+
name: pkg-aarch64-linux-ohos
|
|
211
276
|
path: pkg/*.gem
|
|
@@ -201,10 +201,6 @@ jobs:
|
|
|
201
201
|
platform: x86_64-linux-musl
|
|
202
202
|
- os: ubuntu-24.04-arm
|
|
203
203
|
platform: aarch64-linux-musl
|
|
204
|
-
# OHOS: same Alpine-built musl arm64 binary as aarch64-linux-musl,
|
|
205
|
-
# packaged under a distinct platform label.
|
|
206
|
-
- os: ubuntu-24.04-arm
|
|
207
|
-
platform: aarch64-linux-ohos
|
|
208
204
|
steps:
|
|
209
205
|
- uses: actions/checkout@v4
|
|
210
206
|
with:
|
|
@@ -222,22 +218,8 @@ jobs:
|
|
|
222
218
|
git config --global --add safe.directory /work
|
|
223
219
|
bundle install --jobs 4
|
|
224
220
|
bundle exec rake "gem:native:${PLATFORM}"
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
# OHOS gem is labeled aarch64-linux-ohos so RubyGems on OHOS
|
|
228
|
-
# selects it, but Alpine Ruby reports *-linux-musl. The .so
|
|
229
|
-
# inside is musl-compatible -- unpack and load via -Ilib to
|
|
230
|
-
# verify the binary without going through RubyGems install.
|
|
231
|
-
mkdir -p /tmp/ohos-smoke
|
|
232
|
-
gem unpack pkg/libpng-*.gem --target /tmp/ohos-smoke
|
|
233
|
-
(cd /tmp/ohos-smoke/libpng-* && \
|
|
234
|
-
ruby -Ilib -e 'require "libpng"; png = Libpng.encode(2, 2, "\xff" * 16, pixel_format: "RGBA"); puts Libpng.decode(png, pixel_format: "RGBA").inspect')
|
|
235
|
-
;;
|
|
236
|
-
*)
|
|
237
|
-
gem install -b pkg/libpng-*.gem
|
|
238
|
-
(cd /tmp && ruby -e 'gem "libpng"; require "libpng"; png = Libpng.encode(2, 2, "\xff" * 16, pixel_format: "RGBA"); puts Libpng.decode(png, pixel_format: "RGBA").inspect')
|
|
239
|
-
;;
|
|
240
|
-
esac
|
|
221
|
+
gem install -b pkg/libpng-*.gem
|
|
222
|
+
(cd /tmp && ruby -e 'gem "libpng"; require "libpng"; png = Libpng.encode(2, 2, "\xff" * 16, pixel_format: "RGBA"); puts Libpng.decode(png, pixel_format: "RGBA").inspect')
|
|
241
223
|
BUILD_EOF
|
|
242
224
|
chmod +x /tmp/alpine-build.sh
|
|
243
225
|
docker run --rm \
|
|
@@ -253,8 +235,79 @@ jobs:
|
|
|
253
235
|
name: pkg-${{ matrix.platform }}
|
|
254
236
|
path: pkg/*.gem
|
|
255
237
|
|
|
238
|
+
# OHOS NDK cross-compile. See build.yml's build_ohos job for full notes.
|
|
239
|
+
build_ohos:
|
|
240
|
+
needs: bump
|
|
241
|
+
if: always() && !cancelled() && !failure() && (needs.bump.result == 'success' || needs.bump.result == 'skipped')
|
|
242
|
+
runs-on: ubuntu-24.04-arm
|
|
243
|
+
steps:
|
|
244
|
+
- uses: actions/checkout@v4
|
|
245
|
+
with:
|
|
246
|
+
ref: ${{ needs.bump.outputs.sha || github.ref }}
|
|
247
|
+
|
|
248
|
+
- name: Install host-side tools
|
|
249
|
+
run: |
|
|
250
|
+
sudo apt-get update
|
|
251
|
+
sudo apt-get install -y curl jq unzip file
|
|
252
|
+
|
|
253
|
+
- name: Register binfmt for amd64 docker emulation
|
|
254
|
+
run: docker run --privileged --rm tonistiigi/binfmt --install amd64
|
|
255
|
+
|
|
256
|
+
- name: Cache OHOS NDK
|
|
257
|
+
id: cache-ndk
|
|
258
|
+
uses: actions/cache@v4
|
|
259
|
+
with:
|
|
260
|
+
path: ext/ohos/ndk
|
|
261
|
+
key: ohos-ndk-${{ hashFiles('ext/ohos/setup-ndk.sh') }}
|
|
262
|
+
|
|
263
|
+
- name: Setup OHOS NDK
|
|
264
|
+
if: steps.cache-ndk.outputs.cache-hit != 'true'
|
|
265
|
+
run: sh ext/ohos/setup-ndk.sh --prefix ext/ohos/ndk
|
|
266
|
+
|
|
267
|
+
- name: Build OHOS gem in amd64 container
|
|
268
|
+
run: |
|
|
269
|
+
docker run --rm --platform linux/amd64 \
|
|
270
|
+
-v "$PWD:/work" -w /work \
|
|
271
|
+
-e target_platform=aarch64-linux-ohos \
|
|
272
|
+
ruby:3.3 \
|
|
273
|
+
sh -c '
|
|
274
|
+
set -e
|
|
275
|
+
apt-get update
|
|
276
|
+
apt-get install -y --no-install-recommends cmake ninja-build zlib1g-dev
|
|
277
|
+
bundle install --jobs 4
|
|
278
|
+
bundle exec rake gem:native:aarch64-linux-ohos
|
|
279
|
+
file lib/libpng/libpng16.so
|
|
280
|
+
'
|
|
281
|
+
|
|
282
|
+
- name: Prepare dockerharmony artifacts
|
|
283
|
+
run: |
|
|
284
|
+
docker run --rm --platform linux/amd64 \
|
|
285
|
+
-v "$PWD:/work" -w /work \
|
|
286
|
+
-e NDK_ROOT=/work/ext/ohos/ndk \
|
|
287
|
+
ruby:3.3 \
|
|
288
|
+
sh -c '
|
|
289
|
+
set -e
|
|
290
|
+
apt-get update
|
|
291
|
+
apt-get install -y --no-install-recommends file
|
|
292
|
+
sh ext/ohos/verify-prepare.sh
|
|
293
|
+
'
|
|
294
|
+
|
|
295
|
+
- name: Verify in dockerharmony (real OHOS userland)
|
|
296
|
+
run: |
|
|
297
|
+
docker pull ghcr.io/hqzing/dockerharmony:latest
|
|
298
|
+
docker run --rm \
|
|
299
|
+
-v "$PWD/ohos-verify:/work" \
|
|
300
|
+
-w /work \
|
|
301
|
+
ghcr.io/hqzing/dockerharmony:latest \
|
|
302
|
+
sh -c 'LD_LIBRARY_PATH=. ./smoke-test'
|
|
303
|
+
|
|
304
|
+
- uses: actions/upload-artifact@v4
|
|
305
|
+
with:
|
|
306
|
+
name: pkg-aarch64-linux-ohos
|
|
307
|
+
path: pkg/*.gem
|
|
308
|
+
|
|
256
309
|
publish:
|
|
257
|
-
needs: [ bump, build, build_musl ]
|
|
310
|
+
needs: [ bump, build, build_musl, build_ohos ]
|
|
258
311
|
if: always() && !cancelled() && !failure()
|
|
259
312
|
runs-on: ubuntu-latest
|
|
260
313
|
steps:
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,56 @@ This gem follows a `{LIBPNG_VERSION}.{LIBPNG_RUBY_ITERATION}` version
|
|
|
7
7
|
scheme. `LIBPNG_VERSION` is the upstream libpng release; `ITERATION`
|
|
8
8
|
bumps for Ruby-side changes and resets to 0 when LIBPNG_VERSION bumps.
|
|
9
9
|
|
|
10
|
+
## [1.6.58.6] - 2026-07-26
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **OHOS (`aarch64-linux-ohos`) is now cross-compiled with the official OHOS
|
|
14
|
+
NDK** (Huawei's `ohos.toolchain.cmake` + LLVM-19 clang), replacing the
|
|
15
|
+
1.6.58.4/.5 approach of shipping Alpine-built musl bytes labeled as OHOS.
|
|
16
|
+
|
|
17
|
+
The build runs on `ubuntu-24.04-arm`. The OHOS NDK clang is an x86_64
|
|
18
|
+
binary and runs transparently via `binfmt_misc` + `qemu-user-static`.
|
|
19
|
+
zlib is built statically with the same toolchain and linked into
|
|
20
|
+
`libpng16.so` (avoids the OHOS non-standard zlib SONAME
|
|
21
|
+
`libshared_libz.z.so`). The freshly built `.so` is code-signed with
|
|
22
|
+
`binary-sign-tool sign -selfSign 1` (mandatory for runtime loading on
|
|
23
|
+
production OHOS devices).
|
|
24
|
+
|
|
25
|
+
Verification: the signed `.so` is loaded by a smoke-test binary inside
|
|
26
|
+
real OHOS userland (the `dockerharmony` container running natively on
|
|
27
|
+
the same arm64 host -- no qemu). Build fails if the smoke test fails.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- `lib/libpng/ohos.rb`, `lib/libpng/ohos/{ndk,zlib_builder,code_signer,recipe}.rb`
|
|
31
|
+
-- OHOS cross-compile support. Lazy-loaded only when building for OHOS.
|
|
32
|
+
- `Libpng::OHOS::NDK` -- pure-data class for NDK path discovery.
|
|
33
|
+
- `Libpng::OHOS::ZlibBuilder < MiniPortileCMake` -- static zlib build.
|
|
34
|
+
- `Libpng::OHOS::CodeSigner` -- wraps `binary-sign-tool`.
|
|
35
|
+
- `Libpng::OHOS::Recipe < Libpng::Recipe` -- orchestrates the OHOS build.
|
|
36
|
+
- `lib/libpng/recipe.rb`: `Recipe.for_target(platform)` factory -- OCP seam
|
|
37
|
+
that returns `OHOS::Recipe` for `*-ohos` targets, base `Recipe` otherwise.
|
|
38
|
+
- `ext/ohos/setup-ndk.sh` -- downloads OHOS SDK + LLVM-19 via daily_build API
|
|
39
|
+
(adapted from ohos-node's `build.sh`).
|
|
40
|
+
- `ext/ohos/smoke-test.c` -- minimal libpng round-trip test for dockerharmony.
|
|
41
|
+
- `ext/ohos/verify-prepare.sh` -- cross-compiles smoke-test with NDK clang,
|
|
42
|
+
bundles signed `.so` + SONAME symlinks (fixes PR #12's symlink bug).
|
|
43
|
+
- 49 new specs under `spec/ohos/` + `spec/recipe_factory_spec.rb`.
|
|
44
|
+
|
|
45
|
+
### Caveats
|
|
46
|
+
- The 1.6.58.4/.5 OHOS gems shipped Alpine-built bytes without NDK
|
|
47
|
+
verification. This version is the first with proper OHOS NDK
|
|
48
|
+
cross-compilation + signing.
|
|
49
|
+
- Code signing uses `-selfSign 1` (self-signed). Sufficient for OHOS
|
|
50
|
+
userland load. Production deployment on Huawei-managed hardware may
|
|
51
|
+
require re-signing with an enrolled cert.
|
|
52
|
+
|
|
53
|
+
### Superseded
|
|
54
|
+
- PR #11 (closed) -- hand-written `toolchain.cmake` + system CMake. Replaced
|
|
55
|
+
by NDK's bundled `ohos.toolchain.cmake`.
|
|
56
|
+
- PR #12 (closed) -- dockerharmony verification of Alpine bytes. The
|
|
57
|
+
verification step is reused here; the Alpine-built `.so` is replaced
|
|
58
|
+
with the NDK-built, signed one.
|
|
59
|
+
|
|
10
60
|
## [1.6.58.5] - 2026-07-26
|
|
11
61
|
|
|
12
62
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -29,8 +29,16 @@ loaded via `autoload` from `lib/libpng.rb`. **Never use `require_relative`
|
|
|
29
29
|
| `lib/libpng/standard_decoder.rb` | `Libpng::StandardDecoder` (libpng standard read API; explicit transform control) |
|
|
30
30
|
| `lib/libpng/metadata_writer.rb` | `Libpng::MetadataWriter` (validates + writes text/gAMA/sRGB/cHRM/iCCP/pHYs onto a png_ptr/info_ptr pair) |
|
|
31
31
|
| `lib/libpng/text_writer.rb` | `Libpng::TextWriter` + `Libpng::TextEntry` (builds png_text struct array, calls `png_set_text`) |
|
|
32
|
-
| `lib/libpng/recipe.rb` | `Libpng::Recipe < MiniPortileCMake` (builds libpng from source for the source gem) |
|
|
33
|
-
| `
|
|
32
|
+
| `lib/libpng/recipe.rb` | `Libpng::Recipe < MiniPortileCMake` (builds libpng from source for the source gem). Has `.for_target(platform)` factory -- OCP seam that returns `OHOS::Recipe` for `*-ohos`, base `Recipe` otherwise |
|
|
33
|
+
| `lib/libpng/ohos.rb` | `Libpng::OHOS` namespace + autoloads. Lazy-loaded only when `Recipe.for_target` is called with an OHOS target |
|
|
34
|
+
| `lib/libpng/ohos/ndk.rb` | `OHOS::NDK` -- pure-data class for NDK path discovery (toolchain/sysroot/clang/sign-tool). Idempotent `#download` via `setup-ndk.sh` |
|
|
35
|
+
| `lib/libpng/ohos/zlib_builder.rb` | `OHOS::ZlibBuilder < MiniPortileCMake` -- builds `libz.a` statically with the OHOS toolchain |
|
|
36
|
+
| `lib/libpng/ohos/code_signer.rb` | `OHOS::CodeSigner` -- wraps `binary-sign-tool sign -selfSign 1`. Pure-data `#sign_command` is testable without invoking the tool |
|
|
37
|
+
| `lib/libpng/ohos/recipe.rb` | `OHOS::Recipe < Libpng::Recipe` -- orchestrates NDK setup, zlib build, libpng cross-compile with `ohos.toolchain.cmake`, and post-install signing |
|
|
38
|
+
| `ext/extconf.rb` | Gem extension entry. Calls `Libpng::Recipe.for_target(ENV['target_platform']).new`, then emits a dummy Makefile |
|
|
39
|
+
| `ext/ohos/setup-ndk.sh` | Downloads OHOS SDK + LLVM-19 via OpenHarmony daily_build API (adapted from ohos-node/build.sh). Idempotent |
|
|
40
|
+
| `ext/ohos/smoke-test.c` | Minimal libpng round-trip test, cross-compiled with NDK clang and run inside dockerharmony |
|
|
41
|
+
| `ext/ohos/verify-prepare.sh` | Cross-compiles smoke-test, bundles signed `.so` + SONAME symlinks for dockerharmony |
|
|
34
42
|
|
|
35
43
|
### Public API
|
|
36
44
|
|
|
@@ -74,6 +82,25 @@ bundle exec rake gem:native:any # source gem (compiles on install)
|
|
|
74
82
|
|
|
75
83
|
Platform gem tasks: `x64-mingw32`, `x64-mingw-ucrt`, `aarch64-mingw-ucrt`, `x86_64-linux`, `x86_64-linux-musl`, `aarch64-linux`, `aarch64-linux-musl`, `aarch64-linux-ohos`, `x86_64-darwin`, `arm64-darwin`.
|
|
76
84
|
|
|
85
|
+
### OHOS (`aarch64-linux-ohos`) build notes
|
|
86
|
+
|
|
87
|
+
OHOS uses a dedicated `build_ohos` CI job (see `.github/workflows/build.yml`)
|
|
88
|
+
that runs on `ubuntu-24.04-arm`. The NDK's clang and `binary-sign-tool` are
|
|
89
|
+
x86_64 ELF and run via `binfmt_misc` + `qemu-user-static`. The job:
|
|
90
|
+
|
|
91
|
+
1. Downloads OHOS SDK + LLVM-19 via `ext/ohos/setup-ndk.sh` (~1.5 GB, cached
|
|
92
|
+
across runs by `actions/cache@v4`).
|
|
93
|
+
2. Runs `rake gem:native:aarch64-linux-ohos`, which delegates to
|
|
94
|
+
`Libpng::OHOS::Recipe` (sets up NDK, builds static zlib, cross-compiles
|
|
95
|
+
libpng with `ohos.toolchain.cmake`, signs the `.so`).
|
|
96
|
+
3. Cross-compiles `ext/ohos/smoke-test.c` with NDK clang via
|
|
97
|
+
`verify-prepare.sh`, then runs it inside the `dockerharmony` container
|
|
98
|
+
(real OHOS userland) — build fails if smoke-test doesn't output `OK`.
|
|
99
|
+
|
|
100
|
+
Local dev: `target_platform=aarch64-linux-ohos bundle exec rake compile`
|
|
101
|
+
will only succeed on an arm64 host with `qemu-user-static` registered,
|
|
102
|
+
because the NDK clang is x86_64 ELF. CI handles this automatically.
|
|
103
|
+
|
|
77
104
|
## Release process
|
|
78
105
|
|
|
79
106
|
Releases are tag-triggered via `.github/workflows/release.yml`. Trigger with:
|
data/README.adoc
CHANGED
|
@@ -44,7 +44,7 @@ for the current set):
|
|
|
44
44
|
| `x86_64-linux-musl` | x86_64 Linux (musl, e.g. Alpine) | `ruby:<ver>-alpine` on x86_64
|
|
45
45
|
| `aarch64-linux` | ARM64 Linux (glibc) | `ubuntu-24.04-arm` (native)
|
|
46
46
|
| `aarch64-linux-musl` | ARM64 Linux (musl) | `ruby:<ver>-alpine` on arm64
|
|
47
|
-
| `aarch64-linux-ohos` | ARM64 OpenHarmony / Huawei HarmonyOS PC | `
|
|
47
|
+
| `aarch64-linux-ohos` | ARM64 OpenHarmony / Huawei HarmonyOS PC | `ubuntu-24.04-arm` + OHOS NDK (cross-compiled, signed, **verified in dockerharmony**)
|
|
48
48
|
| `x64-mingw32` | x64 Windows, RubyInstaller < 3.0 (MSVCRT) | `windows-latest`
|
|
49
49
|
| `x64-mingw-ucrt` | x64 Windows, RubyInstaller >= 3.0 (UCRT) | `windows-latest`
|
|
50
50
|
| `aarch64-mingw-ucrt` | ARM64 Windows (Ruby >= 3.4) | `windows-11-arm` (native)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# 01 - Architecture
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Cross-compile `libpng16.so` for `aarch64-linux-ohos` using the official OHOS
|
|
6
|
+
NDK (Huawei-blessed toolchain), code-sign it, and empirically verify it in
|
|
7
|
+
real OHOS userland (dockerharmony). Replace the 1.6.58.4/.5/.6 approach of
|
|
8
|
+
"Alpine-built bytes labeled as OHOS".
|
|
9
|
+
|
|
10
|
+
## Why this design (vs PR #11 / PR #12)
|
|
11
|
+
|
|
12
|
+
| Approach | Status | Why rejected |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| Alpine bytes labeled OHOS (1.6.58.4/.5) | shipped | unverified assumption; user flagged musl symbol visibility, TLS, pthread layout risks |
|
|
15
|
+
| PR #11: hand-written `toolchain.cmake` + system CMake | closed | 5 CI iterations failed (sysroot path, missing zlib in sysroot, try_compile couldn't find crt objects) — root cause: NOT using NDK's bundled `ohos.toolchain.cmake` |
|
|
16
|
+
| PR #12: Alpine bytes + dockerharmony verification | closed | still ships Alpine bytes labeled OHOS; user wants proper NDK bytes |
|
|
17
|
+
| **PR #13 (this plan)** | current | NDK-bundled `ohos.toolchain.cmake` + static zlib + `binary-sign-tool` + dockerharmony verify |
|
|
18
|
+
|
|
19
|
+
## Key insights from references
|
|
20
|
+
|
|
21
|
+
- **OHOS CMake doc** (`openharmony-6.0-app-dev-docs/napi/build-with-ndk-cmake.md`):
|
|
22
|
+
- NDK ships own CMake at `${SDK_PATH}/native/build-tools/cmake/bin/cmake`
|
|
23
|
+
- Toolchain file at `${SDK_PATH}/native/build/cmake/ohos.toolchain.cmake`
|
|
24
|
+
- Invoke: `cmake -DOHOS_ARCH=arm64-v8a -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE=...`
|
|
25
|
+
- Toolchain handles sysroot + `--target=arm-linux-ohos` + try_compile compatibility
|
|
26
|
+
|
|
27
|
+
- **ohos-node** (`~/src/external/ohos-node/build.sh`):
|
|
28
|
+
- NDK download via `https://dcp.openharmony.cn/api/daily_build/build/list/component`
|
|
29
|
+
- Two components needed: `ohos-sdk-public` (SDK + `binary-sign-tool`) + `LLVM-19` (clang + sysroot)
|
|
30
|
+
- `binary-sign-tool sign -selfSign 1` is mandatory post-build
|
|
31
|
+
- Output runs on OHOS via dockerharmony (real OHOS rootfs)
|
|
32
|
+
|
|
33
|
+
- **dockerharmony** (`~/src/external/dockerharmony/`):
|
|
34
|
+
- OHOS rootfs (musl + toybox + mksh) in Docker, runs aarch64-linux-musl binaries natively on arm64 hosts
|
|
35
|
+
- OHOS ships zlib as `libshared_libz.z.so` (NOT `libz.so`) — patchelf needed if linking dynamically
|
|
36
|
+
|
|
37
|
+
- **NDK architecture reality** (verified):
|
|
38
|
+
- `LLVM-19` tarball contains `llvm-linux-x86_64.tar.gz` (x86_64-build clang) + `ohos-sysroot.tar.gz` (architecture-independent sysroot files)
|
|
39
|
+
- There is **no arm64 build of the NDK clang** in the daily_build output
|
|
40
|
+
- `ohos.toolchain.cmake` is a CMake script (architecture-independent)
|
|
41
|
+
- `binary-sign-tool` is in the x86_64-build ohos-sdk
|
|
42
|
+
|
|
43
|
+
## CI topology (corrected: native arm64 + transparent qemu for NDK binaries)
|
|
44
|
+
|
|
45
|
+
Single job on `ubuntu-24.04-arm` (native arm64 runner):
|
|
46
|
+
|
|
47
|
+
1. Install `qemu-user-static` + `binfmt-support` — registers binfmt_misc so
|
|
48
|
+
x86_64 ELF binaries run transparently via `qemu-x86_64`.
|
|
49
|
+
2. Run `ext/ohos/setup-ndk.sh` → NDK + LLVM-19 in `ext/ohos/ndk/`
|
|
50
|
+
3. `bundle exec rake gem:native:aarch64-linux-ohos` →
|
|
51
|
+
- `OHOS::Recipe#cook` runs:
|
|
52
|
+
- Downloads libpng source (MiniPortile)
|
|
53
|
+
- Builds static zlib via `OHOS::ZlibBuilder` (NDK clang under binfmt)
|
|
54
|
+
- CMake-configures libpng with `ohos.toolchain.cmake` + static zlib (NDK cmake/clang under binfmt)
|
|
55
|
+
- Builds + installs `libpng16.so`
|
|
56
|
+
- Signs `.so` via `OHOS::CodeSigner` (`binary-sign-tool` under binfmt)
|
|
57
|
+
4. Run `ext/ohos/verify-prepare.sh` → `ohos-verify/` artifacts (cross-compile smoke-test with NDK clang)
|
|
58
|
+
5. Run dockerharmony natively: `docker run --rm -v ...:/work ghcr.io/hqzing/dockerharmony:latest sh -c 'LD_LIBRARY_PATH=. ./smoke-test'`
|
|
59
|
+
|
|
60
|
+
### Why this is the right topology
|
|
61
|
+
|
|
62
|
+
| Aspect | x86_64 runner (original plan) | arm64 runner + qemu (revised) |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| NDK clang / binary-sign-tool | native speed | ~5x slower (qemu emulation) |
|
|
65
|
+
| dockerharmony verification | ~5x slower (qemu binfmt for arm64) | **native speed** |
|
|
66
|
+
| CI complexity | needs binfmt setup, multi-arch docker pull | standard docker pull |
|
|
67
|
+
| Total CI time | dominated by slow dockerharmony emulation | dominated by slow NDK compile (smaller) |
|
|
68
|
+
|
|
69
|
+
Compilation is ~1 min native → ~5 min under qemu (acceptable).
|
|
70
|
+
dockerharmony smoke-test is ~50ms native → ~250ms under qemu — small absolute number,
|
|
71
|
+
but the binfmt setup for arm64 emulation on x86_64 is finicky and has been flaky
|
|
72
|
+
in CI historically. Native arm64 docker is rock-solid.
|
|
73
|
+
|
|
74
|
+
**Net**: arm64 + qemu is simpler AND faster overall.
|
|
75
|
+
|
|
76
|
+
## MECE file layout
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
ext/ohos/
|
|
80
|
+
├── setup-ndk.sh # Downloads SDK + LLVM-19 (idempotent, shell)
|
|
81
|
+
├── smoke-test.c # Round-trip test (kept from PR #12)
|
|
82
|
+
├── verify-prepare.sh # Cross-compiles smoke-test, bundles for dockerharmony
|
|
83
|
+
└── (no toolchain.cmake — we use NDK's bundled ohos.toolchain.cmake)
|
|
84
|
+
|
|
85
|
+
lib/libpng/
|
|
86
|
+
├── recipe.rb # Add Recipe.for_target factory (OCP seam)
|
|
87
|
+
├── ohos.rb # Module Libpng::OHOS + autoloads
|
|
88
|
+
└── ohos/
|
|
89
|
+
├── ndk.rb # OHOS::NDK: pure-data path discovery + download
|
|
90
|
+
├── zlib_builder.rb # OHOS::ZlibBuilder < MiniPortileCMake (static zlib)
|
|
91
|
+
├── code_signer.rb # OHOS::CodeSigner: wraps binary-sign-tool
|
|
92
|
+
└── recipe.rb # OHOS::Recipe < Libpng::Recipe
|
|
93
|
+
|
|
94
|
+
lib/libpng.rb # Add autoload :OHOS, 'libpng/ohos'
|
|
95
|
+
ext/extconf.rb # Use Recipe.for_target(...) factory
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## OCP compliance
|
|
99
|
+
|
|
100
|
+
Adding a new cross-compile platform = adding `lib/libpng/<platform>/` with a
|
|
101
|
+
`<Platform>::Recipe < Libpng::Recipe` subclass and registering it in
|
|
102
|
+
`Recipe.for_target`. No modification of `Libpng::Recipe` needed.
|
|
103
|
+
|
|
104
|
+
The existing `Libpng::Recipe` is unchanged (except adding the factory class
|
|
105
|
+
method). All OHOS logic is in `lib/libpng/ohos/`.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# 02 - Close PR #12, branch off main
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. Close PR #12 with a comment explaining the pivot:
|
|
6
|
+
|
|
7
|
+
> Closing in favor of a proper OHOS NDK cross-compile approach (PR #13).
|
|
8
|
+
> The dockerharmony verification step is reused; the build approach changes
|
|
9
|
+
> from "Alpine-built bytes labeled OHOS" to "NDK-built bytes signed with
|
|
10
|
+
> binary-sign-tool". The smoke-test.c file is carried over.
|
|
11
|
+
|
|
12
|
+
2. From `main`, create `fix/ohos-ndk-cmake`:
|
|
13
|
+
```sh
|
|
14
|
+
git checkout main
|
|
15
|
+
git pull origin main
|
|
16
|
+
git checkout -b fix/ohos-ndk-cmake
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
3. Cherry-pick reusable files from `fix/ohos-dockerharmony`:
|
|
20
|
+
- `ext/ohos/smoke-test.c` — keep as-is
|
|
21
|
+
- `lib/libpng/version.rb` — keep iteration = 6 (it's already at 6 on PR #12 branch)
|
|
22
|
+
|
|
23
|
+
`verify-prepare.sh` will be rewritten (was Alpine-gcc-based; new version
|
|
24
|
+
uses NDK clang for cross-compile from x86_64 host).
|
|
25
|
+
|
|
26
|
+
## Why branch off main (not off fix/ohos-dockerharmony)
|
|
27
|
+
|
|
28
|
+
PR #12's CI changes (build.yml, release.yml) are incompatible with the NDK
|
|
29
|
+
approach — they assume Alpine container build. Cleaner to start fresh and
|
|
30
|
+
re-introduce only what's needed.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# 03 - ext/ohos/setup-ndk.sh
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Download and extract the OHOS NDK (SDK + LLVM-19) into `ext/ohos/ndk/`.
|
|
6
|
+
Idempotent — skips if the destination already looks complete.
|
|
7
|
+
|
|
8
|
+
## Source pattern
|
|
9
|
+
|
|
10
|
+
Adapted from `~/src/external/ohos-node/build.sh` (lines 14-49). Key pieces:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
query_component() {
|
|
14
|
+
component=$1
|
|
15
|
+
curl -fsSL 'https://dcp.openharmony.cn/api/daily_build/build/list/component' \
|
|
16
|
+
-H 'Accept: application/json, text/plain, */*' \
|
|
17
|
+
-H 'Content-Type: application/json' \
|
|
18
|
+
--data-raw '{"projectName":"openharmony","branch":"master","pageNum":1,"pageSize":10,"deviceLevel":"","component":"'${component}'","type":1,"startTime":"2025080100000000","endTime":"20990101235959","sortType":"","sortField":"","hardwareBoard":"","buildStatus":"success","buildFailReason":"","withDomain":1}'
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Two components needed:
|
|
23
|
+
- `ohos-sdk-public` → contains `toolchains/lib/binary-sign-tool` + `build/cmake/ohos.toolchain.cmake`
|
|
24
|
+
- `LLVM-19` → contains `llvm/bin/aarch64-unknown-linux-ohos-clang` + `ohos-sysroot.tar.gz`
|
|
25
|
+
|
|
26
|
+
## Script contract
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Usage: setup-ndk.sh [--prefix <dir>]
|
|
30
|
+
Default prefix: $PWD/ext/ohos/ndk
|
|
31
|
+
|
|
32
|
+
Outputs:
|
|
33
|
+
$PREFIX/ohos-sdk/linux/ # SDK
|
|
34
|
+
$PREFIX/llvm-19/llvm/ # Clang
|
|
35
|
+
$PREFIX/llvm-19/sysroot/ # OHOS sysroot (extracted from ohos-sysroot.tar.gz)
|
|
36
|
+
|
|
37
|
+
Exits 0 if setup is complete (or was already complete).
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Idempotency
|
|
41
|
+
|
|
42
|
+
Skip download if `$PREFIX/ohos-sdk/linux/toolchains/lib/binary-sign-tool` exists
|
|
43
|
+
AND `$PREFIX/llvm-19/sysroot/usr/lib/aarch64-linux-ohos/` exists. This lets
|
|
44
|
+
CI cache the directory across runs.
|
|
45
|
+
|
|
46
|
+
## Dependencies (CI-side)
|
|
47
|
+
|
|
48
|
+
- `curl`, `tar`, `unzip`, `jq` — apt-installed in workflow before script runs.
|
|
49
|
+
|
|
50
|
+
## Why shell (not Ruby)
|
|
51
|
+
|
|
52
|
+
- curl + jq + tar pipeline is 5 lines of shell vs 50+ lines of Ruby (Net::HTTP + JSON parsing).
|
|
53
|
+
- Pattern is proven by ohos-node; we follow it verbatim.
|
|
54
|
+
- Ruby's role is orchestration (deciding *when* to invoke); the script does the heavy lifting.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 04 - lib/libpng/ohos.rb + lib/libpng/ohos/ndk.rb
|
|
2
|
+
|
|
3
|
+
## lib/libpng.rb modification
|
|
4
|
+
|
|
5
|
+
Add one autoload entry (follows existing convention):
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# OHOS cross-compile support. Only loaded when building for aarch64-linux-ohos.
|
|
9
|
+
autoload :OHOS, 'libpng/ohos'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## lib/libpng/ohos.rb
|
|
13
|
+
|
|
14
|
+
Module namespace + sub-autoloads. Loaded lazily only when OHOS is referenced
|
|
15
|
+
(i.e., when `Recipe.for_target('aarch64-linux-ohos')` is called).
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
# frozen_string_literal: true
|
|
19
|
+
|
|
20
|
+
module Libpng
|
|
21
|
+
module OHOS
|
|
22
|
+
autoload :NDK, 'libpng/ohos/ndk'
|
|
23
|
+
autoload :Recipe, 'libpng/ohos/recipe'
|
|
24
|
+
autoload :ZlibBuilder, 'libpng/ohos/zlib_builder'
|
|
25
|
+
autoload :CodeSigner, 'libpng/ohos/code_signer'
|
|
26
|
+
|
|
27
|
+
TARGET_TRIPLE = 'aarch64-linux-ohos'
|
|
28
|
+
OHOS_ARCH = 'arm64-v8a'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## lib/libpng/ohos/ndk.rb
|
|
34
|
+
|
|
35
|
+
Pure-data class — discovers and validates NDK paths. No shell calls except
|
|
36
|
+
via explicit `#download` (which invokes `setup-ndk.sh`).
|
|
37
|
+
|
|
38
|
+
### Public API
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
class NDK
|
|
42
|
+
def initialize(root:) # root = Pathname to NDK install dir
|
|
43
|
+
def exist? # true if all expected paths present
|
|
44
|
+
def toolchain_path # Pathname to ohos.toolchain.cmake
|
|
45
|
+
def clang_path # Pathname to aarch64-unknown-linux-ohos-clang
|
|
46
|
+
def sysroot_path # Pathname to OHOS sysroot root
|
|
47
|
+
def sign_tool_path # Pathname to binary-sign-tool
|
|
48
|
+
def cmake_path # Pathname to NDK's bundled cmake binary
|
|
49
|
+
def download # invoke setup-ndk.sh (no-op if exist?)
|
|
50
|
+
end
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Design notes
|
|
54
|
+
|
|
55
|
+
- All path accessors return `Pathname` (not String) for composability.
|
|
56
|
+
- `#exist?` checks the four critical paths (toolchain, clang, sysroot, sign-tool).
|
|
57
|
+
- `#download` invokes `ext/ohos/setup-ndk.sh` via `system()`. Idempotent.
|
|
58
|
+
- No `instance_variable_get`/`set` — ivars are private, accessed via methods.
|
|
59
|
+
- No `respond_to?` — type checks use `is_a?`.
|
|
60
|
+
|
|
61
|
+
### Testability
|
|
62
|
+
|
|
63
|
+
Spec constructs a fake NDK directory structure (just empty files at expected
|
|
64
|
+
paths) and verifies accessors return correct Pathnames. No doubles, no real
|
|
65
|
+
download.
|