mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 09:46:02 +08:00
170 lines
6.0 KiB
JavaScript
170 lines
6.0 KiB
JavaScript
#!/usr/bin/env node
|
|
import { execSync } from 'node:child_process';
|
|
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { generate } from '../../../spine-c/codegen/src/index.js';
|
|
import { DartWriter } from './dart-writer.js';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
async function generateFFIBindings(spineCDir: string): Promise<void> {
|
|
const ffigenPath = await generateFFigenYaml(spineCDir);
|
|
|
|
// Run ffigen to generate bindings
|
|
console.log('Running ffigen...');
|
|
try {
|
|
execSync('dart run ffigen --config ffigen.yaml', {
|
|
cwd: path.join(__dirname, '../..'),
|
|
stdio: 'inherit'
|
|
});
|
|
} catch (error) {
|
|
console.error('Failed to run ffigen:', error);
|
|
throw error;
|
|
}
|
|
|
|
// Check if bindings were generated successfully
|
|
const bindingsPath = path.join(__dirname, '../../lib/generated/spine_dart_bindings_generated.dart');
|
|
if (!fs.existsSync(bindingsPath)) {
|
|
throw new Error('Failed to generate bindings');
|
|
}
|
|
|
|
// Replace dart:ffi import with ffi_proxy.dart
|
|
console.log('Replacing dart:ffi import with ffi_proxy.dart...');
|
|
let content = fs.readFileSync(bindingsPath, 'utf8');
|
|
content = content.replace("import 'dart:ffi' as ffi;", "import '../../ffi_proxy.dart' as ffi;");
|
|
fs.writeFileSync(bindingsPath, content);
|
|
|
|
// Clean up ffigen.yaml
|
|
console.log('Cleaning up ffigen.yaml...');
|
|
fs.unlinkSync(ffigenPath);
|
|
|
|
console.log('✅ FFI bindings generated successfully!');
|
|
}
|
|
|
|
async function generateFFigenYaml(spineCDir: string): Promise<string> {
|
|
console.log('Finding all header files...');
|
|
const generatedDir = path.join(spineCDir, 'src/generated');
|
|
const headerFiles = fs.readdirSync(generatedDir)
|
|
.filter(f => f.endsWith('.h'))
|
|
.map(f => path.join('src/spine-c/src/generated', f))
|
|
.sort();
|
|
|
|
console.log(`Found ${headerFiles.length} header files`);
|
|
|
|
// Generate ffigen.yaml configuration
|
|
console.log('Generating ffigen.yaml configuration...');
|
|
const ffigenConfig = `# Run with \`dart run ffigen --config ffigen.yaml\`.
|
|
name: SpineDartBindings
|
|
description: |
|
|
Bindings for Spine C headers.
|
|
|
|
Regenerate bindings with \`dart run ffigen --config ffigen.yaml\`.
|
|
output: 'lib/generated/spine_dart_bindings_generated.dart'
|
|
llvm-path:
|
|
- '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/'
|
|
headers:
|
|
entry-points:
|
|
- 'src/spine-c/include/spine-c.h'
|
|
compiler-opts:
|
|
- '-Isrc/spine-c/include'
|
|
- '-Isrc/spine-c/src'
|
|
- '-Isrc/spine-c/src/generated'
|
|
- '-xc'
|
|
- '-std=c99'
|
|
functions:
|
|
include:
|
|
- 'spine_.*'
|
|
structs:
|
|
include:
|
|
- 'spine_.*'
|
|
enums:
|
|
include:
|
|
- 'spine_.*'
|
|
typedefs:
|
|
include:
|
|
- 'spine_.*'
|
|
preamble: |
|
|
// ignore_for_file: always_specify_types, constant_identifier_names
|
|
// ignore_for_file: camel_case_types
|
|
// ignore_for_file: non_constant_identifier_names
|
|
comments:
|
|
style: any
|
|
length: full
|
|
`;
|
|
|
|
const ffigenPath = path.join(__dirname, '../../ffigen.yaml');
|
|
fs.writeFileSync(ffigenPath, ffigenConfig);
|
|
console.log(`FFigen config written to: ${ffigenPath}`);
|
|
return ffigenPath;
|
|
}
|
|
|
|
async function main() {
|
|
const args = process.argv.slice(2);
|
|
const justGenerateYaml = args.includes('--yaml-only');
|
|
|
|
if (justGenerateYaml) {
|
|
console.log('Generating ffigen.yaml only...\n');
|
|
|
|
// Generate FFI bindings YAML config only
|
|
const spineCDir = path.join(__dirname, '../../src/spine-c');
|
|
await generateFFigenYaml(spineCDir);
|
|
console.log('✅ ffigen.yaml generated successfully!');
|
|
return;
|
|
}
|
|
|
|
console.log('Generating Spine Flutter bindings and wrappers...\n');
|
|
|
|
console.log('🔧 Using Dart writer implementation\n');
|
|
|
|
try {
|
|
// Step 1: Generate C intermediate representation using spine-c codegen
|
|
console.log('Step 1: Generating C intermediate representation...');
|
|
const { cTypes, cEnums, cArrayTypes, inheritance, supertypes, subtypes, isInterface } = await generate();
|
|
console.log(`Generated ${cTypes.length} C types, ${cEnums.length} enums, and ${cArrayTypes.length} array types\n`);
|
|
|
|
// Step 2: Write Dart wrapper classes
|
|
console.log('Step 2: Writing Dart wrapper classes...');
|
|
const outputDir = path.join(__dirname, '../../lib/generated');
|
|
const dartWriter = new DartWriter(outputDir);
|
|
await dartWriter.writeAll(cTypes, cEnums, cArrayTypes, inheritance, isInterface, supertypes);
|
|
console.log();
|
|
|
|
// Step 3: Generate FFI bindings using ffigen
|
|
console.log('Step 3: Generating FFI bindings...');
|
|
const spineCDir = path.join(__dirname, '../../src/spine-c');
|
|
await generateFFIBindings(spineCDir);
|
|
|
|
// Step 4: Format and fix generated Dart code
|
|
console.log('Step 4: Formatting and fixing generated Dart code...');
|
|
try {
|
|
const projectRoot = path.join(__dirname, '../..');
|
|
|
|
// Run dart fix to remove unused imports and apply other fixes
|
|
console.log('Running dart fix --apply...');
|
|
execSync('dart fix --apply lib/generated/', {
|
|
cwd: projectRoot,
|
|
stdio: 'inherit'
|
|
});
|
|
|
|
// Run custom dart format script
|
|
console.log('Running dart format...');
|
|
execSync(path.join(__dirname, '../../../formatters/format-dart.sh lib/generated/'), {
|
|
cwd: projectRoot,
|
|
stdio: 'inherit'
|
|
});
|
|
|
|
console.log('✅ Dart code formatting and fixes applied successfully!');
|
|
} catch (error) {
|
|
console.warn('⚠️ Warning: Could not format/fix Dart code:', error);
|
|
console.warn('You may want to run "dart fix --apply lib/generated/" and "dart format lib/generated/" manually');
|
|
}
|
|
|
|
console.log('\n✅ All code generation completed successfully!');
|
|
} catch (error) {
|
|
console.error('\n❌ Error:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main(); |