diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcf40fd8..da2d5a46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,137 +1,142 @@ -name: CI - -on: - push: - branches: - - "master" - - "release/*" - pull_request: - branches: - - "master" - - "release/*" - merge_group: - types: [checks_requested] - -env: - RUST_VERSION: "1.77" - CMAKE_GENERATOR: Ninja - -jobs: - build: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - preset: - - rust-release - - rust-with-sqlite-release - runs-on: ${{ matrix.os }} - name: ${{ matrix.os }}, preset=${{ matrix.preset }} - - steps: - - uses: actions/checkout@v4 - - - if: ${{ matrix.os == 'ubuntu-latest' }} - run: sudo apt-get install ninja-build - - if: ${{ matrix.os == 'macos-latest' }} - run: brew install ninja - - if: ${{ matrix.os == 'windows-latest' }} - run: choco install ninja - - if: ${{ matrix.os == 'windows-latest' }} - uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 - - - name: Setup rustup - run: | - rustup default ${{ env.RUST_VERSION }} - rustup update - - - name: Build - run: | - cmake --preset ${{ matrix.preset }} - cmake --build build - cmake --install build --prefix install - - - name: Test - run: | - ctest --test-dir build --output-on-failure - - aarch64-smoke: - runs-on: ubuntu-latest - name: Aarch64 cross-compile smoke test - - steps: - - uses: actions/checkout@v4 - - name: Setup rustup - run: | - rustup default ${{ env.RUST_VERSION }} - rustup target add aarch64-unknown-linux-gnu - rustup update - - - name: Build - run: | - cargo build --target=aarch64-unknown-linux-gnu - cargo build -p chewing_capi --target=aarch64-unknown-linux-gnu - - coverage: - strategy: - matrix: - preset: - - rust-coverage - - rust-with-sqlite-coverage - runs-on: ubuntu-latest - container: fedora:latest - name: Coverage preset=${{ matrix.preset }} - - steps: - - run: sudo dnf -y install clang cmake ninja-build sqlite-devel llvm rustup bzip2 git - - - uses: actions/checkout@v4 - - - name: Setup rustup - run: | - rustup-init -y - source "$HOME/.cargo/env" - rustup component add llvm-tools - - - name: Setup grcov - run: | - curl -LO https://github.com/mozilla/grcov/releases/download/v0.8.19/grcov-x86_64-unknown-linux-gnu.tar.bz2 - echo 098be4d60b8016913542d58456fea6e771890096d1bf86e7f83dac650ba4b58a grcov-x86_64-unknown-linux-gnu.tar.bz2 | sha256sum -c - - tar xf grcov-x86_64-unknown-linux-gnu.tar.bz2 - - - name: Build - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: -Cinstrument-coverage -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off - run: | - source "$HOME/.cargo/env" - cmake --preset ${{ matrix.preset }} - cmake --build build - - - name: Test - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: -Cinstrument-coverage -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off - run: | - source "$HOME/.cargo/env" - ctest --test-dir build --output-on-failure - ./grcov . -s . -b . --keep-only 'src/*' --keep-only 'capi/src/*' --llvm -t lcov -o coverage.lcov - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - # https://github.com/orgs/community/discussions/26822 - results: - if: ${{ always() }} - runs-on: ubuntu-latest - name: Final Results - needs: [build, aarch64-smoke] - steps: - - run: exit 1 - # see https://stackoverflow.com/a/67532120/4907315 - if: >- - ${{ - contains(needs.*.result, 'failure') - || contains(needs.*.result, 'cancelled') - }} +name: CI + +on: + push: + branches: + - "master" + - "release/*" + pull_request: + branches: + - "master" + - "release/*" + merge_group: + types: [checks_requested] + +env: + RUST_VERSION: "1.77" + CMAKE_GENERATOR: Ninja + +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + preset: + - rust-release + - rust-with-sqlite-release + runs-on: ${{ matrix.os }} + name: ${{ matrix.os }}, preset=${{ matrix.preset }} + + steps: + - uses: actions/checkout@v4 + + - if: ${{ matrix.os == 'ubuntu-latest' }} + run: sudo apt-get install ninja-build + - if: ${{ matrix.os == 'macos-latest' }} + run: brew install ninja + - if: ${{ matrix.os == 'windows-latest' }} + run: | + choco install ninja + echo VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT >> $env:GITHUB_ENV + echo CMAKE_TOOLCHAIN_FILE=$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake >> $env:GITHUB_ENV + echo VCPKGRS_TRIPLET=x64-windows-static >> $env:GITHUB_ENV + $env:VCPKG_INSTALLATION_ROOT\vcpkg install --triplet x64-windows-static + - if: ${{ matrix.os == 'windows-latest' }} + uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 + + - name: Setup rustup + run: | + rustup default ${{ env.RUST_VERSION }} + rustup update + + - name: Build + run: | + cmake --preset ${{ matrix.preset }} -DVCPKG_TARGET_TRIPLET=${{ env.VCPKGRS_TRIPLET }} + cmake --build build + cmake --install build --prefix install + + - name: Test + run: | + ctest --test-dir build --output-on-failure + + aarch64-smoke: + runs-on: ubuntu-latest + name: Aarch64 cross-compile smoke test + + steps: + - uses: actions/checkout@v4 + - name: Setup rustup + run: | + rustup default ${{ env.RUST_VERSION }} + rustup target add aarch64-unknown-linux-gnu + rustup update + + - name: Build + run: | + cargo build --target=aarch64-unknown-linux-gnu + cargo build -p chewing_capi --target=aarch64-unknown-linux-gnu + + coverage: + strategy: + matrix: + preset: + - rust-coverage + - rust-with-sqlite-coverage + runs-on: ubuntu-latest + container: fedora:latest + name: Coverage preset=${{ matrix.preset }} + + steps: + - run: sudo dnf -y install clang cmake ninja-build sqlite-devel llvm rustup bzip2 git + + - uses: actions/checkout@v4 + + - name: Setup rustup + run: | + rustup-init -y + source "$HOME/.cargo/env" + rustup component add llvm-tools + + - name: Setup grcov + run: | + curl -LO https://github.com/mozilla/grcov/releases/download/v0.8.19/grcov-x86_64-unknown-linux-gnu.tar.bz2 + echo 098be4d60b8016913542d58456fea6e771890096d1bf86e7f83dac650ba4b58a grcov-x86_64-unknown-linux-gnu.tar.bz2 | sha256sum -c - + tar xf grcov-x86_64-unknown-linux-gnu.tar.bz2 + + - name: Build + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: -Cinstrument-coverage -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off + run: | + source "$HOME/.cargo/env" + cmake --preset ${{ matrix.preset }} + cmake --build build + + - name: Test + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: -Cinstrument-coverage -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off + run: | + source "$HOME/.cargo/env" + ctest --test-dir build --output-on-failure + ./grcov . -s . -b . --keep-only 'src/*' --keep-only 'capi/src/*' --llvm -t lcov -o coverage.lcov + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + # https://github.com/orgs/community/discussions/26822 + results: + if: ${{ always() }} + runs-on: ubuntu-latest + name: Final Results + needs: [build, aarch64-smoke] + steps: + - run: exit 1 + # see https://stackoverflow.com/a/67532120/4907315 + if: >- + ${{ + contains(needs.*.result, 'failure') + || contains(needs.*.result, 'cancelled') + }} diff --git a/CMakeLists.txt b/CMakeLists.txt index daaad08b..f6477ce9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,296 +1,267 @@ -cmake_minimum_required(VERSION 3.24.0) -project(libchewing LANGUAGES C) - -set(CMAKE_PROJECT_VERSION 0.9.0) - -find_package(Git) -if(Git_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} --work-tree ${CMAKE_SOURCE_DIR} describe --dirty --always - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE GIT_DESCRIBE - ERROR_VARIABLE GIT_DESCRIBE_ERROR - ) - if(NOT GIT_DESCRIBE_ERROR) - string(REPLACE "v" "" CMAKE_PROJECT_VERSION ${GIT_DESCRIBE}) - endif() -endif() - -set(LIBCHEWING_VERSION ${CMAKE_PROJECT_VERSION}) -set(PACKAGE_VERSION ${CMAKE_PROJECT_VERSION}) -set(LIBCHEWING_BINARY_VERSION 1.0.0) -set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) - -include(CTest) -set(CTEST_PARALLEL_LEVEL 1) - -if(UNIX) - set(CMAKE_C_FLAGS "-g -O2 -Wall -fPIC ${CMAKE_C_FLAGS}") - add_compile_definitions(UNDER_POSIX PIC) -endif() - -if(MSVC) - set(CMAKE_C_FLAGS "/utf-8 ${CMAKE_C_FLAGS}") -endif() - -include(CheckCCompilerFlag) -include(FetchContent) - -option(BUILD_SHARED_LIBS "Build using shared libraries" ON) - -if(CMAKE_C_COMPILER_ID MATCHES GNU|Clang) - set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}") - add_compile_definitions(_GNU_SOURCE) - option(ENABLE_GCOV "Coverage support" false) - if(ENABLE_GCOV) - if(CMAKE_C_COMPILER_ID MATCHES Clang) - set(CMAKE_C_FLAGS "-fprofile-instr-generate -fcoverage-mapping ${CMAKE_C_FLAGS}") - else() - set(CMAKE_C_FLAGS "--coverage ${CMAKE_C_FLAGS}") - endif() - endif() -endif() - -add_compile_definitions(HAVE_CONFIG_H=1) -add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) - -option(WITH_SQLITE3 "Use sqlite3 to store userphrase" true) - -# Use valgrind when testing -option(USE_VALGRIND "Use valgrind when testing" true) - -find_package(Corrosion QUIET) -if(NOT Corrosion_FOUND) - FetchContent_Declare( - Corrosion - GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git - GIT_TAG 64289b1d79d6d19cd2e241db515381a086bb8407 # v0.5 - FIND_PACKAGE_ARGS - ) - FetchContent_MakeAvailable(Corrosion) -endif() - -corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing_capi) -corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing_testhelper) -corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing-cli) - -if(WITH_SQLITE3) - corrosion_set_features(chewing_capi FEATURES sqlite) - corrosion_set_features(chewing_testhelper FEATURES sqlite) -endif() - -if(ENABLE_GCOV) - corrosion_set_env_vars(chewing_capi CARGO_INCREMENTAL=0) - corrosion_add_target_local_rustflags(chewing_capi -Cinstrument-coverage -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Cpanic=abort) -endif() - -if(CMAKE_SYSTEM MATCHES "Windows") - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") - corrosion_add_target_rustflags(chewing_capi -Ctarget-feature=+crt-static) - corrosion_add_target_rustflags(chewing_testhelper -Ctarget-feature=+crt-static) - corrosion_add_target_rustflags(chewing-cli -Ctarget-feature=+crt-static) -endif() - -# Feature probe -include(CheckTypeSize) -check_type_size(uint16_t UINT16_T) - -set(CURSES_NEED_WIDE true) -find_package(Curses) - -if(WITH_SQLITE3) - find_package(SQLite3 QUIET) - if(SQLite3_FOUND) - message(STATUS "Found SQLite3 version ${SQLite3_VERSION}") - include_directories(SQLite3_INCLUDE_DIRS) - else() - message(STATUS "Fetching SQLite3 source from internet") - FetchContent_Declare( - SQLite3 - URL https://www.sqlite.org/2024/sqlite-amalgamation-3460000.zip - URL_HASH SHA3_256=1221eed70de626871912bfca144c00411f0c30d3c2b7935cff3963b63370ef7c - ) - FetchContent_MakeAvailable(SQLite3) - - include_directories(${sqlite3_SOURCE_DIR}) - add_library(sqlite3_library STATIC - ${sqlite3_SOURCE_DIR}/sqlite3.c - ${sqlite3_SOURCE_DIR}/sqlite3.h - ) - find_package(Threads) - target_link_libraries(sqlite3_library PUBLIC ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) - set(SQLite3_LIBRARIES sqlite3_library) - - add_executable(sqlite3 - ${sqlite3_SOURCE_DIR}/shell.c - ) - target_link_libraries(sqlite3 PRIVATE ${SQLite3_LIBRARIES}) - set_target_properties(sqlite3 PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${sqlite3_BINARY_DIR} - RUNTIME_OUTPUT_DIRECTORY_DEBUG ${sqlite3_BINARY_DIR} - RUNTIME_OUTPUT_DIRECTORY_RELEASE ${sqlite3_BINARY_DIR} - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${sqlite3_BINARY_DIR} - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${sqlite3_BINARY_DIR} - ) - endif() -endif() - -include(CheckFunctionExists) -check_function_exists(asprintf HAVE_ASPRINTF) - -include(CheckIncludeFiles) -check_include_files(unistd.h HAVE_UNISTD_H) -check_include_files(stdint.h HAVE_STDINT_H) - -set(SRC_DIR ${PROJECT_SOURCE_DIR}/src) -set(INC_DIR ${PROJECT_SOURCE_DIR}/include) -set(TOOLS_SRC_DIR ${PROJECT_SOURCE_DIR}/src/tools) -set(TOOLS_BIN_DIR ${PROJECT_BINARY_DIR}/src/tools) -set(DATA_SRC_DIR ${PROJECT_SOURCE_DIR}/data) -set(DATA_BIN_DIR ${PROJECT_BINARY_DIR}/data) -set(TEST_SRC_DIR ${PROJECT_SOURCE_DIR}/tests) -set(TEST_BIN_DIR ${PROJECT_BINARY_DIR}/tests) - -include(GNUInstallDirs) - -configure_file( - ${PROJECT_SOURCE_DIR}/cmake/config.h.in - ${PROJECT_BINARY_DIR}/include/config.h -) - -configure_file( - ${PROJECT_SOURCE_DIR}/cmake/version.texi.in - ${PROJECT_BINARY_DIR}/doc/version.texi -) - -set(prefix "${CMAKE_INSTALL_PREFIX}") -set(exec_prefix "\${prefix}") -set(libdir "\${exec_prefix}/lib") -set(includedir "\${prefix}/include") -set(datarootdir "\${prefix}/share") -set(datadir "\${datarootdir}") -set(sysconfdir "\${prefix}/etc") -configure_file( - ${PROJECT_SOURCE_DIR}/chewing.pc.in - ${PROJECT_BINARY_DIR}/chewing.pc - @ONLY -) - -include_directories( - ${PROJECT_BINARY_DIR}/include - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR}/src/porting_layer/include -) - -set(ALL_INC - ${INC_DIR}/chewing.h - - # 0.5.x compatibility headers - ${INC_DIR}/chewing-compat.h - ${INC_DIR}/chewingio.h - ${INC_DIR}/global.h - ${INC_DIR}/mod_aux.h -) - -add_subdirectory(doc) -add_subdirectory(data) -if(BUILD_TESTING) - add_subdirectory(tests) -endif() - -add_library(libchewing ${ALL_INC} capi/src/chewing.c) -set_target_properties(libchewing PROPERTIES LINKER_LANGUAGE C) -target_compile_definitions(libchewing PRIVATE - CHEWING_DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}/libchewing\" -) -target_include_directories(libchewing - PUBLIC - $ - $ -) - -corrosion_set_env_vars(chewing_capi - CHEWING_DATADIR=${CMAKE_INSTALL_FULL_DATADIR}/libchewing -) -target_link_libraries(libchewing PRIVATE chewing_capi) -target_link_libraries(chewing_capi INTERFACE ${SQLite3_LIBRARIES}) -if(BUILD_SHARED_LIBS) - if(CMAKE_C_COMPILER_ID MATCHES GNU|^Clang) - target_link_options(libchewing - PRIVATE LINKER:-version-script,${PROJECT_SOURCE_DIR}/capi/src/symbols-elf.map - PRIVATE LINKER:--gc-sections - PRIVATE LINKER:-u,chewing_new - PRIVATE LINKER:-u,chewing_version - ) - set_target_properties(libchewing PROPERTIES - LINK_DEPENDS ${PROJECT_SOURCE_DIR}/capi/src/symbols-elf.map - ) - elseif(CMAKE_C_COMPILER_ID MATCHES AppleClang) - target_link_options(libchewing - PRIVATE LINKER:-exported_symbols_list,${PROJECT_SOURCE_DIR}/capi/src/symbols-mach_o.map - PRIVATE LINKER:-dead_strip - ) - set_target_properties(libchewing PROPERTIES - LINK_DEPENDS ${PROJECT_SOURCE_DIR}/capi/src/symbols-mach_o.map - ) - elseif(MSVC) - target_link_options(libchewing - PRIVATE /DEF:${PROJECT_SOURCE_DIR}/capi/src/symbols-msvc.def - PRIVATE /NODEFAULTLIB:MSVCRT - PRIVATE /NODEFAULTLIB:MSVCRTD - ) - set_target_properties(libchewing PROPERTIES - LINK_DEPENDS ${PROJECT_SOURCE_DIR}/capi/src/symbols-msvc.def - ) - endif() -endif() - -if(MSVC) - set_target_properties(libchewing PROPERTIES - OUTPUT_NAME chewing-msvc - ) -else() - set_target_properties(libchewing PROPERTIES - OUTPUT_NAME chewing - SOVERSION 3 - VERSION 3.3.1 - ) -endif() - -install(FILES ${ALL_INC} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/chewing) -install(FILES ${PROJECT_BINARY_DIR}/chewing.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) -install(TARGETS libchewing - EXPORT libchewingTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(IMPORTED_RUNTIME_ARTIFACTS chewing-cli DESTINATION ${CMAKE_INSTALL_BINDIR}) - -# generate CMake Config files -include(CMakePackageConfigHelpers) -set(CONFIG_PACKAGE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/Chewing") -configure_package_config_file(ChewingConfig.cmake.in - "${CMAKE_CURRENT_BINARY_DIR}/ChewingConfig.cmake" - INSTALL_DESTINATION ${CONFIG_PACKAGE_DIR}) -write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/ChewingConfigVersion.cmake" - VERSION ${LIBCHEWING_VERSION} - COMPATIBILITY SameMajorVersion) -export(EXPORT libchewingTargets - NAMESPACE Chewing:: - FILE "${CMAKE_CURRENT_BINARY_DIR}/ChewingTargets.cmake") -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ChewingConfig.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/ChewingConfigVersion.cmake" - DESTINATION ${CONFIG_PACKAGE_DIR}) -install(EXPORT libchewingTargets - FILE ChewingTargets.cmake - NAMESPACE Chewing:: - DESTINATION ${CONFIG_PACKAGE_DIR}) - -set(CPACK_PACKAGE_CHECKSUM SHA256) -set(CPACK_PACKAGE_VERSION ${CMAKE_PROJECT_VERSION}) -set(CPACK_SOURCE_IGNORE_FILES "/build" "/out" "/target" "/\\\\..*") -set(CPACK_SOURCE_GENERATOR TZST) -set(CPACK_SOURCE_PACKAGE_FILE_NAME libchewing-${CMAKE_PROJECT_VERSION}) -include(CPack) +cmake_minimum_required(VERSION 3.24.0) +project(libchewing LANGUAGES C) + +set(CMAKE_PROJECT_VERSION 0.9.0) + +find_package(Git) +if(Git_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} --work-tree ${CMAKE_SOURCE_DIR} describe --dirty --always + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE GIT_DESCRIBE + ERROR_VARIABLE GIT_DESCRIBE_ERROR + ) + if(NOT GIT_DESCRIBE_ERROR) + string(REPLACE "v" "" CMAKE_PROJECT_VERSION ${GIT_DESCRIBE}) + endif() +endif() + +set(LIBCHEWING_VERSION ${CMAKE_PROJECT_VERSION}) +set(PACKAGE_VERSION ${CMAKE_PROJECT_VERSION}) +set(LIBCHEWING_BINARY_VERSION 1.0.0) +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +include(CTest) +set(CTEST_PARALLEL_LEVEL 1) + +if(UNIX) + set(CMAKE_C_FLAGS "-g -O2 -Wall -fPIC ${CMAKE_C_FLAGS}") + add_compile_definitions(UNDER_POSIX PIC) +endif() + +if(MSVC) + set(CMAKE_C_FLAGS "/utf-8 ${CMAKE_C_FLAGS}") +endif() + +include(CheckCCompilerFlag) +include(FetchContent) + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +if(CMAKE_C_COMPILER_ID MATCHES GNU|Clang) + set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}") + add_compile_definitions(_GNU_SOURCE) + option(ENABLE_GCOV "Coverage support" false) + if(ENABLE_GCOV) + if(CMAKE_C_COMPILER_ID MATCHES Clang) + set(CMAKE_C_FLAGS "-fprofile-instr-generate -fcoverage-mapping ${CMAKE_C_FLAGS}") + else() + set(CMAKE_C_FLAGS "--coverage ${CMAKE_C_FLAGS}") + endif() + endif() +endif() + +add_compile_definitions(HAVE_CONFIG_H=1) +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) + +option(WITH_SQLITE3 "Use sqlite3 to store userphrase" true) + +# Use valgrind when testing +option(USE_VALGRIND "Use valgrind when testing" true) + +find_package(Corrosion QUIET) +if(NOT Corrosion_FOUND) + FetchContent_Declare( + Corrosion + GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git + GIT_TAG 64289b1d79d6d19cd2e241db515381a086bb8407 # v0.5 + FIND_PACKAGE_ARGS + ) + FetchContent_MakeAvailable(Corrosion) +endif() + +corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing_capi) +corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing_testhelper) +corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES chewing-cli) + +if(WITH_SQLITE3) + corrosion_set_features(chewing_capi FEATURES sqlite) + corrosion_set_features(chewing_testhelper FEATURES sqlite) +endif() + +if(ENABLE_GCOV) + corrosion_set_env_vars(chewing_capi CARGO_INCREMENTAL=0) + corrosion_add_target_local_rustflags(chewing_capi -Cinstrument-coverage -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Cpanic=abort) +endif() + +if(CMAKE_SYSTEM MATCHES "Windows") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") + corrosion_add_target_rustflags(chewing_capi -Ctarget-feature=+crt-static) + corrosion_add_target_rustflags(chewing_testhelper -Ctarget-feature=+crt-static) + corrosion_add_target_rustflags(chewing-cli -Ctarget-feature=+crt-static) +endif() + +# Feature probe +include(CheckTypeSize) +check_type_size(uint16_t UINT16_T) + +set(CURSES_NEED_WIDE true) +find_package(Curses) + +if(WITH_SQLITE3) + find_package(SQLite3 REQUIRED) + if(SQLite3_FOUND) + message(STATUS "Found SQLite3 version ${SQLite3_VERSION}") + include_directories(SQLite3_INCLUDE_DIRS) + endif() +endif() + +include(CheckFunctionExists) +check_function_exists(asprintf HAVE_ASPRINTF) + +include(CheckIncludeFiles) +check_include_files(unistd.h HAVE_UNISTD_H) +check_include_files(stdint.h HAVE_STDINT_H) + +set(SRC_DIR ${PROJECT_SOURCE_DIR}/src) +set(INC_DIR ${PROJECT_SOURCE_DIR}/include) +set(TOOLS_SRC_DIR ${PROJECT_SOURCE_DIR}/src/tools) +set(TOOLS_BIN_DIR ${PROJECT_BINARY_DIR}/src/tools) +set(DATA_SRC_DIR ${PROJECT_SOURCE_DIR}/data) +set(DATA_BIN_DIR ${PROJECT_BINARY_DIR}/data) +set(TEST_SRC_DIR ${PROJECT_SOURCE_DIR}/tests) +set(TEST_BIN_DIR ${PROJECT_BINARY_DIR}/tests) + +include(GNUInstallDirs) + +configure_file( + ${PROJECT_SOURCE_DIR}/cmake/config.h.in + ${PROJECT_BINARY_DIR}/include/config.h +) + +configure_file( + ${PROJECT_SOURCE_DIR}/cmake/version.texi.in + ${PROJECT_BINARY_DIR}/doc/version.texi +) + +set(prefix "${CMAKE_INSTALL_PREFIX}") +set(exec_prefix "\${prefix}") +set(libdir "\${exec_prefix}/lib") +set(includedir "\${prefix}/include") +set(datarootdir "\${prefix}/share") +set(datadir "\${datarootdir}") +set(sysconfdir "\${prefix}/etc") +configure_file( + ${PROJECT_SOURCE_DIR}/chewing.pc.in + ${PROJECT_BINARY_DIR}/chewing.pc + @ONLY +) + +include_directories( + ${PROJECT_BINARY_DIR}/include + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/src/porting_layer/include +) + +set(ALL_INC + ${INC_DIR}/chewing.h + + # 0.5.x compatibility headers + ${INC_DIR}/chewing-compat.h + ${INC_DIR}/chewingio.h + ${INC_DIR}/global.h + ${INC_DIR}/mod_aux.h +) + +add_subdirectory(doc) +add_subdirectory(data) +if(BUILD_TESTING) + add_subdirectory(tests) +endif() + +add_library(libchewing ${ALL_INC} capi/src/chewing.c) +set_target_properties(libchewing PROPERTIES LINKER_LANGUAGE C) +target_compile_definitions(libchewing PRIVATE + CHEWING_DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}/libchewing\" +) +target_include_directories(libchewing + PUBLIC + $ + $ +) + +corrosion_set_env_vars(chewing_capi + CHEWING_DATADIR=${CMAKE_INSTALL_FULL_DATADIR}/libchewing +) +target_link_libraries(libchewing PRIVATE chewing_capi) +target_link_libraries(chewing_capi INTERFACE ${SQLite3_LIBRARIES}) +if(BUILD_SHARED_LIBS) + if(CMAKE_C_COMPILER_ID MATCHES GNU|^Clang) + target_link_options(libchewing + PRIVATE LINKER:-version-script,${PROJECT_SOURCE_DIR}/capi/src/symbols-elf.map + PRIVATE LINKER:--gc-sections + PRIVATE LINKER:-u,chewing_new + PRIVATE LINKER:-u,chewing_version + ) + set_target_properties(libchewing PROPERTIES + LINK_DEPENDS ${PROJECT_SOURCE_DIR}/capi/src/symbols-elf.map + ) + elseif(CMAKE_C_COMPILER_ID MATCHES AppleClang) + target_link_options(libchewing + PRIVATE LINKER:-exported_symbols_list,${PROJECT_SOURCE_DIR}/capi/src/symbols-mach_o.map + PRIVATE LINKER:-dead_strip + ) + set_target_properties(libchewing PROPERTIES + LINK_DEPENDS ${PROJECT_SOURCE_DIR}/capi/src/symbols-mach_o.map + ) + elseif(MSVC) + target_link_options(libchewing + PRIVATE /DEF:${PROJECT_SOURCE_DIR}/capi/src/symbols-msvc.def + PRIVATE /NODEFAULTLIB:MSVCRT + PRIVATE /NODEFAULTLIB:MSVCRTD + ) + set_target_properties(libchewing PROPERTIES + LINK_DEPENDS ${PROJECT_SOURCE_DIR}/capi/src/symbols-msvc.def + ) + endif() +endif() + +if(MSVC) + set_target_properties(libchewing PROPERTIES + OUTPUT_NAME chewing-msvc + ) +else() + set_target_properties(libchewing PROPERTIES + OUTPUT_NAME chewing + SOVERSION 3 + VERSION 3.3.1 + ) +endif() + +install(FILES ${ALL_INC} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/chewing) +install(FILES ${PROJECT_BINARY_DIR}/chewing.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(TARGETS libchewing + EXPORT libchewingTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(IMPORTED_RUNTIME_ARTIFACTS chewing-cli DESTINATION ${CMAKE_INSTALL_BINDIR}) + +# generate CMake Config files +include(CMakePackageConfigHelpers) +set(CONFIG_PACKAGE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/Chewing") +configure_package_config_file(ChewingConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/ChewingConfig.cmake" + INSTALL_DESTINATION ${CONFIG_PACKAGE_DIR}) +write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/ChewingConfigVersion.cmake" + VERSION ${LIBCHEWING_VERSION} + COMPATIBILITY SameMajorVersion) +export(EXPORT libchewingTargets + NAMESPACE Chewing:: + FILE "${CMAKE_CURRENT_BINARY_DIR}/ChewingTargets.cmake") +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ChewingConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/ChewingConfigVersion.cmake" + DESTINATION ${CONFIG_PACKAGE_DIR}) +install(EXPORT libchewingTargets + FILE ChewingTargets.cmake + NAMESPACE Chewing:: + DESTINATION ${CONFIG_PACKAGE_DIR}) + +set(CPACK_PACKAGE_CHECKSUM SHA256) +set(CPACK_PACKAGE_VERSION ${CMAKE_PROJECT_VERSION}) +set(CPACK_SOURCE_IGNORE_FILES "/build" "/out" "/target" "/\\\\..*") +set(CPACK_SOURCE_GENERATOR TZST) +set(CPACK_SOURCE_PACKAGE_FILE_NAME libchewing-${CMAKE_PROJECT_VERSION}) +include(CPack) diff --git a/Cargo.lock b/Cargo.lock index c269f1c4..747a025f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "bitflags" @@ -75,12 +75,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "cc" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549" - [[package]] name = "cfg-if" version = "1.0.0" @@ -127,9 +121,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -137,9 +131,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -254,9 +248,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fuzzer" @@ -311,9 +305,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libredox" @@ -331,7 +325,6 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ - "cc", "pkg-config", "vcpkg", ] @@ -377,18 +370,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -417,9 +410,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags", "errno", @@ -442,9 +435,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.72" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -486,9 +479,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "utf8parse" diff --git a/Cargo.toml b/Cargo.toml index bb4f7e73..8a7d4b42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,9 +23,6 @@ directories = "5.0.0" log = { workspace = true } rusqlite = { version = ">= 0.28.0", optional = true } -[target.'cfg(windows)'.dependencies] -rusqlite = { version = ">= 0.28.0", features = ["bundled"], optional = true } - [dev-dependencies] tempfile = { workspace = true }