diff --git a/3rdparty/lolly/xmake.lua b/3rdparty/lolly/xmake.lua index ab8f615f10..2a6c81aa89 100644 --- a/3rdparty/lolly/xmake.lua +++ b/3rdparty/lolly/xmake.lua @@ -17,11 +17,6 @@ if is_plat("mingw") and is_host("windows") then set_toolchains("mingw@mingw-w64") end -if is_plat("wasm") then - add_requires("emscripten 3.1.25") - set_toolchains("emcc@emscripten") -end - -- Options option("malloc") set_default("default") diff --git a/3rdparty/pdfhummus/xmake.lua b/3rdparty/pdfhummus/xmake.lua index a07744abfb..e171ac9023 100644 --- a/3rdparty/pdfhummus/xmake.lua +++ b/3rdparty/pdfhummus/xmake.lua @@ -13,14 +13,14 @@ end if has_config("libjpeg") then add_requires("libjpeg") end -add_requires("freetype", "zlib", "libaesgm") +add_requires("freetype", "zlib", "liii-libaesgm") target("pdfhummus") set_kind("$(kind)") add_files("PDFWriter/*.cpp") add_headerfiles("(PDFWriter/*.h)") add_packages("freetype") add_packages("libtiff", "libpng", "libjpeg") - add_packages("libaesgm", "zlib") + add_packages("liii-libaesgm", "zlib") if has_package("libtiff") then add_defines("_INCLUDE_TIFF_HEADER") add_cxflags("-Wno-deprecated-declarations") diff --git a/3rdparty/tbox/xmake.lua b/3rdparty/tbox/xmake.lua index bb6301a0fd..3ac880acbb 100644 --- a/3rdparty/tbox/xmake.lua +++ b/3rdparty/tbox/xmake.lua @@ -29,12 +29,6 @@ if has_config("coroutine") then add_cxflags("gcc::-Wno-error=dangling-pointer") end --- set wasm toolchain -if is_plat("wasm") then - add_requires("emscripten") - set_toolchains("emcc@emscripten") -end - -- add build modes add_rules("mode.release", "mode.debug", "mode.profile", "mode.coverage", "mode.valgrind", "mode.asan", "mode.tsan", "mode.ubsan") if is_mode("debug") then diff --git a/bin/wasm_server.py b/bin/wasm_server.py new file mode 100644 index 0000000000..638bf3bf9b --- /dev/null +++ b/bin/wasm_server.py @@ -0,0 +1,29 @@ +from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler +import sys +import os + +root = sys.argv[1] + +class Handler(SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=root, **kwargs) + + def end_headers(self): + self.send_header( + "Cross-Origin-Opener-Policy", + "same-origin" + ) + self.send_header( + "Cross-Origin-Embedder-Policy", + "require-corp" + ) + super().end_headers() + +server = ThreadingHTTPServer( + ("127.0.0.1", 8000), + Handler +) + +print("Serving on http://127.0.0.1:8000") + +server.serve_forever() \ No newline at end of file diff --git a/devel/700.md b/devel/700.md new file mode 100644 index 0000000000..62cb3ebf14 --- /dev/null +++ b/devel/700.md @@ -0,0 +1,19 @@ +# [700] WASM 构建脚本 +## What +调整 xmake 构建脚本适配 WASM 构建 + +## How to test +1. 配置 +``` +xmake f -c -p wasm -vD +``` +2. 构建 +``` +xmake b -vD stem +``` +3. 运行服务器 +``` +xmake r stem +``` +4. 运行 stem +浏览器访问 127.0.0.1:8000 diff --git a/xmake.lua b/xmake.lua index 9ca087bc6b..a7361c74ce 100644 --- a/xmake.lua +++ b/xmake.lua @@ -20,7 +20,10 @@ set_encodings("utf-8") add_requires("s7", {system=false}) add_requires("tbox", {system=false}) add_requires("cpr", {system=false}) +add_requires("zlib", {system=false}) + includes("xmake/goldfish.lua") +includes("xmake/toolchains/liii-emcc/xmake.lua") option("mupdf") set_default(true) @@ -46,7 +49,7 @@ option("is_community") set_description("Adjust community or commercial version") option_end() -local enable_tutorial = not has_config("is_community") +local enable_tutorial = not has_config("is_community") and not is_plat("wasm") option("tutorial") set_default(enable_tutorial) @@ -60,11 +63,19 @@ option_end() set_config("debug_with_timestamp", true) +if is_plat("wasm") then + set_configvar("OS_WASM", true) + add_requires("emscripten 3.1.56") + set_toolchains("liii-emcc@emscripten") +else + set_configvar("OS_WASM", false) +end + -- because this cpp project use variant length arrays which is not supported by -- msvc, this project will not support windows env. -- because some package is not ported to cygwin env, this project will not -- support cygwin env. -set_allowedplats("linux", "macosx", "windows") +set_allowedplats("linux", "macosx", "windows", "wasm") if is_plat("windows") then set_runtimes("MT") @@ -103,86 +114,7 @@ add_repositories("liii-repo xmake") TBOX_VERSION= "1.7.5" LOLLY_VERSION= "1.4.26" S7_VERSION = "20240816" - -package("liii-libaesgm") - set_homepage("https://github.com/xmake-mirror/libaesgm") - set_description("https://repology.org/project/libaesgm/packages") - - set_sourcedir(path.join(os.scriptdir(), "3rdparty/libaesgm")) - - on_install("linux", "macosx", "windows", "mingw", function (package) - if package:is_plat("windows", "mingw") and package:is_arch("arm", "arm64") then - -- Windows is always little endian - io.replace("brg_endian.h", [[ -#elif 0 /* **** EDIT HERE IF NECESSARY **** */ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN]], [[ -#elif 1 /* Edited: Windows ARM is little endian */ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN]], { plain = true }) - end - local configs = {} - if package:config("shared") then - configs.kind = "shared" - end - import("package.tools.xmake").install(package, configs) - end) - - on_test(function (package) - assert(package:has_cfuncs("aes_init", {includes = "aes.h"})) - end) -package_end() - PDFHUMMUS_VERSION = "4.6.2" -package("liii-pdfhummus") - set_homepage("https://www.pdfhummus.com/") - set_description("High performance library for creating, modiyfing and parsing PDF files in C++ ") - set_license("Apache-2.0") - - set_sourcedir(path.join(os.scriptdir(), "3rdparty/pdfhummus")) - - add_deps("zlib", "liii-libaesgm") - add_deps("freetype", {configs={png=true}}) - - add_configs("libtiff", {description = "Supporting tiff image", default = false, type = "boolean"}) - add_configs("libjpeg", {description = "Support DCT encoding", default = false, type = "boolean"}) - add_configs("libpng", {description = "Support png image", default = false, type = "boolean"}) - - if is_plat("linux") then - add_syslinks("m") - end - - on_load(function (package) - for _, dep in ipairs({"libtiff", "libpng", "libjpeg"}) do - if package:config(dep) then - package:add("deps", dep) - end - end - end) - on_install("linux", "windows", "mingw", "macosx", function (package) - local configs = {} - if package:config("shared") then - configs.kind = "shared" - end - for _, dep in ipairs({"libtiff", "libpng", "libjpeg"}) do - if package:config(dep) then - configs[dep] = true - end - end - import("package.tools.xmake").install(package, configs) - end) - - on_test(function (package) - assert(package:check_cxxsnippets({test = [[ - #include "PDFWriter/PDFWriter.h" - #include - using namespace std; - using namespace PDFHummus; - void test() { - PDFWriter pdfWriter; - pdfWriter.Reset(); - } - ]]}, {configs = {languages = "c++11"}})) - end) -package_end() includes("@builtin/check") configvar_check_cxxtypes("HAVE_INTPTR_T", "intptr_t", {includes = {"memory"}}) @@ -229,6 +161,10 @@ add_requires("argh v1.3.2") --- package: qt6widgets QT6_VERSION="6.8.3" add_requires("qt6widgets "..QT6_VERSION) +if is_plat("wasm") then + add_requires("qt6network "..QT6_VERSION) + add_requires("qt6svg "..QT6_VERSION) +end if has_config("mupdf") then if (linuxos.name() == "debian" and linuxos.version():major() >= CURRENT_DEBIAN_VERSION) or @@ -307,7 +243,7 @@ target("QWKCore") if is_plat("windows") then add_cxxflags("/Zc:__cplusplus", "/permissive-") add_syslinks("mpr", "userenv", "kernel32", "user32", "gdi32", "winspool", "shell32", "ole32", "oleaut32", "uuid", "comdlg32", "advapi32") - else + elseif not is_plat("wasm") then add_cxxflags("-fPIC", "-fvisibility=hidden", "-fvisibility-inlines-hidden") end add_packages("qt6base", "qt6core", "qt6gui", "qt6widgets") @@ -452,7 +388,7 @@ target("QWKCore") add_files("3rdparty/qwindowkitty/src/core/contexts/cocoawindowcontext_p.h") add_files("3rdparty/qwindowkitty/src/core/contexts/cocoawindowcontext.mm") end - if is_plat("linux") then + if is_plat("linux", "wasm") then add_files("3rdparty/qwindowkitty/src/core/contexts/qtwindowcontext_p.h") add_files("3rdparty/qwindowkitty/src/core/contexts/qtwindowcontext.cpp") end @@ -491,7 +427,7 @@ target("QWKWidgets") if is_plat("windows") then add_cxxflags("/Zc:__cplusplus", "/permissive-") - else + elseif not is_plat("wasm") then add_cxxflags("-fPIC", "-fvisibility=hidden", "-fvisibility-inlines-hidden") end add_deps("QWKCore") @@ -607,25 +543,40 @@ target("libmogan") do add_includedirs("3rdparty", {public = true}) set_policy("check.auto_ignore_flags", false) - add_rules("qt.static") on_install(function (target) print("No need to install libmogan") end) - add_frameworks("QtGui", "QtWidgets", "QtCore", "QtPrintSupport", "QtSvg", "QtNetwork", "QtNetworkAuth") + if is_plat("wasm") then + -- build static libmogan.a explicitly, otherwise it will generate libmogan.js + set_kind("static") + add_rules("qt.moc") + -- WASM build does not support frameworks + add_packages("qt6base", "qt6core", "qt6gui", "qt6widgets", "qt6network", "qt6svg") + else + add_rules("qt.static") + add_frameworks("QtGui", "QtWidgets", "QtCore", "QtPrintSupport", "QtSvg", "QtNetwork", "QtNetworkAuth") + end build_glue_on_config() set_configvar("QTTEXMACS", 1) add_defines("QTTEXMACS") set_configvar("QTPIPES", 1) add_defines("QTPIPES") - set_configvar("USE_QT_PRINTER", 1) - add_defines("USE_QT_PRINTER") + if not is_plat("wasm") then + set_configvar("USE_QT_PRINTER", 1) + add_defines("USE_QT_PRINTER") + end add_packages("lolly") add_packages("liii-pdfhummus") add_packages("freetype") add_packages("s7") add_packages("argh") + if is_plat("wasm") then + add_packages("tbox") + add_packages("cpr") + add_packages("zlib") + end if not is_plat("macosx") then add_packages("libiconv") end @@ -689,10 +640,18 @@ target("libmogan") do set_configvar("CONFIG_OS", "") end - configvar_check_cxxsnippets( - "CONFIG_LARGE_POINTER", [[ - #include - static_assert(sizeof(void*) == 8, "");]]) + if not is_plat("wasm") then + configvar_check_cxxsnippets( + "CONFIG_LARGE_POINTER", [[ + #include + static_assert(sizeof(void*) == 8, "");]]) + else + -- WASM use 32 bit pointers + configvar_check_cxxsnippets( + "CONFIG_LARGE_POINTER", [[ + #include + static_assert(sizeof(void*) == 4, "");]]) + end add_configfiles( "src/System/tm_configure.hpp.xmake", { filename = "tm_configure.hpp", @@ -815,6 +774,21 @@ target("libmogan") do add_files("src/Plugins/Qt/**.cpp", "src/Plugins/Qt/**.hpp") add_files("src/Mogan/Cache/**.cpp", "src/Mogan/Cache/**.hpp") add_files("src/Mogan/TemplateCenter/**.cpp", "src/Mogan/TemplateCenter/**.hpp") + if is_plat("wasm") then + -- QtPrinter does not support WASM + remove_files("src/Plugins/Qt/qt_printer_widget.cpp") + remove_files("src/Plugins/Qt/QTMPrintDialog.cpp") + remove_files("src/Plugins/Qt/QTMPrintDialog.hpp") + remove_files("src/Plugins/Qt/QTMPrinterSettings.cpp") + remove_files("src/Plugins/Qt/QTMPrinterSettings.hpp") + -- QTMPipeLink requires QProcess, which does not support WASM + remove_files("src/Plugins/Qt/qt_pipe_link.cpp") + remove_files("src/Plugins/Qt/QTMPipeLink.hpp") + remove_files("src/Plugins/Qt/QTMPipeLink.cpp") + remove_files("src/Plugins/Qt/QTMOAuth.cpp") + -- QtNetworkAuth does not support WASM + remove_files("src/Plugins/Qt/QTMOAuth.hpp") + end -- Add Qt resource file add_rules("qt.qrc") @@ -830,7 +804,7 @@ target("libmogan") do add_includedirs("src/Plugins/MacOS", {public = true}) add_files(plugin_macos_srcs) end - if is_plat("macosx", "linux", "windows") then + if is_plat("macosx", "linux", "windows", "wasm") then add_includedirs("src/Plugins/QWindowKit", {public = true}) add_files("src/Plugins/QWindowKit/**.cpp") add_files("src/Plugins/QWindowKit/**.hpp") @@ -896,6 +870,8 @@ target("stem") do set_filename(stem_binary_linux) elseif is_plat("macosx") then set_filename(stem_binary_macos) + elseif is_plat("wasm") then + set_filename(stem_binary_wasm) else set_filename(stem_binary_windows) end @@ -965,7 +941,19 @@ target("stem") do add_rules("qt.widgetapp") end - add_frameworks("QtGui", "QtWidgets", "QtCore", "QtPrintSupport", "QtSvg", "QtNetwork", "QtNetworkAuth") + add_frameworks("QtGui", "QtWidgets", "QtCore", "QtPrintSupport", "QtSvg", "QtNetwork") + if not is_plat("wasm") then + add_frameworks("QtNetworkAuth") + end + if is_plat("wasm") then + add_links("qwasm") + add_ldflags("-O3") -- 使用 Asyncify 时 -O3 优化很重要,否则产物体积会很大,此处 em++ 优化器可能会内存不足崩溃 + add_ldflags("-s INITIAL_MEMORY=64MB") + add_ldflags("-s ASYNCIFY=1") + add_ldflags("-s MODULARIZE=1", {force = true}) + add_ldflags("-s EXPORT_NAME=\"createQtAppInstance\"", {force = true}) + add_ldflags("--preload-file=" .. path.absolute("TeXmacs") .. "@/TeXmacs") + end add_packages("s7") add_packages("lolly") add_deps("libmogan") @@ -1074,6 +1062,12 @@ target("stem") do os.execv(binary, params, {envs={TEXMACS_PATH= path.join(os.projectdir(), "TeXmacs")}}) elseif is_plat("windows") then os.execv(binary, params) + elseif is_plat("wasm") then + local build_dir = path.absolute(path.directory(binary)) + os.execv("python3", { + path.join(os.projectdir(), "bin/wasm_server.py"), + build_dir + }) else print("Unsupported platform: " .. tostring(os.host())) end diff --git a/xmake/packages/c/cpr/xmake.lua b/xmake/packages/c/cpr/xmake.lua new file mode 100644 index 0000000000..d829ee3111 --- /dev/null +++ b/xmake/packages/c/cpr/xmake.lua @@ -0,0 +1,89 @@ +package("cpr") + set_homepage("https://docs.libcpr.org/") + set_description("C++ Requests is a simple wrapper around libcurl inspired by the excellent Python Requests project.") + set_license("MIT") + + set_urls("https://github.com/libcpr/cpr/archive/refs/tags/$(version).tar.gz", + "https://github.com/libcpr/cpr.git") + + add_versions("1.14.2", "b9b529b47083bfe80bba855ca5308d12d767ae7c7b629aef5ef018c4343cf62b") + add_versions("1.14.1", "213ccc7c98683d2ca6304d9760005effa12ec51d664bababf114566cb2b1e23c") + add_versions("1.12.0", "f64b501de66e163d6a278fbb6a95f395ee873b7a66c905dd785eae107266a709") + add_versions("1.11.2", "3795a3581109a9ba5e48fbb50f9efe3399a3ede22f2ab606b71059a615cd6084") + add_versions("1.11.1", "e84b8ef348f41072609f53aab05bdaab24bf5916c62d99651dfbeaf282a8e0a2") + add_versions("1.10.5", "c8590568996cea918d7cf7ec6845d954b9b95ab2c4980b365f582a665dea08d8") + add_versions("1.10.2", "044e98079032f7abf69c4c82f90ee2b4e4a7d2f28245498a5201ad6e8d0b1d08") + add_versions("1.10.3", "d7f2574bd9dae8adb0ce6cf1afab119b509c297fffcb4204a1bb3e4e731074f2") + add_versions("1.9.4", "2fbb27716c010d8a28e52d5bc8f108e0d073ca3b3f5a48a2696b0231ea5196d5") + add_versions("1.8.3", "0784d4c2dbb93a0d3009820b7858976424c56578ce23dcd89d06a1d0bf5fd8e2") + add_versions("1.7.2", "aa38a414fe2ffc49af13a08b6ab34df825fdd2e7a1213d032d835a779e14176f") + add_versions("1.6.2", "c45f9c55797380c6ba44060f0c73713fbd7989eeb1147aedb8723aa14f3afaa3") + + add_configs("ssl", {description = "Enable SSL.", default = false, type = "boolean"}) + + add_deps("cmake") + if is_plat("linux") then + add_syslinks("pthread") + end + add_links("cpr") + + if on_check then + on_check(function (package) + -- Require to fIX cmake try run + if package:version() and package:version():eq("1.6.2") then + if package:is_cross() then + raise("package(cpr 1.6.2) unsupported cross-compilation") + end + end + end) + end + + on_load(function (package) + if package:config("ssl") then + package:add("deps", "libcurl", {configs = {libssh2 = true, zlib = true}}) + package:add("deps", "libssh2") + else + package:add("deps", "libcurl") + end + end) + + on_install("!bsd", function (package) + io.replace("CMakeLists.txt", "-Werror", "", {plain = true}) + if package:is_plat("windows") or (package:is_plat("android") and is_subhost("windows")) then + -- fix find_package issue on windows + io.replace("CMakeLists.txt", "find_package%(CURL COMPONENTS .-%)", "find_package(CURL)") + end + + local configs = { + "-DCPR_BUILD_TESTS=OFF", + "-DCPR_FORCE_USE_SYSTEM_CURL=ON", + "-DCPR_USE_SYSTEM_CURL=ON", + } + table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release")) + table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF")) + table.insert(configs, "-DCPR_ENABLE_SSL=" .. (package:config("ssl") and "ON" or "OFF")) + + local opt = {} + opt.packagedeps = {"libcurl"} + if package:config("ssl") then + table.insert(opt.packagedeps, "libssh2") + end + if package:is_plat("windows") and package:has_tool("cxx", "cl", "clang_cl") then + opt.cxflags = {"/EHsc"} + end + if package:config("shared") and package:is_plat("macosx") then + opt.shflags = {"-framework", "CoreFoundation", "-framework", "Security", "-framework", "SystemConfiguration"} + end + import("package.tools.cmake").install(package, configs, opt) + end) + + on_test(function (package) + assert(package:check_cxxsnippets({test = [[ + #include + #include + static void test() { + cpr::Response r = cpr::Get(cpr::Url{"https://xmake.io"}); + assert(r.status_code == 200); + } + ]]}, {configs = {languages = "c++17"}})) + end) \ No newline at end of file diff --git a/xmake/packages/f/freetype/xmake.lua b/xmake/packages/f/freetype/xmake.lua index 5e91db6060..83b8322422 100644 --- a/xmake/packages/f/freetype/xmake.lua +++ b/xmake/packages/f/freetype/xmake.lua @@ -56,6 +56,12 @@ package("freetype") local configs = {"-DCMAKE_INSTALL_LIBDIR=lib"} table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release")) table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF")) + if package:is_plat("wasm") then + table.insert(configs, "-DCMAKE_C_FLAGS=-matomics -mbulk-memory -pthread") + table.insert(configs, "-DCMAKE_CXX_FLAGS=-matomics -mbulk-memory -pthread") + table.insert(configs, "-DCMAKE_EXE_LINKER_FLAGS=-matomics -mbulk-memory -pthread -sUSE_PTHREADS=1 -sSHARED_MEMORY=1") + table.insert(configs, "-DCMAKE_SHARED_LINKER_FLAGS=-matomics -mbulk-memory -pthread -sUSE_PTHREADS=1 -sSHARED_MEMORY=1") + end local function add_dep(opt) if package:config(opt.conf) then if package:version():ge("2.11.1") then diff --git a/xmake/packages/l/libcurl/xmake.lua b/xmake/packages/l/libcurl/xmake.lua index 91c5f6290b..b8fa9bc3d0 100644 --- a/xmake/packages/l/libcurl/xmake.lua +++ b/xmake/packages/l/libcurl/xmake.lua @@ -85,7 +85,7 @@ package("libcurl") end end) - on_install("windows", "mingw", "linux", "macosx", "iphoneos", "cross", "android", function (package) + on_install("windows", "mingw", "linux", "macosx", "iphoneos", "cross", "android", "wasm", function (package) local version = package:version() local configs = {"-DBUILD_TESTING=OFF", "-DENABLE_MANUAL=OFF", "-DENABLE_CURL_MANUAL=OFF"} diff --git a/xmake/packages/l/libpng/xmake.lua b/xmake/packages/l/libpng/xmake.lua new file mode 100644 index 0000000000..9b287575a0 --- /dev/null +++ b/xmake/packages/l/libpng/xmake.lua @@ -0,0 +1,92 @@ +package("libpng") + set_homepage("https://www.libpng.org/pub/png/libpng.html") + set_description("The official PNG reference library") + set_license("libpng-2.0") + + add_urls("https://github.com/glennrp/libpng/archive/refs/tags/$(version).tar.gz", + "https://github.com/glennrp/libpng.git") + + add_versions("v1.6.58", "a9d4df463d36a6e5f9c29bd6f4967312d17e996c1854f3511f833924eb1993cf") + add_versions("v1.6.57", "4cbb7b0746edc1683c9581b373365e955133b7f1243f171b7d1535b4415dfedb") + add_versions("v1.6.56", "41d74ffe235cb7e8bab40bcad2167f7bb25edbf2231dcfff57ccf4305dc0bfae") + add_versions("v1.6.55", "71a2c5b1218f60c4c6d2f1954c7eb20132156cae90bdb90b566c24db002782a6") + add_versions("v1.6.54", "ba7efce137409079989df4667706c339bebfbb10e9f413474718012a13c8cd4c") + add_versions("v1.6.53", "b20cee717e11416d2f96ccc7d184f63730ca8cb2f03bfd0c4ed77fbc909c0bff") + add_versions("v1.6.51", "b1872484c1c5c70acc79cbb15fb366df954fa8d5dacbe7f729d858902d17933c") + add_versions("v1.6.50", "71158e53cfdf2877bc99bcab33641d78df3f48e6e0daad030afe9cb8c031aa46") + add_versions("v1.6.49", "e425762fdfb9bb30a5d2da29c0067570e96b5d41d79c659cf0dad861e9df738e") + add_versions("v1.6.48", "b17e99026055727e8cba99160c3a9a7f9af788e9f786daeadded5a42243f1dd0") + add_versions("v1.6.47", "631a4c58ea6c10c81f160c4b21fa8495b715d251698ebc2552077e8450f30454") + add_versions("v1.6.46", "767b01936f9620d4ab4cdf6ec348f6526f861f825648b610b1d604167dc738d2") + add_versions("v1.6.44", "0ef5b633d0c65f780c4fced27ff832998e71478c13b45dfb6e94f23a82f64f7c") + add_versions("v1.6.43", "fecc95b46cf05e8e3fc8a414750e0ba5aad00d89e9fdf175e94ff041caf1a03a") + add_versions("v1.6.42", "fe89de292e223829859d21990d9c4d6b7e30e295a268f6a53a022611aa98bd67") + add_versions("v1.6.40", "62d25af25e636454b005c93cae51ddcd5383c40fa14aa3dae8f6576feb5692c2") + add_versions("v1.6.37", "ca74a0dace179a8422187671aee97dd3892b53e168627145271cad5b5ac81307") + add_versions("v1.6.36", "5bef5a850a9255365a2dc344671b7e9ef810de491bd479c2506ac3c337e2d84f") + add_versions("v1.6.35", "6d59d6a154ccbb772ec11772cb8f8beb0d382b61e7ccc62435bf7311c9f4b210") + add_versions("v1.6.34", "e45ce5f68b1d80e2cb9a2b601605b374bdf51e1798ef1c2c2bd62131dfcf9eef") + + if is_plat("wasm") then + add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = true}) + add_deps("zlib") + else + add_deps("zlib") + end + + if is_plat("linux") then + add_syslinks("m") + end + + if is_plat("mingw") and is_subhost("msys") then + add_extsources("pacman::libpng") + elseif is_plat("linux") then + add_extsources("pacman::libpng", "apt::libpng-dev") + elseif is_plat("macosx") then + add_extsources("brew::libpng") + end + + on_install(function (package) + if package:is_plat("android") and package:is_arch("armeabi-v7a") then + io.replace("arm/filter_neon.S", ".func", ".hidden", {plain = true}) + io.replace("arm/filter_neon.S", ".endfunc", "", {plain = true}) + end + os.cp("scripts/pnglibconf.h.prebuilt", "pnglibconf.h") + io.writefile("xmake.lua", [[ + add_rules("mode.debug", "mode.release") + add_requires("zlib") + target("png") + set_kind("$(kind)") + add_files("*.c|example.c|pngtest.c") + if is_arch("x86", "x64", "i386", "x86_64") then + add_files("intel/*.c") + add_defines("PNG_INTEL_SSE_OPT=1") + add_vectorexts("sse", "sse2") + elseif is_arch("arm.*") then + add_files("arm/*.c") + if is_plat("windows") then + add_defines("PNG_ARM_NEON_OPT=1") + add_defines("PNG_ARM_NEON_IMPLEMENTATION=1") + else + add_files("arm/*.S") + add_defines("PNG_ARM_NEON_OPT=2") + end + elseif is_arch("mips.*") then + add_files("mips/*.c") + add_defines("PNG_MIPS_MSA_OPT=2") + elseif is_arch("ppc.*") then + add_files("powerpc/*.c") + add_defines("PNG_POWERPC_VSX_OPT=2") + end + add_headerfiles("*.h") + add_packages("zlib") + if is_kind("shared") and is_plat("windows") then + add_defines("PNG_BUILD_DLL") + end + ]]) + import("package.tools.xmake").install(package) + end) + + on_test(function (package) + assert(package:has_cfuncs("png_create_read_struct", {includes = "png.h"})) + end) \ No newline at end of file diff --git a/xmake/packages/l/liii-libaesgm/xmake.lua b/xmake/packages/l/liii-libaesgm/xmake.lua new file mode 100644 index 0000000000..d7edc05762 --- /dev/null +++ b/xmake/packages/l/liii-libaesgm/xmake.lua @@ -0,0 +1,26 @@ +package("liii-libaesgm") + set_homepage("https://github.com/xmake-mirror/libaesgm") + set_description("https://repology.org/project/libaesgm/packages") + + set_sourcedir(path.join(os.scriptdir(), "../../../../3rdparty/libaesgm")) + + on_install("linux", "macosx", "windows", "mingw", "wasm", function (package) + if package:is_plat("windows", "mingw") and package:is_arch("arm", "arm64") then + -- Windows is always little endian + io.replace("brg_endian.h", [[ +#elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN]], [[ +#elif 1 /* Edited: Windows ARM is little endian */ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN]], { plain = true }) + end + local configs = {} + if package:config("shared") then + configs.kind = "shared" + end + import("package.tools.xmake").install(package, configs) + end) + + on_test(function (package) + assert(package:has_cfuncs("aes_init", {includes = "aes.h"})) + end) +package_end() \ No newline at end of file diff --git a/xmake/packages/l/liii-pdfhummus/xmake.lua b/xmake/packages/l/liii-pdfhummus/xmake.lua new file mode 100644 index 0000000000..642a497b0d --- /dev/null +++ b/xmake/packages/l/liii-pdfhummus/xmake.lua @@ -0,0 +1,54 @@ +package("liii-pdfhummus") + set_homepage("https://www.pdfhummus.com/") + set_description("High performance library for creating, modiyfing and parsing PDF files in C++ ") + set_license("Apache-2.0") + + set_sourcedir(path.join(os.scriptdir(), "../../../../3rdparty/pdfhummus")) + + add_deps("zlib", "liii-libaesgm") + add_deps("freetype", {configs={png=true}}) + + add_configs("libtiff", {description = "Supporting tiff image", default = false, type = "boolean"}) + add_configs("libjpeg", {description = "Support DCT encoding", default = false, type = "boolean"}) + add_configs("libpng", {description = "Support png image", default = false, type = "boolean"}) + + if is_plat("linux") then + add_syslinks("m") + end + + on_load(function (package) + for _, dep in ipairs({"libtiff", "libpng", "libjpeg"}) do + if package:config(dep) then + package:add("deps", dep) + end + end + if package:is_plat("wasm") then + package:add("dep", "zlib") + end + end) + on_install("linux", "windows", "mingw", "macosx", "wasm", function (package) + local configs = {} + if package:config("shared") then + configs.kind = "shared" + end + for _, dep in ipairs({"libtiff", "libpng", "libjpeg"}) do + if package:config(dep) then + configs[dep] = true + end + end + import("package.tools.xmake").install(package, configs) + end) + + on_test(function (package) + assert(package:check_cxxsnippets({test = [[ + #include "PDFWriter/PDFWriter.h" + #include + using namespace std; + using namespace PDFHummus; + void test() { + PDFWriter pdfWriter; + pdfWriter.Reset(); + } + ]]}, {configs = {languages = "c++11"}})) + end) +package_end() \ No newline at end of file diff --git a/xmake/packages/m/mupdf/xmake.lua b/xmake/packages/m/mupdf/xmake.lua index de092ffc61..2264d892db 100644 --- a/xmake/packages/m/mupdf/xmake.lua +++ b/xmake/packages/m/mupdf/xmake.lua @@ -27,26 +27,31 @@ package("mupdf") if is_plat("linux", "macosx") then add_deps("pkg-config", "make", "libjpeg", "freetype", "libcurl", "zlib") + elseif is_plat("wasm") then + add_deps("freetype", {configs={png=true}}) -- 保持与 liii-pdfhummus 一致,避免多次安装 + add_deps("pkg-config", "make", "libjpeg", "libcurl", "harfbuzz", "zlib") end on_load(function (package) if not is_plat("windows") then if is_plat("linux") then package:add("links", "mupdf", "mupdf-third", "harfbuzz") + elseif is_plat("wasm") then + package:add("links", "mupdf", "mupdf-third", "harfbuzz", "libjpeg", "freetype", "zlib") else package:add("links", "mupdf", "mupdf-third") end end end) - on_install("linux", "macosx", function (package) + on_install("linux", "macosx", "wasm", function (package) if is_plat("macosx") then io.writefile("user.make", "CFLAGS = -arch " .. package:targetarch()) -- Use pkg-config to detect system library io.replace("Makerules", "else ifeq ($(LINUX_OR_OPENBSD),yes)", "", {plain = true}) end -- Use system library from xmake to compat with other program - import("package.tools.make").build(package, { + local configs = { "install-libs", "USE_SYSTEM_LIBJPEG=yes", "USE_SYSTEM_FREETYPE=yes", @@ -55,7 +60,56 @@ package("mupdf") "tofu=yes", "tofu_cjk=yes", "prefix=" .. package:installdir() - }) + } + if not is_plat("wasm") then + import("package.tools.make").build(package, configs) + else + -- xmake seems not passing the right configs to mupdf's make + local cflags = {} + local ldflags = {} + local harfbuzz = package:dep("harfbuzz"):fetch() + local libjpeg = package:dep("libjpeg"):fetch() + local freetype = package:dep("freetype"):fetch() + local zlib = package:dep("zlib"):fetch() + local cc = package:tool("cc") + local cxx = package:tool("cxx") + local ld = package:tool("ld") + local ar = package:tool("ar") + local ranlib = package:tool("ranlib") + table.insert(configs, "CC=" .. cc) + table.insert(configs, "CXX=" .. cxx) + table.insert(configs, "LD=" .. ld) + table.insert(configs, "AR=" .. ar) + table.insert(configs, "RANLIB=" .. ranlib) + table.insert(configs, "USE_SYSTEM_HARFBUZZ=yes") + table.insert(cflags, "-matomics") + table.insert(cflags, "-mbulk-memory") + table.insert(cflags, "-pthread") + table.insert(ldflags, "-matomics") + table.insert(ldflags, "-mbulk-memory") + table.insert(ldflags, "-pthread") + table.insert(ldflags, "-sUSE_PTHREADS=1") + table.insert(ldflags, "-sSHARED_MEMORY=1") + table.insert(ldflags, "-DZ_PREFIX=OFF") + for _, pkg in ipairs({harfbuzz, libjpeg, freetype, zlib}) do + for _, dir in ipairs(pkg.sysincludedirs or {}) do + table.insert(cflags, "-I" .. dir) + end + for _, dir in ipairs(pkg.includedirs or {}) do + table.insert(cflags, "-I" .. dir) + end + for _, dir in ipairs(pkg.linkdirs or {}) do + table.insert(ldflags, "-L" .. dir) + end + end + os.execv("make verbose=yes", configs, { + envs = { + CFLAGS = table.concat(cflags, " "), + LDFLAGS = table.concat(ldflags, " ") + } + }) + os.execv("make", table.join({"install-libs"}, configs)) + end end) on_install("windows", function (package) diff --git a/xmake/packages/q/qt6core/xmake.lua b/xmake/packages/q/qt6core/xmake.lua new file mode 100644 index 0000000000..e49b0a0e26 --- /dev/null +++ b/xmake/packages/q/qt6core/xmake.lua @@ -0,0 +1,36 @@ +package("qt6core") + set_base("qt6lib") + set_kind("library") + + on_load(function (package) + if package:is_plat("wasm") then + package:add("deps", "pcre2", {configs = {bitwidth = "16"}}) + end + package:data_set("libname", "Core") + if package:is_plat("android") then + package:data_set("syslinks", "z") + elseif package:is_plat("iphoneos") then + package:data_set("frameworks", {"UIKit", "CoreText", "CoreGraphics", "CoreServices", "CoreFoundation"}) + package:data_set("syslinks", "z") + end + + package:base():script("load")(package) + end) + + on_test(function (package) + local cxflags + local ldflags + if package:is_plat("windows") then + cxflags = {"/Zc:__cplusplus", "/permissive-"} + elseif package:is_plat("wasm") then + ldflags = {"-lQt6BundledZLIB"} + else + cxflags = "-fPIC" + end + assert(package:check_cxxsnippets({test = [[ + int test(int argc, char** argv) { + QCoreApplication app (argc, argv); + return app.exec(); + } + ]]}, {configs = {languages = "c++17", cxflags = cxflags, ldflags = ldflags}, includes = {"QCoreApplication"}})) + end) \ No newline at end of file diff --git a/xmake/packages/q/qt6gui/xmake.lua b/xmake/packages/q/qt6gui/xmake.lua new file mode 100644 index 0000000000..171d7432f6 --- /dev/null +++ b/xmake/packages/q/qt6gui/xmake.lua @@ -0,0 +1,37 @@ +package("qt6gui") + set_base("qt6lib") + set_kind("library") + + on_load(function (package) + package:add("deps", "qt6core", {debug = package:is_debug(), version = package:version_str()}) + package:data_set("libname", "Gui") + + if package:is_plat("linux") then + package:add("deps", "freetype", "fontconfig", "libxkbcommon") + elseif package:is_plat("android") then + package:data_set("syslinks", "GLESv2") + elseif package:is_plat("iphoneos") then + package:data_set("links", "qtharfbuzz") + package:data_set("syslinks", {"qtlibpng", "z"}) + elseif package:is_plat("wasm") then + package:add("deps", "harfbuzz", "libpng") + package:data_set("links", "Qt6BundledZLIB") + end + + package:base():script("load")(package) + end) + + on_test(function (package) + local cxflags + if package:is_plat("windows") then + cxflags = {"/Zc:__cplusplus", "/permissive-"} + else + cxflags = "-fPIC" + end + assert(package:check_cxxsnippets({test = [[ + int test(int argc, char** argv) { + QGuiApplication app (argc, argv); + return app.exec(); + } + ]]}, {configs = {languages = "c++17", cxflags = cxflags}, includes = {"QGuiApplication"}})) + end) \ No newline at end of file diff --git a/xmake/packages/q/qt6lib/xmake.lua b/xmake/packages/q/qt6lib/xmake.lua index b20b2017d4..faabaac61c 100644 --- a/xmake/packages/q/qt6lib/xmake.lua +++ b/xmake/packages/q/qt6lib/xmake.lua @@ -82,18 +82,27 @@ package("qt6lib") end table.insert(links, 1, linkname) + if package:is_plat("wasm") then + table.insert(links, "qwasm") + table.insert(links, "embind") + end if frameworks then table.join2(frameworks, package:data("frameworks")) else frameworks = package:data("frameworks") end + local linkdirs = qt.libdir + if package:is_plat("wasm") then + linkdirs = {qt.libdir, path.join(qt.sdkdir, "plugins/platforms")} + end + return { qtdir = qt, version = qt.version, includedirs = includedirs, links = links, - linkdirs = qt.libdir, + linkdirs = linkdirs, frameworks = frameworks, frameworkdirs = qt.libdir, syslinks = package:data("syslinks") diff --git a/xmake/packages/q/qt6network/xmake.lua b/xmake/packages/q/qt6network/xmake.lua new file mode 100644 index 0000000000..3d6acacf61 --- /dev/null +++ b/xmake/packages/q/qt6network/xmake.lua @@ -0,0 +1,44 @@ +package("qt6network") + set_base("qt6lib") + set_kind("library") + + on_load(function (package) + package:add("deps", "qt6core", {debug = package:is_debug(), version = package:version_str()}) + package:data_set("libname", "Network") + + if package:is_plat("linux") then + -- we need system openssl with evp-kdf + -- @see https://github.com/xmake-io/xmake-repo/pull/1057#issuecomment-1069006866 + if linuxos.name() == "fedora" then + package:add("deps", "openssl", {system = true}) + else + package:add("deps", "openssl") + end + elseif package:is_plat("iphoneos") then + package:data_set("frameworks", {"GSS", "IOKit", "Security", "SystemConfiguration"}) + elseif package:is_plat("wasm") then + package:data_set("links", "Qt6BundledZLIB") + end + + package:base():script("load")(package) + end) + + on_test(function (package) + local cxflags + if package:is_plat("windows") then + cxflags = {"/Zc:__cplusplus", "/permissive-"} + else + cxflags = "-fPIC" + end + assert(package:check_cxxsnippets({test = [[ + int test(int argc, char** argv) { + QCoreApplication app(argc, argv); + + QByteArray datagram = "Hello from xmake!"; + QUdpSocket udpSocket; + udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, 45454); + + return app.exec(); + } + ]]}, {configs = {languages = "c++17", cxflags = cxflags}, includes = {"QCoreApplication", "QByteArray", "QUdpSocket"}})) + end) \ No newline at end of file diff --git a/xmake/packages/q/qt6svg/xmake.lua b/xmake/packages/q/qt6svg/xmake.lua new file mode 100644 index 0000000000..a77a659f8f --- /dev/null +++ b/xmake/packages/q/qt6svg/xmake.lua @@ -0,0 +1,35 @@ +package("qt6svg") + set_base("qt6lib") + set_kind("library") + + on_load(function (package) + -- qt6svg 依赖 core + gui + package:add("deps", "qt6core", {debug = package:is_debug(), version = package:version_str()}) + package:add("deps", "qt6gui", {debug = package:is_debug(), version = package:version_str()}) + + -- Qt module name + package:data_set("libname", "Svg") + + -- base loader(Qt6通用逻辑) + package:base():script("load")(package) + end) + + on_test(function (package) + assert(package:check_cxxsnippets({test = [[ + #include + #include + + int test() { + QSvgRenderer renderer(QString("test.svg")); + return renderer.isValid() ? 0 : 1; + } + ]]}, { + configs = { + languages = "c++17" + }, + includes = { + "QSvgRenderer", + "QPainter" + } + })) + end) \ No newline at end of file diff --git a/xmake/packages/q/qtbase/xmake.lua b/xmake/packages/q/qtbase/xmake.lua index cc4de3369a..a911c97869 100644 --- a/xmake/packages/q/qtbase/xmake.lua +++ b/xmake/packages/q/qtbase/xmake.lua @@ -299,7 +299,10 @@ package("qtbase") table.insert(aqt_args, "-m") table.insert(aqt_args, "qtimageformats") - table.insert(aqt_args, "qtnetworkauth") + if not is_plat("wasm") then + -- Seems Qt's official WASM build does not support this package + table.insert(aqt_args, "qtnetworkauth") + end os.vrunv("aqt", aqt_args) diff --git a/xmake/stem.lua b/xmake/stem.lua index 5c283e030f..49d737886d 100644 --- a/xmake/stem.lua +++ b/xmake/stem.lua @@ -17,6 +17,7 @@ stem_binary_linux = "moganstem" stem_dmg_bg_image = "mogan-background.png" stem_binary_macos = stem_binary_name stem_binary_windows = stem_binary_name .. ".exe" +stem_binary_wasm = "stem.js" stem_lab_name = "moganlab" stem_lab_big_name= "MoganLab" diff --git a/xmake/toolchains/liii-emcc/xmake.lua b/xmake/toolchains/liii-emcc/xmake.lua new file mode 100644 index 0000000000..5b084a1a2f --- /dev/null +++ b/xmake/toolchains/liii-emcc/xmake.lua @@ -0,0 +1,105 @@ +--!A cross-platform build utility based on Lua +-- +-- 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) 2015-present, Xmake Open Source Community. +-- +-- @author ruki +-- @file xmake.lua +-- + +toolchain("liii-emcc") + + set_homepage("http://emscripten.org") + set_description("A toolchain for compiling to asm.js and WebAssembly") + + set_kind("standalone") + + local suffix = is_host("windows") and ".bat" or "" + set_toolset("cc", "emcc" .. suffix) + set_toolset("cxx", "emcc" .. suffix, "em++" .. suffix) + set_toolset("ld", "em++" .. suffix, "emcc" .. suffix) + set_toolset("sh", "em++" .. suffix, "emcc" .. suffix) + set_toolset("ar", "emar" .. suffix) + set_toolset("as", "emcc" .. suffix) + set_toolset("ranlib", "emranlib" .. suffix) + + on_check(function (toolchain) + import("lib.detect.find_tool") + import("detect.sdks.find_emsdk") + local emsdk + for _, package in ipairs(toolchain:packages()) do + local installdir = package:installdir() + if installdir and os.isdir(installdir) then + emsdk = find_emsdk(installdir) + if emsdk then + break + end + end + end + if not emsdk then + emsdk = find_emsdk() + end + if emsdk then + toolchain:config_set("bindir", emsdk.emscripten) + toolchain:config_set("sdkdir", emsdk.sdkdir) + return emsdk + end + return find_tool("emcc") + end) + + on_load(function (toolchain) + if toolchain:is_arch("wasm64") then + toolchain:add("cxflags", "-sMEMORY64=1") + toolchain:add("asflags", "-sMEMORY64=1") + toolchain:add("ldflags", "-sMEMORY64=1") + toolchain:add("shflags", "-sMEMORY64=1") + else + toolchain:add("cxflags", "") + toolchain:add("asflags", "") + toolchain:add("ldflags", "") + toolchain:add("shflags", "") + end + for _, package in ipairs(toolchain:packages()) do + local envs = package:envs() + if envs then + for _, name in ipairs({"EMSDK", "EMSDK_NODE", "EMSDK_PYTHON", "JAVA_HOME"}) do + local values = envs[name] + if values then + toolchain:add("runenvs", name, table.unwrap(values)) + end + end + end + end + toolchain:add("cxflags", "-matomics", "-mbulk-memory", "-pthread") + toolchain:add("cflags", "-matomics", "-mbulk-memory", "-pthread") + toolchain:add("cxxflags", "-matomics", "-mbulk-memory", "-pthread") + toolchain:add("mxflags", "-matomics", "-mbulk-memory", "-pthread") + toolchain:add("ldflags", + "-matomics", + "-mbulk-memory", + "-pthread", + "-s USE_PTHREADS=1", + "-s SHARED_MEMORY=1", + "-s ALLOW_MEMORY_GROWTH=1", + "-s ENVIRONMENT=web,node", + opt + ) + toolchain:add("shflags", + "-matomics", + "-mbulk-memory", + "-pthread", + "-s USE_PTHREADS=1", + "-s SHARED_MEMORY=1" + ) + end) \ No newline at end of file