2024年9月23日 星期一

PHP 開發筆記 - 在 macOS 15 安裝 PHP 7.4 開發環境 @ Apple M2 / arm64

原本是習慣用 MacPorts 管理套件,然後升上 macOS 15 後,跑了 MacPorts migration 後,發現 php74 不見了,細追才發現沒裝起來 XD 努力研究了一下:

--->  Configuring php74
Warning: Configuration logfiles contain indications of -Wimplicit-function-declaration; check that features were not accidentally disabled:
  gethostbyname_r: found in php-7.4.33/config.log
  _controlfp: found in php-7.4.33/config.log
  _controlfp_s: found in php-7.4.33/config.log
Warning: Configuration logfiles contain indications of -Wimplicit-int; check that features were not accidentally disabled:
  found in php-7.4.33/config.log
--->  Building php74
Error: Failed to build php74: command execution failed   
Error: See /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_php/php74/main.log for details.
Error: Follow https://guide.macports.org/#project.tickets if you believe there is a bug.
Error: Processing of port php74 failed
--->  Some of the ports you installed have notes:
  db48 has the following notes:
    The Java and Tcl bindings are now provided by the db48-java and
    db48-tcl subports.

===

:info:build ld: warning: ignoring duplicate libraries: '-largon2', '-lxml2', '-lz'
:info:build Undefined symbols for architecture arm64:
:info:build   "_res_9_dn_expand", referenced from:
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       ...  
:info:build   "_res_9_dn_skipname", referenced from:
:info:build       _zif_dns_get_record in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build   "_res_9_init", referenced from:
:info:build       _zif_dns_check_record in dns.o
:info:build       _zif_dns_get_record in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build   "_res_9_search", referenced from:
:info:build       _zif_dns_check_record in dns.o
:info:build       _zif_dns_get_record in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build ld: symbol(s) not found for architecture arm64
:info:build clang: error: linker command failed with exit code 1 (use -v to see invocation)
:info:build make: *** [sapi/cli/php] Error 1
:info:build make: *** Waiting for unfinished jobs....
:info:build ld: warning: ignoring duplicate libraries: '-largon2', '-lxml2', '-lz'
:info:build Undefined symbols for architecture arm64:
:info:build   "_res_9_dn_expand", referenced from:
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       _php_parserr in dns.o
:info:build       ...  
:info:build   "_res_9_dn_skipname", referenced from:
:info:build       _zif_dns_get_record in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build   "_res_9_init", referenced from:
:info:build       _zif_dns_check_record in dns.o
:info:build       _zif_dns_get_record in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build   "_res_9_search", referenced from:
:info:build       _zif_dns_check_record in dns.o
:info:build       _zif_dns_get_record in dns.o
:info:build       _zif_dns_get_mx in dns.o
:info:build ld: symbol(s) not found for architecture arm64
:info:build clang: error: linker command failed with exit code 1 (use -v to see invocation)
:info:build make: *** [sapi/phpdbg/phpdbg] Error 1
:info:build make: Leaving directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_php/php74/work/php-7.4.33'
:info:build Command failed:  cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_php/php74/work/php-7.4.33" && /usr/bin/make -j8 -w all
:info:build Exit code: 2
:error:build Failed to build php74: command execution failed
:debug:build Error code: CHILDSTATUS 94983 2
:debug:build Backtrace: command execution failed
:debug:build     while executing
:debug:build "system {*}$notty {*}$callback {*}$nice $fullcmdstring"
:debug:build     invoked from within
:debug:build "command_exec -callback portprogress::target_progress_callback build"
:debug:build     (procedure "portbuild::build_main" line 10)
:debug:build     invoked from within
:debug:build "$procedure $targetname"
:error:build See /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_php/php74/main.log for details.

因此,主要是 _res_9_dn_* 等等的問題,問 AI 說,解方若還要繼續用 MacPorts 管理,只能裝個肥滋滋的 bind9

% sudo port install bind9
% sudo port clean php74
% sudo port install php74 configure.cflags="-I/opt/local/include" configure.ldflags="-L/opt/local/lib -lbind9 -ldns -lisc"

