Skip to content

Failing to build better-sqlite3 for nodejs-mobile on iOS #4

@Jermolene

Description

@Jermolene

I am writing an iOS app that uses nodejs-mobile to run TiddlyWiki. It uses the full Node.js configuration of TiddlyWiki, not the single file configuration.

In the main branch I have it working. Now I want to be able to use the npm package better-sqlite3 which includes native code.

I have a script that includes running prebuild-for-nodejs-mobile within the node_modules/better-sqlite3 directory:

npx prebuild-for-nodejs-mobile ios-arm64

The prebuild works, and I can see the better_sqlite3.node directory in the prebuilds/ios-arm64/ folder.

Now comes the tricky bit. I am trying to use node-gyp-build to modify the package so that npm rebuild will pick the prebuilds for ios-arm64, and prepare a node_modules folder that works correctly with nodejs-mobile.

After running the script below in the terminal, and then running the app itself in Xcode on an Apple Silicon Mac and an iPad Pro, I get the following error:

[Whitespace inserted for readability]

Error: dlopen(/private/var/containers/Bundle/Application/FB49F9C9-3055-48AF-B69F-2217051F055E/TiddlyWiki.app/nodejs-project/node_modules/better-sqlite3/build/Release/better_sqlite3.node, 0x0001):
 tried: '/usr/lib/system/introspection/better_sqlite3.node' (no such file, not in dyld cache),
'/private/var/containers/Bundle/Application/FB49F9C9-3055-48AF-B69F-2217051F055E/TiddlyWiki.app/nodejs-project/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
(mach-o file (/private/var/containers/Bundle/Application/FB49F9C9-3055-48AF-B69F-2217051F055E/TiddlyWiki.app/nodejs-project/node_modules/better-sqlite3/build/Release/better_sqlite3.node),
but incompatible platform (have 'macOS', need 'iOS')), '/private/preboot/Cryptexes/OS/private/var/containers/Bundle/Application/FB49F9C9-3055-48AF-B69F-2217051F055E/TiddlyWiki.app/nodejs-project/node_modules/better-sqlite3/build/Release/better_sqlite3.node' (no such file),
'/private/var/containers/Bundle/Application/FB49F9C9-3055-48AF-B69F-2217051F055E/TiddlyWiki.app/nodejs-project/node_modules/better-sqlite3/build/Release/better_sqlite3.node' (mach-o file (/private/var/containers/Bundle/Application/FB49F9C9-3055-48AF-B69F-2217051F055E/TiddlyWiki.app/nodejs-project/node_modules/better-sqlite3/build/Release/better_sqlite3.node), but incompatible platform (have 'macOS', need 'iOS'))

I think the crucial part is incompatible platform (have 'macOS', need 'iOS'), which suggests that npm rebuild is ignoring the prebuilds and compiling for the native platform.

I would appreciate any pointers that anyone can give me.

Here's the full code of my script
#!/bin/bash

# This script downloads and prepares TiddlyWiki 5 for inclusion in the app by compiling native modules

# 1. Download the TiddlyWiki5 branch "multi-wiki-support" into the folder ./nodejs-project
# 2. Build better-sqlite3 for ios-arm64 in ./TiddlyWiki/nodejs-project/node_modules/better-sqlite3

# Exit immediately if a command exits with a non-zero status
set -e

# Remove existing nodejs-project
rm -rf ./TiddlyWiki/nodejs-project

# Download TW5
REPO="Jermolene/TiddlyWiki5"
BRANCH="multi-wiki-support"
ZIP_URL="https://github.com/$REPO/archive/refs/heads/$BRANCH.zip"
TEMP_DIR=$(mktemp -d)
TEMP_ZIP="$TEMP_DIR/$BRANCH.zip"
curl -L $ZIP_URL -o $TEMP_ZIP
unzip -q $TEMP_ZIP -d ./TiddlyWiki
mv ./TiddlyWiki/TiddlyWiki5-multi-wiki-support ./TiddlyWiki/nodejs-project
rm -rf $TEMP_DIR
echo "TW5 downloaded"

# Remove existing node_modules
rm -rf ./TiddlyWiki/nodejs-project/node_modules

# Navigate to project directory
pushd "./TiddlyWiki/nodejs-project"

# Install the necessary packages
npm install better-sqlite3
npm install node-gyp-build

# Navigate to the better-sqlite3 directory
pushd "node_modules/better-sqlite3"

# Run the prebuild command
npx prebuild-for-nodejs-mobile ios-arm64

# Update package.json

node -e "
const fs = require('fs');
const path = 'package.json';

// Read the package.json file
fs.readFile(path, 'utf8', (err, data) => {
  if (err) {
    console.error('Error reading package.json:', err);
    return;
  }

  // Parse the existing package.json content
  const packageJson = JSON.parse(data);

  packageJson.name = 'better-sqlite3';
  packageJson.scripts.install = 'node-gyp-build';

  // Write the updated package.json back to file
  fs.writeFile(path, JSON.stringify(packageJson, null, 2), (err) => {
    if (err) {
      console.error('Error writing package.json:', err);
      return;
    }
    console.log('package.json updated successfully.');
  });
});
"

# Return to the project directory
popd

# Rebuild
npm rebuild

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions