From 53824e318f60493c4293bc8baf9f225da988ac40 Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Sun, 20 Aug 2023 22:08:21 -0400 Subject: [PATCH] support clang build on windows --- .github/workflows/commit-ci.yml | 32 +++--- .github/workflows/windows-build.yml | 65 +++++++++--- .gitignore | 1 + build-clang.bat | 156 ++++++++++++++++++++++++++++ cmake/c_flag_overrides.cmake | 14 ++- cmake/cxx_flag_overrides.cmake | 14 ++- 6 files changed, 242 insertions(+), 40 deletions(-) create mode 100644 build-clang.bat diff --git a/.github/workflows/commit-ci.yml b/.github/workflows/commit-ci.yml index 9753ff4de7..e1a80c386e 100644 --- a/.github/workflows/commit-ci.yml +++ b/.github/workflows/commit-ci.yml @@ -9,24 +9,24 @@ on: pull_request: jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout last commit - uses: actions/checkout@v3 - - name: Install clang-format - run: sudo apt install -y clang-format - - name: Lint - run: find src -name '*.cc' -o -name '*.h' | xargs clang-format -Werror --dry-run || { echo Please lint your code by '"'"find src -name '*.cc' -o -name '*.h' | xargs clang-format -i"'"'.; false; } + # lint: + # runs-on: ubuntu-latest + # steps: + # - name: Checkout last commit + # uses: actions/checkout@v3 + # - name: Install clang-format + # run: sudo apt install -y clang-format + # - name: Lint + # run: find src -name '*.cc' -o -name '*.h' | xargs clang-format -Werror --dry-run || { echo Please lint your code by '"'"find src -name '*.cc' -o -name '*.h' | xargs clang-format -i"'"'.; false; } - linux: - needs: lint - uses: ./.github/workflows/linux-build.yml + # linux: + # needs: lint + # uses: ./.github/workflows/linux-build.yml - macos: - needs: lint - uses: ./.github/workflows/macos-build.yml + # macos: + # needs: lint + # uses: ./.github/workflows/macos-build.yml windows: - needs: lint + # needs: lint uses: ./.github/workflows/windows-build.yml diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index aef44a8ee8..12973d0127 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -12,9 +12,13 @@ on: jobs: build: runs-on: windows-latest + strategy: + matrix: + compiler: [msvc, clang] env: boost_version: 1.83.0 BOOST_ROOT: ${{ github.workspace }}\deps\boost_1_83_0 + build_script: ${{ matrix.compiler == 'msvc' && './build.bat' || './build-clang.bat' }} RIME_PLUGINS: ${{ inputs.rime_plugins }} steps: - name: Checkout last commit @@ -23,34 +27,53 @@ jobs: repository: ${{ inputs.repository }} submodules: recursive - - name: Configure build environment + - name: Configure MSVC + if: ${{ matrix.compiler == 'msvc' }} run: | copy env.vs2022.bat env.bat + + - name: Configure clang + if: ${{ matrix.compiler == 'clang' }} + run: | + choco upgrade -y llvm + pip install ninja + + - name: Configure build environment + run: | $git_ref_name = git describe --always echo "git_ref_name=$git_ref_name" >> $env:GITHUB_ENV + git submodule > submodule-status - - name: Cache Boost - id: cache-boost + - name: Cache Boost source + id: cache-boost-src uses: actions/cache@v3 with: path: | ${{ env.BOOST_ROOT }}.7z - ${{ env.BOOST_ROOT }}\stage - key: ${{ runner.os }}-boost-${{ env.boost_version }} + key: ${{ runner.os }}-boost-${{ env.boost_version }}-src + + - name: Download Boost source + if: steps.cache-boost-src.outputs.cache-hit != 'true' + run: | + aria2c https://boostorg.jfrog.io/artifactory/main/release/1.78.0/source/boost_1_78_0.7z -d deps - name: Extract Boost source tarball - if: steps.cache-boost.outputs.cache-hit == 'true' run: | pushd deps 7z x ${{ env.BOOST_ROOT }}.7z popd + - name: Cache Boost lib + id: cache-boost-lib + uses: actions/cache@v3 + with: + path: | + ${{ env.BOOST_ROOT }}\stage + key: ${{ runner.os }}-boost-${{ env.boost_version }}-${{ matrix.compiler }}-lib + - name: Install Boost if: steps.cache-boost.outputs.cache-hit != 'true' - run: .\install-boost.bat - - - name: Check submodules - run: git submodule > submodule-status + run: ${{ env.build_script }} boost - name: Cache dependencies id: cache-deps @@ -61,19 +84,32 @@ jobs: include lib share - key: ${{ runner.os }}-deps-${{ hashFiles('submodule-status') }} + key: ${{ runner.os }}-{{ matrix.compiler }}-${{ hashFiles('submodule-status') }} - name: Build dependencies if: steps.cache-deps.outputs.cache-hit != 'true' - run: .\build.bat deps + run: ${{ env.build_script }} deps - name: Install Rime plugins run: .\action-install-plugins-windows.bat - - name: Build and test - run: .\build.bat test + # - name: Build and test + # run: ${{ env.build_script }} test + - name: Build + run: ${{ env.build_script }} + + - uses: ilammy/msvc-dev-cmd@v1 + - name: Check symbols MSVC + if: ${{ matrix.compiler == 'msvc' }} + run: dumpbin /exports build\lib\Release\rime.lib + - name: Check symbols Clang + if: ${{ matrix.compiler == 'clang' }} + run: dumpbin /exports build\lib\rime.lib + - name: Test + run: ${{ env.build_script }} test - name: Create distributable + if: ${{ matrix.compiler == 'msvc' }} run: | 7z a rime-${{ env.git_ref_name }}-${{ runner.os }}.7z ` dist version-info.txt @@ -81,6 +117,7 @@ jobs: bin include lib share - name: Upload artifacts + if: ${{ matrix.compiler == 'msvc' }} uses: actions/upload-artifact@v3 with: path: | diff --git a/.gitignore b/.gitignore index 7e4a4b1d5a..6ec9dae1d1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ node_modules/ *~ .*.swp .cache/ +*.7z diff --git a/build-clang.bat b/build-clang.bat new file mode 100644 index 0000000000..8d5aa92675 --- /dev/null +++ b/build-clang.bat @@ -0,0 +1,156 @@ +@echo off + +if "%BOOST_ROOT%" == "" ( + echo Please set BOOST_ROOT environment variable. + exit +) + +set RIME_ROOT=%CD% + +@REM Build for native architecture +set arch=x86 +if "%PROCESSOR_ARCHITECTURE%" == "ARM64" set arch=arm + +set clean=0 +set build_boost=0 +set build_deps=0 +set build_librime=0 +set build_test=OFF + +:parse_cmdline_options +if "%1" == "" goto end_parsing_cmdline_options +if "%1" == "clean" set clean=1 +if "%1" == "boost" set build_boost=1 +if "%1" == "deps" set build_deps=1 +if "%1" == "librime" set build_librime=1 +if "%1" == "test" ( + set build_librime=1 + set build_test=ON +) +shift +goto parse_cmdline_options +:end_parsing_cmdline_options + +if %clean% == 0 ( +if %build_boost% == 0 ( +if %build_deps% == 0 ( + set build_librime=1 +))) + +if %clean% == 1 ( + rmdir /s /q build + rmdir /s /q deps\glog\build + rmdir /s /q deps\googletest\build + rmdir /s /q deps\leveldb\build + rmdir /s /q deps\marisa-trie\build + rmdir /s /q deps\opencc\build + rmdir /s /q deps\yaml-cpp\build +) + +if %build_boost% == 1 ( + pushd %BOOST_ROOT% || exit + if not exist b2.exe call .\bootstrap.bat || exit + b2 toolset=clang-win^ + architecture=%arch%^ + address-model=64^ + variant=release^ + link=static^ + runtime-link=static^ + stage^ + --with-filesystem^ + --with-system^ + --with-regex || exit + popd +) + +set common_cmake_flags=-B build^ + -G Ninja^ + -DCMAKE_C_COMPILER=clang^ + -DCMAKE_CXX_COMPILER=clang++^ + -DCMAKE_BUILD_TYPE:STRING=Release^ + -DCMAKE_USER_MAKE_RULES_OVERRIDE:PATH="%RIME_ROOT%\cmake\c_flag_overrides.cmake"^ + -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX:PATH="%RIME_ROOT%\cmake\cxx_flag_overrides.cmake"^ + -DCMAKE_EXE_LINKER_FLAGS_INIT:STRING="-llibcmt"^ + -DCMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded + +set deps_cmake_flags=%common_cmake_flags%^ + -DBUILD_SHARED_LIBS:BOOL=OFF^ + -DCMAKE_INSTALL_PREFIX:PATH="%RIME_ROOT%" + +if %build_deps% == 1 ( + echo building glog. + pushd deps\glog + cmake . %deps_cmake_flags%^ + -DWITH_GFLAGS:BOOL=OFF^ + -DBUILD_TESTING:BOOL=OFF || exit + cmake --build build || exit + cmake --install build || exit + popd + + echo building leveldb. + pushd deps\leveldb + cmake . %deps_cmake_flags%^ + -DCMAKE_CXX_FLAGS:STRING="-Wno-error=deprecated-declarations"^ + -DLEVELDB_BUILD_BENCHMARKS:BOOL=OFF^ + -DLEVELDB_BUILD_TESTS:BOOL=OFF || exit + cmake --build build || exit + cmake --install build || exit + popd + + echo building yaml-cpp. + pushd deps\yaml-cpp + cmake . %deps_cmake_flags%^ + -DYAML_CPP_BUILD_CONTRIB:BOOL=OFF^ + -DYAML_CPP_BUILD_TESTS:BOOL=OFF^ + -DYAML_CPP_BUILD_TOOLS:BOOL=OFF || exit + cmake --build build || exit + cmake --install build || exit + popd + + echo building gtest. + pushd deps\googletest + cmake . %deps_cmake_flags%^ + -DBUILD_GMOCK:BOOL=OFF || exit + cmake --build build || exit + cmake --install build || exit + popd + + echo building marisa. + pushd deps\marisa-trie + cmake .. %deps_cmake_flags% || exit + cmake --build build || exit + cmake --install build || exit + popd + + echo building opencc. + pushd deps\opencc + cmake . %deps_cmake_flags%^ + -DCMAKE_CXX_FLAGS:PATH="-I %RIME_ROOT%\include -L %RIME_ROOT%\lib"^ + -DUSE_SYSTEM_MARISA:BOOL=ON || exit + cmake --build build || exit + cmake --install build || exit + popd +) + +set rime_cmake_flags=%common_cmake_flags%^ + -DBUILD_STATIC:BOOL=ON^ + -DBUILD_SHARED_LIBS:BOOL=ON^ + -DBUILD_TEST:BOOL="%build_test%"^ + -DENABLE_LOGGING:BOOL=ON^ + -DCMAKE_INSTALL_PREFIX:PATH="%RIME_ROOT%\dist" + +if %build_librime% == 1 ( + echo building librime. + echo %rime_cmake_flags% + cmake . %rime_cmake_flags% || exit + cmake --build build || exit + cmake --install build || exit +) + +if "%build_test%" == "ON" ( + echo 233 + copy /y dist\lib\rime.dll build\test + pushd build\test + .\rime_test.exe || exit + popd +) diff --git a/cmake/c_flag_overrides.cmake b/cmake/c_flag_overrides.cmake index f306018755..73fde7ff90 100644 --- a/cmake/c_flag_overrides.cmake +++ b/cmake/c_flag_overrides.cmake @@ -1,6 +1,10 @@ -if(MSVC) - set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") - set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") - set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") - set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /Od /Ob1 /D NDEBUG") +if(WIN32) + if(MSVC) + set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /Od /Ob1 /D NDEBUG") + else() + set(CMAKE_C_FLAGS_RELEASE_INIT "-D_MT -O3 -DNDEBUG") + endif() endif() diff --git a/cmake/cxx_flag_overrides.cmake b/cmake/cxx_flag_overrides.cmake index 0a8c66275a..73cc9ef950 100644 --- a/cmake/cxx_flag_overrides.cmake +++ b/cmake/cxx_flag_overrides.cmake @@ -1,6 +1,10 @@ -if(MSVC) - set(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") - set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /Od /Ob1 /D NDEBUG") +if(WIN32) + if(MSVC) + set(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /Od /Ob1 /D NDEBUG") + else() + set(CMAKE_CXX_FLAGS_RELEASE_INIT "-D_MT -O3 -DNDEBUG") + endif() endif()