diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..3d17831 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: ci + +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-24.04 + env: + EMSCRIPTEN_VERSION: '3.1.64' + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + sudo apt install -y ninja-build \ + extra-cmake-modules \ + gettext \ + marisa + ./install-deps.sh + + - name: Install emsdk + run: | + git clone https://github.com/emscripten-core/emsdk + cd emsdk + ./emsdk install ${{ env.EMSCRIPTEN_VERSION }} + ./emsdk activate ${{ env.EMSCRIPTEN_VERSION }} + + - name: Build + run: | + . emsdk/emsdk_env.sh + python scripts/hallelujah.py + + - name: Release + if: ${{ github.ref == 'refs/heads/master' }} + uses: 'marvinpinto/action-automatic-releases@latest' + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + automatic_release_tag: latest + prerelease: true + title: "Nightly Build" + files: | + build/*.tar.bz2 diff --git a/.gitignore b/.gitignore index f5c343b..c49feb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store +*.tar.bz2 build __pycache__ diff --git a/cache/README.md b/cache/README.md new file mode 100644 index 0000000..ca7e54d --- /dev/null +++ b/cache/README.md @@ -0,0 +1,3 @@ +This directory caches tarball of build dependencies +(downloaded from [prebuilder](https://github.com/fcitx-contrib/fcitx5-js-prebuilder/releases)), +which will be extracted to `build/sysroot/usr`. diff --git a/fcitx5-hallelujah b/fcitx5-hallelujah index 809a2d4..9eca643 160000 --- a/fcitx5-hallelujah +++ b/fcitx5-hallelujah @@ -1 +1 @@ -Subproject commit 809a2d4f980f74fbb658467bd516bef0caed31aa +Subproject commit 9eca643ea97c28fb5fb19e04e23185bb111592ad diff --git a/install-deps.sh b/install-deps.sh new file mode 100755 index 0000000..a7383c3 --- /dev/null +++ b/install-deps.sh @@ -0,0 +1,17 @@ +deps=( + json-c + marisa +) + +EXTRACT_DIR=build/sysroot/usr +mkdir -p $EXTRACT_DIR + +for dep in "${deps[@]}"; do + file=$dep.tar.bz2 + [[ -f cache/$file ]] || wget -P cache https://github.com/fcitx-contrib/fcitx5-js-prebuilder/releases/download/latest/$file + tar xjvf cache/$file -C $EXTRACT_DIR +done + +file=fcitx5-js-dev.tar.bz2 +[[ -f cache/$file ]] || wget -P cache https://github.com/fcitx-contrib/fcitx5-js/releases/download/latest/$file +tar xjvf cache/$file -C $EXTRACT_DIR diff --git a/patches/hallelujah.patch b/patches/hallelujah.patch new file mode 100644 index 0000000..43d137b --- /dev/null +++ b/patches/hallelujah.patch @@ -0,0 +1,24 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 02daeea..17cf5c9 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.6.0) + + project(fcitx5-hallelujah VERSION 5.0.0) + ++set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) ++set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-sSIDE_MODULE") ++set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-sSIDE_MODULE") ++ + find_package(ECM 1.0.0 REQUIRED) + set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH}) + include(FeatureSummary) +@@ -33,7 +37,7 @@ endif() + add_definitions(-DFCITX_GETTEXT_DOMAIN=\"fcitx5-hallelujah\") + fcitx5_add_i18n_definition() + +-include("${FCITX_INSTALL_CMAKECONFIG_DIR}/Fcitx5Utils/Fcitx5CompilerSettings.cmake") ++include("../build/sysroot${FCITX_INSTALL_CMAKECONFIG_DIR}/Fcitx5Utils/Fcitx5CompilerSettings.cmake") + + add_subdirectory(src) + if (ENABLE_TEST) diff --git a/scripts/common.py b/scripts/common.py new file mode 100644 index 0000000..6476a5c --- /dev/null +++ b/scripts/common.py @@ -0,0 +1,72 @@ +import os + +INSTALL_PREFIX = '/usr' + + +def ensure(program: str, args: list[str]): + command = " ".join([program, *args]) + print(command) + if os.system(command) != 0: + raise Exception("Command failed") + + +class Builder: + def __init__(self, name: str, options: list[str] | None=None): + self.name = name + self.root = os.getcwd() + self.destdir = f'{self.root}/build/{self.name}' + self.options = options or [] + + def patch(self): + os.chdir(f'{self.root}/fcitx5-{self.name}') + file = f'../patches/{self.name}.patch' + if os.system('git diff --ignore-submodules --exit-code > /dev/null') == 0 and os.path.isfile(file): + ensure('git', ['apply', file]) + ensure('sed', [ + '-i', + f'"s|\\"/usr/include|\\"{self.root}/build/sysroot/usr/include|g"', + '$(find ../build/sysroot/usr -name "*.cmake")' + ]) + ensure('sed', [ + '-i', + f'"s|=/usr/include|={self.root}/build/sysroot/usr/include|g"', + '$(find ../build/sysroot/usr -name "*.pc")' + ]) + + def configure(self): + os.environ['PKG_CONFIG_PATH'] = f'{self.root}/build/sysroot/usr/lib/pkgconfig' + ensure('emcmake', ['cmake', + '-B', 'build', '-G', 'Ninja', + f'-DCMAKE_INSTALL_PREFIX={INSTALL_PREFIX}', + f'-DCMAKE_FIND_ROOT_PATH="{self.root}/build/sysroot/usr;/usr"', + '-DCMAKE_BUILD_TYPE=Release', + *self.options + ]) + + def build(self): + ensure('cmake', ['--build', 'build']) + + def install(self): + os.environ['DESTDIR'] = self.destdir + ensure('cmake', ['--install', 'build']) + + def package(self): + os.chdir(f'{self.destdir}{INSTALL_PREFIX}') + ensure('tar', ['cjvf', f'{self.destdir}.tar.bz2', '*']) + + def exec(self): + self.patch() + self.configure() + ensure('sed', [ + '-i', + f'"s|-I/usr|-I{self.root}/build/sysroot/usr|g"', + 'build/build.ninja' + ]) + ensure('sed', [ + '-i', + f'"s|-isystem /usr|-isystem {self.root}/build/sysroot/usr|g"', + 'build/build.ninja' + ]) + self.build() + self.install() + self.package() diff --git a/scripts/hallelujah.py b/scripts/hallelujah.py new file mode 100644 index 0000000..b757b24 --- /dev/null +++ b/scripts/hallelujah.py @@ -0,0 +1,5 @@ +from common import Builder + +Builder('hallelujah', [ + '-DENABLE_TEST=OFF' +]).exec()