但這樣跑也失敗了

接著又試了 

% brew install php@7.4   
Warning: No available formula with the name "php@7.4". Did you mean php@8.2, php@8.1 or php@8.0?
==> Searching for similarly named formulae and casks...
==> Formulae
php@8.2                                               php@8.1                                               php@8.0

To install php@8.2, run:
  brew install php@8.2

雖然繼續深入問 AI 可以得到要做 php-7.4 patch 檔案,但這樣搞下去維護太累了,等於自己編譯 php74 跟改 code 了

最終,取個平衡,未來需要 php74 的環境,就靠 Docker 吧 XD 就單純這樣用即可:

% docker run -it -v ~/projects/:/projects -p 8080:8080 -p 8000:8000 -p 8443:8443 --rm php:7.4-cli bash

如此在 Docker 內部用 `php -S 0.0.0.0:8000` 就可以在 Host 端存取查看運行結果了

若還是想直接裝在系統,可以參考 github.com/shivammathur/homebrew-php

2024年9月8日 星期日

Dart 開發筆記 - 製作 Big5 to UTF8 工具以及發布到 pub.dev


最近想整理以前 C++ 寫過的東西來尋找熱情,先試試把很片段的小東西轉出來使用,這次純靠 claude.ai 做了滿多事,包括 README.md, CHANGELOG.md, example 和 test 都是他寫的 XD 剛好把最懶散的部分都給搞定了,因此 example 和 test 裡頭都會有簡體中文,甚至 README 一開始也給簡中版,只好請他給予英文版即可

整個過程大概不用兩個小時,非常舒服,花比較多的時間是請他把工具規劃成 library 的過程,claude ai 提了不少建議,但我也打槍他,最終有了現況的產出,這時真的感受到 AI 輔助的有趣的地方,還會提供一些觀點,像是 Flutter 他有多種平台,有些平台不適合 io 操作,這時會收到一些 AI 給予的建議,調整一些實作方向。


其中 pub.dev 發布過程還不太熟悉,參考官網 dart.dev.org.tw/tools/pub/publishing 先用指令:

```
big5_utf8_converter_dart % dart pub publish --dry-run                 
Resolving dependencies... 
Downloading packages... 
  _fe_analyzer_shared 73.0.0 (74.0.0 available)
  analyzer 6.8.0 (6.9.0 available)
  macros 0.1.2-main.4 (0.1.3-main.0 available)
Got dependencies!
3 packages have newer versions incompatible with dependency constraints.
Try `dart pub outdated` for more information.
Publishing big5_utf8_converter 1.0.0 to https://pub.dev:
├── CHANGELOG.md (<1 KB)
├── LICENSE (1 KB)
├── README.md (2 KB)
├── assets
│   └── big5_to_utf8_lookup.bin (64 KB)
├── bin2dart.dart (<1 KB)
├── example
│   ├── big5_utf8_converter_example.dart (<1 KB)
│   └── big5_utf8_converter_load_table_example.dart (1 KB)
├── lib
│   ├── big5_utf8_converter.dart (<1 KB)
│   └── src
│       ├── big5_to_utf8_lookup_data.dart (260 KB)
│       └── big5_utf8_converter.dart (1 KB)
├── pubspec.yaml (<1 KB)
└── test
    └── big5_decoder_test.dart (2 KB)

Total compressed archive size: 98 KB.
The server may enforce additional checks.

Package has 0 warnings.
```

接著才使用 Github Actions 來做事,僅需使用 Github Actions 預設的 Dart 就會幫跑 test case:


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

    steps:
      - uses: actions/checkout@v4

      - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603

      - name: Install dependencies
        run: dart pub get

      - name: Analyze project source
        run: dart analyze

      - name: Run tests
        run: dart test
```

最後,更新 README.md 增加圖標令牌:

[![pub package](https://img.shields.io/pub/v/big5_utf8_converter.svg)](https://pub.dev/packages/big5_utf8_converter)
[![Build Status](https://github.com/changyy/big5_utf8_converter_dart/workflows/Dart/badge.svg)](https://github.com/changyy/big5_utf8_converter_dart/actions)

收工!