diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 337b488f..d22989fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ jobs: NDK_VERSION: "28.0.13004108" CMAKE_VERSION: "3.31.6" ANDROID_PLATFORM: "23" + RUST_VERSION: "1.92.0" steps: - name: Install build dependencies @@ -21,6 +22,7 @@ jobs: # sdkmanager needs jre # libime needs boost (build host tools) # opencc needs python (scripts) + # libchewing needs rustup (build) # libiconv needs gperf (build) run: | pacman -Syu --needed --noconfirm \ @@ -29,6 +31,7 @@ jobs: cmake extra-cmake-modules ninja \ boost \ python \ + rustup \ gperf - name: Fetch source code @@ -44,6 +47,8 @@ jobs: git config --global --add safe.directory '*' # fetch libime submodule kenlm since it's not in .gitmodules git submodule update --init --recursive libime + # fetch libchewing-data submodule + git submodule update --init --recursive libchewing - name: Setup Android NDK uses: android-actions/setup-android@v3 @@ -53,6 +58,7 @@ jobs: - name: Build everything env: ANDROID_NDK_ROOT: ${{ env.ANDROID_HOME }}/ndk/${{ env.NDK_VERSION }} + RUST_VERSION: ${{ env.RUST_VERSION }} run: | # use archlinux's dynamic only ghc cabal configure --disable-library-vanilla --enable-shared --enable-executable-dynamic --ghc-options=-dynamic diff --git a/libchewing b/libchewing index 9be48513..a6a8fa4a 160000 --- a/libchewing +++ b/libchewing @@ -1 +1 @@ -Subproject commit 9be48513bc46bafa134eef4b2bfde6a533470d33 +Subproject commit a6a8fa4abd3f215e3ba89a7b61702eaf8ca68f5c diff --git a/patches/libchewing.patch b/patches/libchewing.patch index cb719ae0..ca23a90d 100644 --- a/patches/libchewing.patch +++ b/patches/libchewing.patch @@ -1,50 +1,85 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index ae1d14b7..5d03df35 100644 +index 59e012d8..48dca4c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -1,2 +1,2 @@ --cmake_minimum_required(VERSION 3.24.0) -+cmake_minimum_required(VERSION 3.22.1) - project(libchewing LANGUAGES C) -@@ -216,8 +216,6 @@ if(WITH_RUST) - list(APPEND ALL_INC ${INC_DIR}/chewing_rs.h) - endif() - --add_subdirectory(doc) --add_subdirectory(data) +@@ -77,7 +77,7 @@ corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing_capi) if(BUILD_TESTING) - add_subdirectory(tests) + corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing_testhelper) endif() -@@ -228,14 +226,20 @@ add_library(common OBJECT +-corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing-cli) ++corrosion_add_target_rustflags(chewing_capi "--remap-path-prefix=${PROJECT_SOURCE_DIR}=.") - src/porting_layer/src/asprintf.c - ) -+target_compile_options(common PRIVATE -+ "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=." -+) - target_compile_definitions(common PRIVATE -- CHEWING_DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}/libchewing\" -+ CHEWING_DATADIR=\"./libchewing\" + if(WITH_SQLITE3) + corrosion_set_features(chewing_capi FEATURES sqlite) +@@ -191,7 +191,7 @@ target_include_directories(libchewing ) - add_library(libchewing ${ALL_INC} src/chewing.c) - set_target_properties(libchewing PROPERTIES LINKER_LANGUAGE C) -+target_compile_options(libchewing PRIVATE -+ "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=." -+) - target_compile_definitions(libchewing PRIVATE -- CHEWING_DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}/libchewing\" -+ CHEWING_DATADIR=\"./libchewing\" + corrosion_set_env_vars(chewing_capi +- CHEWING_DATADIR=${CMAKE_INSTALL_FULL_DATADIR}/libchewing ++ CHEWING_DATADIR="./libchewing" ) - if(NOT WITH_RUST) - target_sources(common PRIVATE -@@ -288,6 +292,9 @@ if(NOT WITH_RUST) - ${SRC_DIR}/userphrase-hash.c - ) - endif() -+ target_compile_options(userphrase PRIVATE -+ "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=." -+ ) - target_link_libraries(libchewing - PRIVATE common - PRIVATE userphrase) + target_link_libraries(libchewing PRIVATE chewing_capi) + target_link_libraries(chewing_capi INTERFACE ${SQLite3_LIBRARIES}) +@@ -239,15 +239,17 @@ else() + ) + endif() + +-install(FILES ${ALL_INC} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/chewing) ++install(FILES ${ALL_INC} DESTINATION include/chewing) + install(FILES ${PROJECT_BINARY_DIR}/chewing.pc +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +-install(TARGETS libchewing ++ DESTINATION lib/pkgconfig) ++install(TARGETS chewing_capi + EXPORT libchewingTargets +- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +- INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ++ ARCHIVE DESTINATION lib ++ INCLUDES DESTINATION include ++ LIBRARY DESTINATION lib ++ RUNTIME DESTINATION bin) ++install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libchewing_capi.a ++ DESTINATION lib) + + if(BUILD_DATA) + install( +@@ -261,7 +263,6 @@ if(BUILD_DATA) + ) + endif() + +-install(IMPORTED_RUNTIME_ARTIFACTS chewing-cli DESTINATION ${CMAKE_INSTALL_BINDIR}) + + # generate CMake Config files + include(CMakePackageConfigHelpers) +diff --git a/Cargo.toml b/Cargo.toml +index d546d772..448f6b1d 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -41,10 +41,10 @@ tempfile = "3.10.1" + + [profile.release] + lto = true +-opt-level = 3 ++opt-level = "s" + panic = "abort" + codegen-units = 1 +-debug = true ++debug = false + + [package.metadata.docs.rs] + features = ["sqlite"] +diff --git a/capi/Cargo.toml b/capi/Cargo.toml +index 517dd9e2..12fefb9e 100644 +--- a/capi/Cargo.toml ++++ b/capi/Cargo.toml +@@ -7,7 +7,7 @@ rust-version = "1.88" + edition = "2024" + + [lib] +-crate-type = ["rlib", "staticlib"] ++crate-type = ["staticlib"] + + [dependencies] + chewing = { version = "0.11.0", path = ".." } diff --git a/src/Main.hs b/src/Main.hs index a8223b96..3034a0e3 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -177,7 +177,8 @@ data ToolchainVersions = ToolchainVersions { prebuilderRev :: String, ndkVersion :: String, platformVersion :: Int, - cmakeVersion :: String + cmakeVersion :: String, + rustVersion :: String } instance A.ToJSON ToolchainVersions where @@ -186,7 +187,8 @@ instance A.ToJSON ToolchainVersions where [ fromString "prebuilder" A..= prebuilderRev, fromString "ndk" A..= ndkVersion, fromString "platform" A..= platformVersion, - fromString "cmake" A..= cmakeVersion + fromString "cmake" A..= cmakeVersion, + fromString "rust" A..= rustVersion ] getToolchainVersions :: Action ToolchainVersions @@ -200,4 +202,5 @@ getToolchainVersions = do pure $ dropWhileEnd (== ' ') ndkVersion | otherwise -> fail "Failed to parse Pkg.Revision" Nothing -> fail "Pkg.Revision not found in source.properties" + rustVersion <- fromMaybeM (fail "RUST_VERSION not set") (getEnv "RUST_VERSION") pure ToolchainVersions {..} diff --git a/src/Rules/LibChewing.hs b/src/Rules/LibChewing.hs index 53216704..cb206bb5 100644 --- a/src/Rules/LibChewing.hs +++ b/src/Rules/LibChewing.hs @@ -23,23 +23,34 @@ libchewingRule = do useCMake $ (cmakeBuilder "libchewing") { preBuild = BuildAction $ \_ src -> do - -- CMakeLists is changed in last build + -- install rust toolchain + cmd_ Shell "rustup toolchain install $RUST_VERSION" + -- CMakeLists.txt changed in last build cmd_ (Cwd src) Shell "git checkout ." - -- skip data and shared lib - -- merge libuserphrase.a into libchewing.a - -- remove absolute path by CHEWING_DATADIR macro - -- remove absolute path by __FILE__ macro + -- disable data/doc, remove absolute path, optimize library size cmd_ (Cwd src) "git apply ../patches/libchewing.patch", - cmakeFlags = - const - [ "-DBUILD_SHARED_LIBS=OFF", - "-DBUILD_TESTING=OFF", - "-DWITH_SQLITE3=OFF", - "-DWITH_RUST=OFF" - ] + preBuildEachABI = BuildActionABI $ \_ env -> do + -- install rust target for this abi + let targetName = case (buildEnvABI env) of + "armeabi-v7a" -> "armv7-linux-androideabi" + "arm64-v8a" -> "aarch64-linux-android" + "x86" -> "i686-linux-android" + "x86_64" -> "x86_64-linux-android" + _ -> fail "Unknown Android ABI" + cmd_ "rustup" "target" "add" targetName, + cmakeFlags = + const + [ "-DBUILD_SHARED_LIBS=OFF", + "-DBUILD_TESTING=OFF", + "-DBUILD_DATA=OFF", + "-DBUILD_DOC=OFF", + "-DWITH_SQLITE3=OFF" + ] } "chewing-dict" ~> do + -- install rust + cmd_ Shell "rustup toolchain install $RUST_VERSION" let libchewingBuildHost = outputDir "libchewing-build-host" dictSrcDir = libchewingBuildHost "data" cmd_ (Cwd libchewingSrc) Shell "git checkout ." @@ -49,10 +60,9 @@ libchewingRule = do libchewingBuildHost "-G" "Ninja" - [ "-DBUILD_SHARED_LIBS=OFF", - "-DBUILD_TESTING=OFF", + [ "-DBUILD_TESTING=OFF", "-DWITH_SQLITE3=OFF", - "-DWITH_RUST=OFF" + "-DBUILD_DOC=OFF" ] libchewingSrc cmd_ @@ -60,14 +70,13 @@ libchewingRule = do "--build" libchewingBuildHost "--target" - [ "data", - "all_static_data" + [ "dict_chewing", + "misc" ] - copyFile' (dictSrcDir "dictionary.dat") (dictOutputDir "dictionary.dat") - copyFile' (dictSrcDir "index_tree.dat") (dictOutputDir "index_tree.dat") - copyFile' (dictSrcDir "pinyin.tab") (dictOutputDir "pinyin.tab") - copyFile' (dictSrcDir "swkb.dat") (dictOutputDir "swkb.dat") - copyFile' (dictSrcDir "symbols.dat") (dictOutputDir "symbols.dat") + copyFile' (dictSrcDir "dict" "chewing" "tsi.dat") (dictOutputDir "tsi.dat") + copyFile' (dictSrcDir "dict" "chewing" "word.dat") (dictOutputDir "word.dat") + copyFile' (dictSrcDir "misc" "swkb.dat") (dictOutputDir "swkb.dat") + copyFile' (dictSrcDir "misc" "symbols.dat") (dictOutputDir "symbols.dat") "libchewing" ~> do need ["chewing-dict"]