diff --git a/.github/workflows/prebuilds.yml b/.github/workflows/prebuilds.yml index a029b6b..77439da 100644 --- a/.github/workflows/prebuilds.yml +++ b/.github/workflows/prebuilds.yml @@ -1,43 +1,45 @@ name: Generate prebuilds -on: - push: - branches: [main] - tags: - - "*" - env: - NODE_VERSION: 18 + NODE_VERSION: "20" + MODULE_NAME: "better-sqlite3" # Needs to match to the corresponding Node version used by NodeJS Mobile # NodeJS Mobile runtime version: https://github.com/nodejs-mobile/nodejs-mobile/blob/main/src/node_mobile_version.h # ABI mapping reference: https://github.com/nodejs-mobile/nodejs-mobile/blob/main/doc/abi_version_registry.json NODE_ABI: 108 - MODULE_NAME: "better-sqlite3" - MODULE_VERSION: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || 'latest' }} + +on: + workflow_dispatch: + inputs: + module_version: + description: "Module version" + required: true + default: "11" + type: string + publish_release: + description: "Publish release" + required: false + default: true + type: boolean + release_tag: + description: "Release tag" + required: false + type: string jobs: build: - runs-on: ubuntu-latest - timeout-minutes: 10 strategy: - fail-fast: false matrix: - target: ["android-arm", "android-arm64", "android-x64"] + platform: [android] + arch: [arm64, x64, arm] + runs-on: ubuntu-22.04 + timeout-minutes: 10 + name: better-sqlite3 (${{ matrix.platform }}-${{ matrix.arch }}) + outputs: + module_version: ${{ steps.parse-module-version.outputs.version }} steps: - - uses: actions/checkout@v5 - - - uses: MatteoH2O1999/setup-python@v6 - with: - python-version: '2.7.18' - cache-build: true - - - name: Setup NDK - uses: nttld/setup-ndk@v1 - id: setup-ndk - with: - ndk-version: r24 # https://github.com/android/ndk/wiki/Unsupported-Downloads#r24 - add-to-path: false + - uses: actions/checkout@v4 - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v4 @@ -45,54 +47,81 @@ jobs: node-version: ${{ env.NODE_VERSION }} - name: Download npm package and unpack - run: npm pack ${{ env.MODULE_NAME }}@${{ env.MODULE_VERSION }} | xargs tar -zxvf + run: + npm pack ${{ env.MODULE_NAME }}@${{ inputs.module_version }} | xargs + tar -zxvf + + - name: Parse module version + id: parse-module-version + working-directory: ./package + run: echo version=$(jq -r .version package.json) >> $GITHUB_OUTPUT + + - run: npm install -g bare-make - name: Install deps for package working-directory: ./package - run: npm install + run: npm install --ignore-scripts - - name: Generate prebuild for ${{ matrix.target }} + - name: Install cmake build tools working-directory: ./package - env: - ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} - run: npx --yes prebuild-for-nodejs-mobile@18.17.7 ${{ matrix.target }} --verbose + run: npm install -D --ignore-scripts cmake-bare cmake-fetch - - name: Upload original prebuild artifacts # mostly for debugging purposes - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.target }} - path: ./package/prebuilds/${{ matrix.target }} + - name: Install patched cmake-napi + working-directory: ./package + run: + npm install -D --ignore-scripts + cmake-napi@github:digidem/cmake-napi-nodejs-mobile - # The below steps are needed for the release job + - name: Copy CMakeLists.txt + run: cp ./CMakeLists.txt ./package/ - - name: Derive release artifact name - id: artifact-name - run: echo "NAME=${{ env.MODULE_NAME }}-${{ env.MODULE_VERSION }}-node-${{ env.NODE_ABI }}-${{ matrix.TARGET }}" >> "$GITHUB_OUTPUT" + - name: Generate + working-directory: ./package + run: + bare-make generate --platform ${{ matrix.platform }} --arch + ${{matrix.arch }} - - name: Prepare release artifact - run: tar -czf ${{ steps.artifact-name.outputs.NAME }}.tar.gz --directory=./package/prebuilds/${{ matrix.TARGET }} . + - name: Build + working-directory: ./package + run: bare-make build - - name: Upload release artifact + - name: Install + working-directory: ./package + run: bare-make install + + - name: Upload original prebuild artifacts # mostly for debugging purposes uses: actions/upload-artifact@v4 with: - name: ${{ steps.artifact-name.outputs.NAME }} - path: ./${{ steps.artifact-name.outputs.NAME }}.tar.gz + name: + ${{ env.MODULE_NAME }}-${{ + steps.parse-module-version.outputs.version }}-node-${{ env.NODE_ABI + }}-${{ matrix.platform}}-${{ matrix.arch }} + path: + ./package/prebuilds/${{ matrix.platform }}-${{ matrix.arch }}/*.node release: - if: ${{ startsWith(github.ref, 'refs/tags') }} + if: ${{ inputs.publish_release }} needs: build - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - - uses: actions/checkout@v5 - - name: Download artifacts - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v4 + with: + path: prebuilds + + - run: | + mkdir -p artifacts + for folder in prebuilds/*/; do + folder_name=$(basename "$folder") + tar -czvf "artifacts/${folder_name}.tar.gz" -C "prebuilds/${folder_name}" . + done - name: Create GitHub Release uses: ncipollo/release-action@v1 with: - artifacts: "${{ env.MODULE_NAME }}-${{ env.MODULE_VERSION }}-*/*.tar.gz" + artifacts: "artifacts/*" artifactErrorsFailBuild: true allowUpdates: true replacesArtifacts: true + tag: ${{ inputs.release_tag || needs.build.outputs.module_version }} diff --git a/.nvmrc b/.nvmrc index 3c03207..209e3ef 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18 +20 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bae664f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,173 @@ +cmake_minimum_required(VERSION 3.25) + +find_package(cmake-bare REQUIRED PATHS node_modules/cmake-bare) +find_package(cmake-napi REQUIRED PATHS node_modules/cmake-napi) + +message("cmake-bare: ${cmake-bare_DIR}") + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +project(better_sqlite3 C CXX) + +bare_target(target) + +# SQLite3 static library +add_library(sqlite3 STATIC) + +target_sources( + sqlite3 + PRIVATE + deps/sqlite3/sqlite3.c +) + +target_include_directories( + sqlite3 + PUBLIC + deps/sqlite3 +) + +target_compile_options( + sqlite3 + PRIVATE + -std=c99 + -w # Suppress warnings for SQLite +) + +# SQLite compile-time definitions from defines.gypi +target_compile_definitions( + sqlite3 + PUBLIC + HAVE_INT16_T=1 + HAVE_INT32_T=1 + HAVE_INT8_T=1 + HAVE_STDINT_H=1 + HAVE_UINT16_T=1 + HAVE_UINT32_T=1 + HAVE_UINT8_T=1 + HAVE_USLEEP=1 + SQLITE_DEFAULT_CACHE_SIZE=-16000 + SQLITE_DEFAULT_FOREIGN_KEYS=1 + SQLITE_DEFAULT_MEMSTATUS=0 + SQLITE_DEFAULT_WAL_SYNCHRONOUS=1 + SQLITE_DQS=0 + SQLITE_ENABLE_COLUMN_METADATA + SQLITE_ENABLE_DBSTAT_VTAB + SQLITE_ENABLE_DESERIALIZE + SQLITE_ENABLE_FTS3 + SQLITE_ENABLE_FTS3_PARENTHESIS + SQLITE_ENABLE_FTS4 + SQLITE_ENABLE_FTS5 + SQLITE_ENABLE_GEOPOLY + SQLITE_ENABLE_JSON1 + SQLITE_ENABLE_MATH_FUNCTIONS + SQLITE_ENABLE_RTREE + SQLITE_ENABLE_STAT4 + SQLITE_ENABLE_UPDATE_DELETE_LIMIT + SQLITE_LIKE_DOESNT_MATCH_BLOBS + SQLITE_OMIT_DEPRECATED + SQLITE_OMIT_PROGRESS_CALLBACK + SQLITE_OMIT_SHARED_CACHE + SQLITE_OMIT_TCL_VARIABLE + SQLITE_SOUNDEX + SQLITE_THREADSAFE=2 + SQLITE_TRACE_SIZE_LIMIT=32 + SQLITE_USE_URI=0 +) + +# Platform-specific definitions +if(target MATCHES "win32") + target_compile_definitions( + sqlite3 + PUBLIC + WIN32 + ) +endif() + +# Debug vs Release configurations +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions( + sqlite3 + PUBLIC + DEBUG + _DEBUG + SQLITE_DEBUG + SQLITE_MEMDEBUG + SQLITE_ENABLE_API_ARMOR + SQLITE_WIN32_MALLOC_VALIDATE + ) + + target_compile_options( + sqlite3 + PRIVATE + -O0 + ) +else() + target_compile_definitions( + sqlite3 + PUBLIC + NDEBUG + ) + + target_compile_options( + sqlite3 + PRIVATE + -O3 + ) +endif() + +# Better SQLite3 Node.js addon +add_napi_module(better_sqlite3_node) + +target_sources( + ${better_sqlite3_node} + PRIVATE + src/better_sqlite3.cpp +) + +target_link_libraries( + ${better_sqlite3_node} + PRIVATE + sqlite3 +) + +target_compile_options( + ${better_sqlite3_node} + PRIVATE + -std=c++20 +) + +# Fix Android NDK C++ standard library include path +if(ANDROID) + target_include_directories( + ${better_sqlite3_node} + SYSTEM PRIVATE + "${CMAKE_SYSROOT}/usr/include/c++/v1" + ) +endif() + +# Platform-specific linker flags +if(target MATCHES "linux") + target_link_options( + ${better_sqlite3_node} + PRIVATE + -Wl,-Bsymbolic + -Wl,--exclude-libs,ALL + ) +endif() + +# Test extension (optional) +add_library(test_extension SHARED) + +target_sources( + test_extension + PRIVATE + deps/test_extension.c +) + +target_link_libraries( + test_extension + PRIVATE + sqlite3 +) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 38d47ab..65f569f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Digital Democracy +Copyright (c) 2024 Awana Digital Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index f421524..5ed9ffc 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,71 @@ # better-sqlite3-nodejs-mobile -[NodeJS Mobile](https://github.com/nodejs-mobile/nodejs-mobile) prebuilds for [`better-sqlite3`](https://www.npmjs.com/package/better-sqlite3). +[NodeJS Mobile](https://github.com/nodejs-mobile/nodejs-mobile) prebuilds for +[`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3) ## Working locally ### Requirements -- Node 18 -- Android NDK 24.0.8215888 - - (optional) exported `ANDROID_NDK_PATH` environment variable +- Node 20+ (CI uses version 20) +- Android NDK (CI uses version 27.2.12479018) + - (optional) exported `ANDROID_NDK_HOME` environment variable ### General steps -Should be clear enough to follow the workflow steps but in summary: +Should be clear enough to follow the +[reusable workflow steps](https://github.com/digidem/nodejs-mobile-bare-prebuilds/blob/main/.github/workflows/prebuild.yml) +but in summary: -1. Download the npm tarball package and unzip e.g. `npm pack better-sqlite@latest | xargs tar -zxvf` - -2. Navigate to unzipped directory and run `npx prebuild-for-nodejs-mobile TARGET`, where `TARGET` is an accepted value from the [`prebuild-for-nodejs-mobile`](https://github.com/staltz/prebuild-for-nodejs-mobile) CLI - - if you don't have the `ANDROID_NDK_PATH` environment variable exported, you may run the command like so: `ANDROID_NDK_HOME=/path/to/ndk npx prebuild-for-nodejs-mobile TARGET` +1. Download the npm tarball package and unzip e.g. + ``` + npm pack better-sqlite3@11 | xargs tar -zxvf + ``` +2. Navigate to unzipped directory: + ``` + cd package + ``` +3. Install dependencies: + ``` + npm install --ignore-scripts + ``` +4. Install cmake build tools: + ``` + npm install -D --ignore-scripts cmake-bare cmake-fetch + ``` +5. Install + [patched `cmake-napi`](https://github.com/digidem/cmake-napi-nodejs-mobile): + ``` + npm install -D --ignore-scripts cmake-napi@github:digidem/cmake-napi-nodejs-mobile + ``` +6. Copy `CMakeLists.txt` from this repository to the `package` directory: + ``` + cp ../CMakeLists.txt ./ + ``` +7. Install [bare-make](https://github.com/holepunchto/bare-make) globally: + ``` + npm install -g bare-make@latest + ``` +8. Generate, build and install: + ``` + bare-make generate --platform android --arch arm64 + bare-make build + bare-make install + ``` ## Creating a release -1. Create a git tag that matches the version of the module you want to create prebuilds for e.g. `git tag 1.0.0` +1. Navigate to the + [Generate Prebuilds workflow](https://github.com/digidem/better-sqlite3-nodejs-mobile/actions/workflows/prebuilds.yml) +2. Manually dispatch the worflow with the version you want to build, ensuring + that "Publish Release" is checked. + +## Contributing + +We welcome contributions to this repository. If you have an idea for a new +feature or have found a bug, please open an issue or submit a pull request. -2. Push the tag to the remote e.g. `git push origin 1.0.0` +## License -3. The workflow uses the tag version to create the prebuilds and then publish a release with those prebuilds. +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file +for more details.