diff --git a/devel/1129.md b/devel/1129.md new file mode 100644 index 0000000000..28f88788a9 --- /dev/null +++ b/devel/1129.md @@ -0,0 +1,84 @@ +# [1129] 引入 goldfish package,移除 s7 package + +## 1 背景 + +- 历史上 s7 作为独立 xmake package 定义在 `xmake/packages/s/s7/`, + 其源码与 `xmake/goldfish.lua` 的 goldfish binary target 内联编译的 + s7 源码完全相同(均来自 `TeXmacs/plugins/goldfish/src/`)。两份构建 + 脚本(s7 package 的 `port/xmake.lua` 与 goldfish target 的 + `add_files`)手工维护同一份源文件清单,容易漂移。 +- `libmogan` / `stem` / tests 通过 `add_packages("s7")` 拿到 s7 的头文件 + 和静态库,而 goldfish binary 又把同一批 s7 源码重新内联编译了一遍, + 存在概念上的重复。 +- s7 本身只是 goldfish 项目的内置 Scheme 引擎,真正的对外单元应当是 + goldfish,而非裸 s7。 + +## 2 What + +1. 在 `xmake/goldfish.lua` 中新增 `package("goldfish")` 定义: + - 源码来自 `TeXmacs/plugins/goldfish/src/`(与 goldfish binary 同源) + - `on_install` 把 `*.c`/`*.h` 拷贝到包缓存目录,并在缓存目录内联 + 生成 `xmake.lua`(定义 `libgoldfish` 静态库 target),再用 + `package.tools.xmake.install` 构建,保持工作树干净 + - `libgoldfish` 编译全部 `s7*.c`(C11),`add_headerfiles("s7.h")` + 并通过 `add_includedirs(".", {public = true})` 公开头文件 + - 依赖 `liii-tbox`(s7 部分宏需要 tbox) +2. `xmake.lua`: `add_requires("s7")` → `add_requires("goldfish")`; + `libmogan` 与 `stem` 的 `add_packages("s7")` → `add_packages("goldfish")`。 +3. `xmake/tests.lua`: 两处 `add_packages("s7")` → `add_packages("goldfish")`。 +4. 删除 `xmake/packages/s/s7/`(含 `xmake.lua` 与 `port/xmake.lua`)。 +5. `xmake/goldfish.lua` 中原有的 `target("goldfish")` binary 定义保持 + 不变 —— 它仍负责产出 goldfish REPL 可执行文件(包含 `goldfish.cpp` + 的 `main` 与 `liii_*.cpp` / json-schema-validator 等完整功能)。 + +## 3 Why + +- **消除重复**:s7 package 与 goldfish binary target 此前各自维护一份 + 完全相同的 s7 源文件清单(`s7.c` / `s7_continuation.c` / ... + 共 19 个文件),任何一边漏改都会导致 libmogan/stem 链接的 s7 与 + goldfish REPL 内嵌的 s7 行为不一致。改为以 goldfish 为唯一对外 + package 后,源码出处唯一(goldfish 源码树),概念上也更准确 —— + s7 只是 goldfish 内部实现细节。 +- **命名对齐**:外部依赖方现在 `add_packages("goldfish")`,与分支名 + `da/1129/libgoldfish` 及 goldfish 项目的实际身份一致,不再让后续 + 开发者误以为项目「直接依赖上游 s7」。 +- **为后续 libgoldfish 拆分铺路**:当前 libgoldfish 只编译 s7 子集, + 后续可逐步把 `liii_*.cpp` 也迁入 libgoldfish,让 goldfish binary + 反过来依赖 libgoldfish,彻底消除 goldfish.lua 中那份 19 行的 + s7 源文件清单。本 PR 先完成 package 化这一步。 + +## 4 How + +- `package("goldfish")` 的 `on_install` 借鉴原 s7 package 的做法: + 不使用 `set_sourcedir()`(会让 `package.tools.xmake` 把生成的 + xmake.lua 写进工作树,污染 `TeXmacs/plugins/goldfish/src/`), + 而是手工 `os.cp` 源码到 `package:cachedir()`,再用 `io.writefile` + 在该缓存目录内联生成 port 构建脚本,最后以 `{curdir = curdir}` + 交给 `package.tools.xmake.install`。 +- 所有 package 定义代码集中在 `xmake/goldfish.lua`(与 `3rdparty/tbox.lua` + 把 `package("liii-tbox")` 与 target 放同一文件的风格一致),不另建 + `xmake/packages/g/goldfish/` 目录,减少散落。 +- `libgoldfish` target 的源文件清单、`add_defines`、`set_basename` + 等与原 s7 `port/xmake.lua` 的 `libs7` target 完全对齐,仅改名 + `libs7` → `libgoldfish`、`set_basename("s7")` → `set_basename("goldfish")`, + 保证行为不变。 +- goldfish binary target 的 `add_files` / `add_includedirs` / + `add_packages` 维持原状,REPL 可执行文件行为不受影响。 + +## 5 涉及文件 + +- `xmake/goldfish.lua`(新增 `package("goldfish")` 定义,保留原 + `target("goldfish")`) +- `xmake.lua`(`add_requires` 与两处 `add_packages` 由 s7 改为 goldfish) +- `xmake/tests.lua`(两处 `add_packages` 由 s7 改为 goldfish) +- `xmake/packages/s/s7/xmake.lua`(删除) +- `xmake/packages/s/s7/port/xmake.lua`(删除) +- `devel/1129.md`(新增,本文档) + +## 6 验证 + +- `grep -rn 'add_requires.*"s7"\|add_packages.*"s7"' xmake.lua xmake/*.lua` + 无匹配。 +- `xmake f -c --yes` 配置通过,goldfish package 成功安装到缓存。 +- `xmake b stem` 构建通过(`libmogan.a` / `moganstem` 均链接成功, + 证明 goldfish package 正确暴露了 s7 头文件与符号)。 diff --git a/xmake.lua b/xmake.lua index 214bc245f7..02023cc6b1 100644 --- a/xmake.lua +++ b/xmake.lua @@ -25,7 +25,7 @@ set_policy("run.autobuild", false) set_languages("c++17") set_encodings("utf-8") -add_requires("s7", {system=false}) +add_requires("goldfish", {system=false}) add_requires("liii-tbox", {system=false}) add_requires("cpr", {system=false}) includes("xmake/goldfish.lua") @@ -540,7 +540,7 @@ target("libmogan") do add_packages("liii-pdfhummus") add_packages("freetype") - add_packages("s7") + add_packages("goldfish") add_packages("liii-tbox") add_packages("cpr") add_packages("argh") @@ -884,7 +884,7 @@ target("stem") do add_frameworks("QtGui", "QtWidgets", "QtCore", "QtPrintSupport", "QtSvg", "QtNetwork", "QtNetworkAuth") add_frameworks("QtQml", "QtQuick", "QtBodymovin") - add_packages("s7") + add_packages("goldfish") add_deps("liblolly") add_deps("libmogan") add_deps("libmoebius") diff --git a/xmake/goldfish.lua b/xmake/goldfish.lua index 446d833bfc..f216eb4e8b 100644 --- a/xmake/goldfish.lua +++ b/xmake/goldfish.lua @@ -1,12 +1,113 @@ ------------------------------------------------------------------------------- -- -- MODULE : goldfish.lua --- DESCRIPTION : goldfish scheme +-- DESCRIPTION : goldfish scheme (package + binary target) -- COPYRIGHT : (C) 2025 Darcy Shen -- -- This software falls under the GNU general public license version 3 or later. -- It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE -- in the root directory or . +-- + +-- goldfish 的 s7 源码内置在 TeXmacs/plugins/goldfish/src/,与下面 goldfish +-- binary target 内联编译的那一份完全相同。不使用 set_sourcedir() 直接指向 +-- 工作树(否则 package.tools.xmake 会把 port 出来的 xmake.lua 写进工作树, +-- 污染源码目录),而是在 on_install 里把源码拷贝到包缓存目录后构建。 +local goldfish_src = "$(projectdir)/TeXmacs/plugins/goldfish/src" + +package("goldfish") + set_homepage("https://github.com/goldfishscheme/goldfish") + set_description("Goldfish Scheme: a Scheme interpreter intended as an extension language for other applications.") + + add_deps("liii-tbox") + + on_load(function (package) + package:addenv("PATH", "bin") + package:add("deps", "argh") + end) + + on_install("bsd", "cross", "cygwin", "linux", "macosx", "mingw", "msys", "wasm", "windows", function (package) + -- 在包缓存目录中构建,保持工作树干净。先把内置的 s7 源码和我们的 + -- port/xmake.lua(定义了 libgoldfish 静态库 target)拷进缓存目录, + -- 再交给 package.tools.xmake 构建。这里必须由我们自己放置 xmake.lua, + -- 否则 xmake 会自动生成默认工程(把 s7.c 误当成二进制 target 链接, + -- 报缺少 _main)。 + -- {curdir = curdir} 告诉 package.tools.xmake 在该缓存目录下执行 + -- xmake f/build/install。 + local curdir = package:cachedir() + os.cp(path.join(goldfish_src, "*.c"), curdir) + os.cp(path.join(goldfish_src, "*.h"), curdir) + io.writefile(path.join(curdir, "xmake.lua"), [[ +add_rules("mode.release", "mode.debug") + +target("libgoldfish") do + set_kind("$(kind)") + set_languages("c11") + add_defines("WITH_SYSTEM_EXTRAS=0") + if not is_plat("wasm") then + add_defines("HAVE_OVERFLOW_CHECKS=0") + end + add_defines("WITH_WARNINGS") + add_defines("WITH_R7RS=1") + set_basename("goldfish") + add_files( + "s7.c", + "s7_continuation.c", + "s7_ctables.c", + "s7_dtoa.c", + "s7_module.c", + "s7_op_names.c", + "s7_scheme_base.c", + "s7_scheme_char.c", + "s7_scheme_complex.c", + "s7_scheme_format.c", + "s7_scheme_inexact.c", + "s7_scheme_predicate.c", + "s7_scheme_symbol.c", + "s7_scheme_write.c", + "s7_liii_bitwise.c", + "s7_liii_hash_table.c", + "s7_liii_list.c", + "s7_liii_string.c", + "s7_liii_vector.c" + ) + add_headerfiles("$(curdir)/s7.h") + add_includedirs(".", {public = true}) + if is_plat("windows") then + set_optimize("faster") + add_cxxflags("/fp:precise") + end + if is_mode("debug") then + add_defines("S7_DEBUGGING") + end + add_packages("liii-tbox") +end +]]) + local configs = {} + if package:config("shared") then + configs.kind = "shared" + end + import("package.tools.xmake").install(package, configs, {curdir = curdir}) + end) + + on_test(function (package) + assert(package:check_csnippets([[ + static s7_pointer old_add; /* the original "+" function for non-string cases */ + static s7_pointer old_string_append; /* same, for "string-append" */ + + static s7_pointer our_add(s7_scheme *sc, s7_pointer args) + { + /* this will replace the built-in "+" operator, extending it to include strings: + * (+ "hi" "ho") -> "hiho" and (+ 3 4) -> 7 + */ + if ((s7_is_pair(args)) && + (s7_is_string(s7_car(args)))) + return(s7_apply_function(sc, old_string_append, args)); + return(s7_apply_function(sc, old_add, args)); + } + ]], {includes = "s7.h"})) + end) +package_end() target ("goldfish") do set_languages("c++17") diff --git a/xmake/packages/s/s7/port/xmake.lua b/xmake/packages/s/s7/port/xmake.lua deleted file mode 100644 index 364e34a592..0000000000 --- a/xmake/packages/s/s7/port/xmake.lua +++ /dev/null @@ -1,78 +0,0 @@ ---! xmake.lua for s7 (libs7 target) --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- --- Copyright (C) 2023-present, TBOOX Open Source Group. --- --- @author jinkaimori, Darcy Shen --- @file s7_xmake.lua --- --- 本文件是 package.tools.xmake.install 使用的 port 构建脚本(见 --- xmake/packages/s/s7/xmake.lua)。它编译的 s7 源文件集合与 goldfish 目标内联编译 --- 的那份完全一致(见 xmake/goldfish.lua),从而保证 STEM/tests 通过 add_packages("s7") --- 用到的 s7 与 goldfish 二进制内嵌的 s7 完全相同。包脚本里的 on_install 会把源码拷进 --- 包缓存构建目录,因此本文件中 add_files 的相对路径(s7.c 等)会在该缓存目录下解析。 - -add_rules("mode.release", "mode.debug") - -option("gmp", {default = false, defines = "WITH_GMP"}) - -if has_config("gmp") then - add_requires("gmp") -end - -target("libs7") do - set_kind("$(kind)") - -- s7 源码使用 C11 特性,无条件设为 c11,与 xmake/goldfish.lua 编译同一批源码时 - -- 使用的 {languages = "c11"} 保持一致(原 3rdparty/s7 仅在 windows 下设置,这里统一)。 - set_languages("c11") - add_defines("WITH_SYSTEM_EXTRAS=0") - if not is_plat("wasm") then - add_defines("HAVE_OVERFLOW_CHECKS=0") - end - add_defines("WITH_WARNINGS") - add_defines("WITH_R7RS=1") - set_basename("s7") - add_files( - "s7.c", - "s7_continuation.c", - "s7_ctables.c", - "s7_dtoa.c", - "s7_module.c", - "s7_op_names.c", - "s7_scheme_base.c", - "s7_scheme_char.c", - "s7_scheme_complex.c", - "s7_scheme_format.c", - "s7_scheme_inexact.c", - "s7_scheme_predicate.c", - "s7_scheme_symbol.c", - "s7_scheme_write.c", - "s7_liii_bitwise.c", - "s7_liii_hash_table.c", - "s7_liii_list.c", - "s7_liii_string.c", - "s7_liii_vector.c" - ) - add_headerfiles("s7.h") - add_includedirs(".", {public = true}) - add_options("gmp") - if is_plat("windows") then - set_optimize("faster") - add_cxxflags("/fp:precise") - end - add_packages("gmp") - if is_mode("debug") then - add_defines("S7_DEBUGGING") - end -end diff --git a/xmake/packages/s/s7/xmake.lua b/xmake/packages/s/s7/xmake.lua deleted file mode 100644 index 622ca7250b..0000000000 --- a/xmake/packages/s/s7/xmake.lua +++ /dev/null @@ -1,58 +0,0 @@ -package("s7") - set_homepage("https://ccrma.stanford.edu/software/snd/snd/s7.html") - set_description("s7 is a Scheme interpreter intended as an extension language for other applications.") - - -- s7 的源码随 goldfish 插件内置在 TeXmacs/plugins/goldfish/src/,与 goldfish - -- 目标内联编译的那一份完全相同。这里不使用 set_sourcedir() 直接指向工作树 - -- (否则 package.tools.xmake 会把 port 出来的 xmake.lua 写进工作树,污染源码目录), - -- 而是在 on_install 里把源码拷贝到包缓存目录后再构建。 - local goldfish_s7_src = path.join(os.scriptdir(), "../../../../TeXmacs/plugins/goldfish/src") - - add_configs("gmp", {description = "enable gmp support", default = false, type = "boolean"}) - - on_load(function (package) - package:addenv("PATH", "bin") - if package:config("gmp") then - package:add("deps", "gmp") - end - end) - - if is_plat("linux") then - add_syslinks("pthread", "dl", "m") - end - - on_install("bsd", "cross", "cygwin", "linux", "macosx", "mingw", "msys", "wasm", "windows", function (package) - -- 在包缓存目录中构建,保持工作树干净。先把内置的 s7 源码和我们的 - -- port/xmake.lua(定义了包含完整源文件集合的 libs7 静态库 target)拷进缓存目录, - -- 再交给 package.tools.xmake 构建。这里必须由我们自己放置 xmake.lua,否则 xmake - -- 会自动生成默认工程(把 s7.c 误当成二进制 target 链接,报缺少 _main)。 - -- {curdir = curdir} 告诉 package.tools.xmake 在该缓存目录下执行 xmake f/build/install。 - local curdir = package:cachedir() - os.cp(path.join(goldfish_s7_src, "*.c"), curdir) - os.cp(path.join(goldfish_s7_src, "*.h"), curdir) - os.cp(path.join(os.scriptdir(), "port", "xmake.lua"), path.join(curdir, "xmake.lua")) - local configs = {} - if package:config("shared") then - configs.kind = "shared" - end - import("package.tools.xmake").install(package, configs, {curdir = curdir}) - end) - - on_test(function(package) - assert(package:check_csnippets([[ - static s7_pointer old_add; /* the original "+" function for non-string cases */ - static s7_pointer old_string_append; /* same, for "string-append" */ - - static s7_pointer our_add(s7_scheme *sc, s7_pointer args) - { - /* this will replace the built-in "+" operator, extending it to include strings: - * (+ "hi" "ho") -> "hiho" and (+ 3 4) -> 7 - */ - if ((s7_is_pair(args)) && - (s7_is_string(s7_car(args)))) - return(s7_apply_function(sc, old_string_append, args)); - return(s7_apply_function(sc, old_add, args)); - } - ]], {includes = "s7.h"})) - end) -package_end() diff --git a/xmake/tests.lua b/xmake/tests.lua index ca6810b6e3..de86d71805 100644 --- a/xmake/tests.lua +++ b/xmake/tests.lua @@ -29,7 +29,7 @@ function add_target_cpp_test(filepath, dep1, dep2) if not is_plat("windows") then add_syslinks("pthread") end - add_packages("s7") + add_packages("goldfish") add_packages("liii-pdfhummus") add_includedirs({"$(builddir)", "tests/Base"}) @@ -78,7 +78,7 @@ function add_target_cpp_bench(filepath, dep) if not is_plat("windows") then add_syslinks("pthread") end - add_packages("s7") + add_packages("goldfish") add_packages("liii-pdfhummus") add_includedirs({"$(builddir)", "tests/Base"})