mathcalc-cli 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,22 +8,36 @@ A lightweight Rust command-line calculator capable of evaluating real/complex ex
8
8
  2. Build a Release binary: `cargo build --release`.
9
9
  3. Run an expression straight from your shell: `./target/release/calculator "x^2-5x+6=0"`.
10
10
 
11
- ## NPM Installation
11
+ ## 安装和使用
12
12
 
13
- ### For x64 Systems (Windows, macOS Intel, Linux x64)
14
- The easiest way to install calculator-cli is via npm:
13
+ ### npm全局安装(推荐)
14
+ ```bash
15
+ npm install -g mathcalc-cli
16
+ mathcalc "2 + 2"
17
+ mathcalc "x^2-5x+6=0"
18
+ ```
15
19
 
20
+ ### npx方式(无需全局安装)
16
21
  ```bash
17
- npm install -g calculator-cli
22
+ npx mathcalc-cli "2 + 2"
23
+ npx mathcalc-cli "x^2-5x+6=0"
18
24
  ```
19
25
 
20
- Once installed, you can run:
26
+ ### 本地项目使用
27
+ ```bash
28
+ npm install mathcalc-cli
29
+ npx mathcalc-cli "2 + 2"
30
+ ```
21
31
 
32
+ ### 从GitHub Release下载
22
33
  ```bash
23
- calculator "2 + 2"
24
- calculator "x^2-5x+6=0"
34
+ https://github.com/Mcas-996/calculator-cli/releases
25
35
  ```
26
36
 
37
+ 下载对应平台的二进制文件
38
+ ```
39
+
40
+
27
41
  ### For ARM Systems (Apple Silicon, ARM64 Linux)
28
42
  The npm package includes precompiled binaries only for x64 systems. For ARM systems:
29
43
 
package/index.js CHANGED
@@ -1,40 +1,89 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // Entry point for the calculator-cli npm package
4
- // This is a minimal wrapper that delegates to the compiled binary
5
-
3
+ const os = require("os");
6
4
  const path = require("path");
5
+ const fs = require("fs");
7
6
  const { spawnSync } = require("child_process");
8
- const os = require("os");
9
7
 
10
- // Determine the appropriate binary based on platform
8
+ // Determine platform and appropriate binary
11
9
  const platform = os.platform();
12
10
  const isWindows = platform === "win32";
11
+ const arch = os.arch();
13
12
 
14
- // Binary file names
15
- const binaryName = isWindows
16
- ? "calculator_windows-x86-64.exe"
17
- : "calculator_linux-x64";
18
- const binaryPath = path.join(__dirname, "bin", binaryName);
13
+ if (!arch.includes("64")) {
14
+ console.error("❌ Calculator CLI only supports 64-bit architectures");
15
+ process.exit(1);
16
+ }
19
17
 
20
- function runCalculator(args) {
21
- if (!require("fs").existsSync(binaryPath)) {
22
- console.error(`Error: Calculator binary not found for ${platform}`);
23
- process.exit(1);
24
- }
18
+ let binaryPath, calculatorName;
25
19
 
20
+ if (isWindows) {
21
+ calculatorName = "calculator_windows-x86-64.exe";
22
+ binaryPath = path.join(__dirname, "bin", calculatorName);
23
+ } else if (platform === "linux") {
24
+ calculatorName = "calculator-linux-x64";
25
+ binaryPath = path.join(__dirname, "bin", calculatorName);
26
+ } else {
27
+ console.error("❌ Platform not supported:", platform);
28
+ console.log(
29
+ "For macOS (Apple Silicon) or other platforms, please install from source:",
30
+ );
31
+ console.log(" cargo install calculator");
32
+ process.exit(1);
33
+ }
34
+
35
+ // Check if binary exists
36
+ if (!fs.existsSync(binaryPath)) {
37
+ console.error(`❌ Calculator binary not found: ${calculatorName}`);
38
+ console.log(
39
+ "Please ensure the binary files are present in the bin directory.",
40
+ );
41
+ console.log("\nFor Windows:");
42
+ console.log(" Place calculator_windows-x86-64.exe in bin/");
43
+ console.log("\nFor Linux:");
44
+ console.log(" Place calculator-linux-x64 in bin/");
45
+ console.log("\nDownload releases from:");
46
+ console.log(" https://github.com/Mcas-996/calculator-cli/releases");
47
+ process.exit(1);
48
+ }
49
+
50
+ // Make sure binary is executable (Unix-like systems)
51
+ if (!isWindows) {
26
52
  try {
27
- const result = spawnSync(binaryPath, args, { stdio: "inherit" });
28
- process.exit(result.status);
29
- } catch (error) {
30
- console.error(`Error: ${error.message}`);
31
- process.exit(1);
53
+ fs.chmodSync(binaryPath, "755");
54
+ } catch (err) {
55
+ console.warn(
56
+ `⚠️ Warning: Could not set executable permissions: ${err.message}`,
57
+ );
32
58
  }
33
59
  }
34
60
 
35
- // If called from npm scripts, pass all arguments to the binary
36
- if (require.main === module) {
37
- runCalculator(process.argv.slice(2));
61
+ // Handle command line arguments
62
+ const args = process.argv.slice(2);
63
+
64
+ if (args.length === 0) {
65
+ // Display help when no arguments provided
66
+ console.log("Calculator CLI v0.2.0 - Command Line Calculator");
67
+ console.log("");
68
+ console.log("Usage:");
69
+ console.log(' mathcalc "expression" Calculate an expression');
70
+ console.log(' mathcalc "equation" Solve an equation');
71
+ console.log(" mathcalc Interactive mode");
72
+ console.log("");
73
+ console.log("Examples:");
74
+ console.log(' mathcalc "2 + 2" # => 4');
75
+ console.log(' mathcalc "x^2-4=0" # => x = 2, -2');
76
+ console.log(' mathcalc "(3+2i)*(1-i)" # => 5 + i');
77
+ console.log("");
78
+ console.log("For more help:");
79
+ console.log(" mathcalc --help");
80
+ process.exit(0);
38
81
  }
39
82
 
40
- module.exports = { runCalculator };
83
+ try {
84
+ const result = spawnSync(binaryPath, args, { stdio: "inherit" });
85
+ process.exit(result.status || 0);
86
+ } catch (error) {
87
+ console.error(`Error: ${error.message}`);
88
+ process.exit(1);
89
+ }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "mathcalc-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "A command-line calculator with symbolic math support",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "calculator": "bin/calculator_linux-x64"
7
+ "mathcalc": "index.js"
8
8
  },
9
9
  "scripts": {
10
10
  "preinstall": "node scripts/install.js",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "git+https://github.com/anomalyco/calculator-cli.git"
16
+ "url": "git+https://github.com/Mcas-996/calculator-cli.git"
17
17
  },
18
18
  "keywords": [
19
19
  "calculator",
@@ -22,11 +22,11 @@
22
22
  "command-line",
23
23
  "equations"
24
24
  ],
25
- "author": "Allen <anomalyco@github.com>",
25
+ "author": "allen",
26
26
  "license": "MIT",
27
27
  "os": [
28
- "linux",
29
- "win32"
28
+ "win32",
29
+ "linux"
30
30
  ],
31
31
  "cpu": [
32
32
  "x64"
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const path = require('path');
4
- const fs = require('fs');
5
- const os = require('os');
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+ const os = require("os");
6
6
 
7
7
  // Platform detection
8
8
  const platform = os.platform();
@@ -11,255 +11,89 @@ console.log(`Detected architecture: ${os.arch()}`);
11
11
 
12
12
  // Map platforms to binary files
13
13
  const binaries = {
14
- 'win32': 'calculator_windows-x86-64.exe',
15
- 'linux': 'calculator_linux-x64'
14
+ win32: "calculator_windows-x86-64.exe",
15
+ linux: "calculator-linux-x64",
16
16
  };
17
17
 
18
18
  // Check if platform is supported
19
19
  if (!binaries[platform]) {
20
- console.error(`
21
- ❌ Platform ${platform} is not supported by calculator-cli v0.1.0
20
+ console.error(`
21
+ ❌ Platform ${platform} is not supported by mathcalc-cli v0.2.0
22
22
 
23
23
  Supported platforms:
24
24
  - Windows (x64)
25
25
  - Linux (x64)
26
26
 
27
27
  For other platforms, please build from source:
28
- git clone https://github.com/anomalyco/calculator-cli.git
28
+ git clone https://github.com/Mcas-996/calculator-cli.git
29
29
  cd calculator-cli
30
30
  cargo build --release
31
31
  `);
32
- process.exit(1);
32
+ process.exit(1);
33
33
  }
34
34
 
35
35
  // Binary path
36
36
  const binaryName = binaries[platform];
37
- const binaryPath = path.join(__dirname, '..', 'bin', binaryName);
37
+ const binaryPath = path.join(__dirname, "..", "bin", binaryName);
38
38
 
39
39
  // Verify binary exists
40
40
  if (!fs.existsSync(binaryPath)) {
41
- console.error(`❌ Binary not found: ${binaryPath}`);
42
- console.error('Please ensure the binary files are present in the bin directory.');
43
- console.error('For Windows users: Place calculator_windows-x86-64.exe in bin/');
44
- console.error('For Linux users: Place calculator_linux-x64 in bin/');
45
- process.exit(1);
41
+ console.error(`❌ Binary not found: ${binaryPath}`);
42
+ console.error(
43
+ "Please ensure the binary files are present in the bin directory.",
44
+ );
45
+ console.error(
46
+ "For Windows users: Place calculator_windows-x86-64.exe in bin/",
47
+ );
48
+ console.error("For Linux users: Place calculator-linux-x64 in bin/");
49
+ process.exit(1);
46
50
  }
47
51
 
48
52
  // Create symlink or wrapper for node_modules/.bin
49
- const targetDir = path.join(__dirname, '..', 'node_modules', '.bin');
50
- const targetPath = path.join(targetDir, 'calculator');
53
+ const targetDir = path.join(__dirname, "..", "node_modules", ".bin");
54
+ const targetPath = path.join(targetDir, "mathcalc");
51
55
 
52
56
  try {
53
- // Ensure .bin directory exists
54
- if (!fs.existsSync(targetDir)) {
55
- fs.mkdirSync(targetDir, { recursive: true });
56
- }
57
+ // Ensure .bin directory exists
58
+ if (!fs.existsSync(targetDir)) {
59
+ fs.mkdirSync(targetDir, { recursive: true });
60
+ }
57
61
 
58
- if (platform === 'win32') {
59
- // Create a batch file wrapper for Windows
60
- const batchContent = `@echo off
62
+ if (platform === "win32") {
63
+ // Create a batch file wrapper for Windows
64
+ const batchContent = `@echo off
61
65
  "${binaryPath}" %*`;
62
- fs.writeFileSync(`${targetPath}.cmd`, batchContent);
63
- console.log('✅ Created Windows batch file');
64
- } else {
65
- // Create symbolic link for Unix-like systems
66
- if (fs.existsSync(targetPath)) {
67
- fs.unlinkSync(targetPath);
66
+ fs.writeFileSync(`${targetPath}.cmd`, batchContent);
67
+ console.log("✅ Created Windows batch file");
68
+ } else {
69
+ // Create symbolic link for Unix-like systems
70
+ if (fs.existsSync(targetPath)) {
71
+ fs.unlinkSync(targetPath);
72
+ }
73
+ fs.symlinkSync(binaryPath, targetPath);
74
+ // Ensure executable permissions
75
+ fs.chmodSync(targetPath, "755");
76
+ console.log("✅ Created symbolic link with executable permissions");
68
77
  }
69
- fs.symlinkSync(binaryPath, targetPath);
70
- // Ensure executable permissions
71
- fs.chmodSync(targetPath, '755');
72
- console.log('✅ Created symbolic link with executable permissions');
73
- }
74
- } catch (error) {
75
- console.error(`❌ Failed to create command link: ${error.message}`);
76
- process.exit(1);
77
- }
78
-
79
- console.log('✅ Installation complete!');
80
- console.log(`You can now run 'calculator' in your terminal.`);
81
- ```
82
-
83
- <file_path>
84
- calculator-cli/scripts/postinstall.js
85
- </file_path>
86
-
87
- <edit_description>
88
- Create postinstall validation script
89
- </edit_description>
90
-
91
- ```javascript
92
- #!/usr/bin/env node
93
-
94
- const path = require('path');
95
- const fs = require('fs');
96
- const os = require('os');
97
-
98
- console.log('✅ Validating calculator-cli installation...');
99
-
100
- // Check for proper binary based on platform
101
- const platform = os.platform();
102
- const expectedBinary = platform === 'win32'
103
- ? 'calculator_windows-x86-64.exe'
104
- : 'calculator_linux-x64';
105
-
106
- const binaryPath = path.join(__dirname, '..', 'bin', expectedBinary);
107
-
108
- if (fs.existsSync(binaryPath)) {
109
- console.log(`✅ Binary found: ${expectedBinary}`);
110
- } else {
111
- console.error(`❌ Binary not found: ${expectedBinary}`);
112
- console.error('Please ensure the binary files are present in the bin directory.');
113
- process.exit(1);
114
- }
115
-
116
- // Verify command is accessible
117
- const targetPath = path.join(__dirname, '..', 'node_modules', '.bin');
118
- const commandPath = platform === 'win32'
119
- ? path.join(targetPath, 'calculator.cmd')
120
- : path.join(targetPath, 'calculator');
121
-
122
- if (fs.existsSync(commandPath)) {
123
- console.log('✅ Command link created successfully');
124
- } else {
125
- console.error('❌ Command link not found');
126
- process.exit(1);
127
- }
128
-
129
- console.log('✅ Installation validated successfully!');
130
- ```
131
-
132
- <file_path>
133
- calculator-cli/scripts/test.js
134
- </file_path>
135
-
136
- <edit_description>
137
- Create test script to validate the binary
138
- </edit_description>
139
-
140
- ```javascript
141
- #!/usr/bin/env node
142
-
143
- const path = require('path');
144
- const fs = require('fs');
145
- const os = require('os');
146
- const { execSync } = require('child_process');
147
-
148
- console.log('🧪 Testing calculator-cli binary...');
149
-
150
- // Platform detection
151
- const platform = os.platform();
152
- const binaryName = platform === 'win32'
153
- ? 'calculator_windows-x86-64.exe'
154
- : 'calculator_linux-x64';
155
-
156
- const binaryPath = path.join(__dirname, '..', 'bin', binaryName);
157
-
158
- // Check if binary exists
159
- if (!fs.existsSync(binaryPath)) {
160
- console.error(`❌ Binary not found: ${binaryName}`);
161
- process.exit(1);
162
- }
163
-
164
- // Test basic calculation
165
- try {
166
- console.log('🧮 Testing basic calculation: 2 + 2');
167
- const result = execSync(`"${binaryPath}" "2 + 2"`, { encoding: 'utf8' }).trim();
168
-
169
- if (result && result.includes('4')) {
170
- console.log(`✅ Basic calculation test passed: ${result}`);
171
- } else {
172
- console.log(`❌ Unexpected result: ${result}`);
173
- process.exit(1);
174
- }
175
78
  } catch (error) {
176
- console.error(`❌ Failed to run binary: ${error.message}`);
177
- process.exit(1);
178
- }
179
-
180
- // Test equation solving
181
- try {
182
- console.log('🧮 Testing equation solving: x^2-4=0');
183
- const equationResult = execSync(`"${binaryPath}" "x^2-4=0"`, { encoding: 'utf8' }).trim();
184
-
185
- console.log(`✅ Equation solving result: ${equationResult}`);
186
- } catch (error) {
187
- console.error(`❌ Failed to solve equation: ${error.message}`);
188
- process.exit(1);
79
+ console.error(`❌ Failed to create command link: ${error.message}`);
80
+ console.error("Creating alternative wrapper script...");
81
+
82
+ try {
83
+ // Create a wrapper script instead
84
+ const wrapperContent = `#!/usr/bin/env node
85
+ const { spawnSync } = require('child_process');
86
+ const result = spawnSync('${binaryPath}', process.argv.slice(2), { stdio: 'inherit' });
87
+ process.exit(result.status || 0);
88
+ `;
89
+ fs.writeFileSync(targetPath, wrapperContent);
90
+ fs.chmodSync(targetPath, "755");
91
+ console.log("✅ Created wrapper script");
92
+ } catch (wrapperError) {
93
+ console.error(`❌ Failed to create wrapper: ${wrapperError.message}`);
94
+ process.exit(1);
95
+ }
189
96
  }
190
97
 
191
- console.log('🎉 All tests passed! Calculator CLI is working correctly.');
192
- ```
193
-
194
- <file_path>
195
- calculator-cli/index.js
196
- </file_path>
197
-
198
- <edit_description>
199
- Create simple entry point
200
- </edit_description>
201
-
202
- ```javascript
203
- #!/usr/bin/env node
204
-
205
- // Entry point for the calculator-cli npm package
206
- // This file is minimal because the actual binary handles all functionality
207
-
208
- console.log('calculator-cli v0.1.0');
209
- console.log('Run "calculator <expression>" to use the calculator');
210
- ```
211
-
212
- <file_path>
213
- calculator-cli/README.md
214
- </file_path>
215
-
216
- <edit_description>
217
- Create simple README for v0.1 release
218
- </edit_description>
219
-
220
- ```markdown
221
- # Calculator CLI v0.1.0
222
-
223
- A lightweight command-line calculator with symbolic math support, available for Windows and Linux x64 platforms.
224
-
225
- ## Quick Start
226
-
227
- 1. Install: `npm install -g calculator-cli`
228
- 2. Run: `calculator "2 + 2"` or `calculator "x^2-4=0"`
229
- 3. For interactive mode: `calculator` (no arguments)
230
-
231
- ## Features
232
-
233
- - Basic arithmetic operations
234
- - Equation solving
235
- - Complex number support
236
- - Fraction and symbolic output when possible
237
-
238
- ## Supported Platforms
239
-
240
- - Windows (x64)
241
- - Linux (x64)
242
-
243
- ## Usage Examples
244
-
245
- ```bash
246
- # Basic calculations
247
- calculator "2 + 2"
248
- calculator "3 * (4 + 5)"
249
-
250
- # Equation solving
251
- calculator "x^2-4=0"
252
- calculator "x+y=5, x-y=1"
253
-
254
- # Complex numbers
255
- calculator "sqrt(-4)"
256
- calculator "(3+2i) * (1-i)"
257
- ```
258
-
259
- ## Installation Notes
260
-
261
- This package includes precompiled binaries for Windows and Linux x64. No Rust toolchain is required.
262
-
263
- ## License
264
-
265
- MIT License
98
+ console.log("✅ Installation complete!");
99
+ console.log(`You can now run 'mathcalc' in your terminal.`);
@@ -4,14 +4,14 @@ const path = require("path");
4
4
  const fs = require("fs");
5
5
  const os = require("os");
6
6
 
7
- console.log("🔍 Validating calculator-cli installation...");
7
+ console.log("🔍 Validating mathcalc-cli installation...");
8
8
 
9
9
  // Platform detection
10
10
  const platform = os.platform();
11
11
  const expectedBinary =
12
12
  platform === "win32"
13
13
  ? "calculator_windows-x86-64.exe"
14
- : "calculator_linux-x64";
14
+ : "calculator-linux-x64";
15
15
 
16
16
  const binaryPath = path.join(__dirname, "..", "bin", expectedBinary);
17
17
 
@@ -24,4 +24,4 @@ if (!os.arch().includes("64")) {
24
24
  console.warn("⚠️ Warning: 64-bit architecture recommended");
25
25
  }
26
26
 
27
- console.log("✅ Calculator CLI v0.1.0 is ready!");
27
+ console.log("✅ MathCalc CLI v0.2.0 is ready!");
package/scripts/test.js CHANGED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawnSync } = require("child_process");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const os = require("os");
7
+
8
+ console.log("🧪 Testing calculator-cli package functionality...\n");
9
+
10
+ // Platform detection
11
+ const platform = os.platform();
12
+ const binaryName =
13
+ platform === "win32"
14
+ ? "calculator_windows-x86-64.exe"
15
+ : "calculator-linux-x64";
16
+
17
+ const binaryPath = path.join(__dirname, "..", "bin", binaryName);
18
+
19
+ // Test 1: Check if binary exists
20
+ console.log("1. Checking binary existence...");
21
+ if (!fs.existsSync(binaryPath)) {
22
+ console.error(`❌ Binary not found: ${binaryName}`);
23
+ process.exit(1);
24
+ }
25
+ console.log(`✅ Found binary: ${binaryName}`);
26
+
27
+ // Test 2: Test basic calculation
28
+ console.log("\n2. Testing basic calculation: 2 + 2");
29
+ try {
30
+ const result = spawnSync(binaryPath, ["2 + 2"], { encoding: "utf8" });
31
+
32
+ if (result.status === 0) {
33
+ console.log(`✅ Calculation result: ${result.stdout.trim()}`);
34
+ } else {
35
+ console.error(`❌ Calculation failed with status ${result.status}`);
36
+ console.error(`Error output: ${result.stderr}`);
37
+ process.exit(1);
38
+ }
39
+ } catch (error) {
40
+ console.error(`❌ Failed to run binary: ${error.message}`);
41
+ process.exit(1);
42
+ }
43
+
44
+ // Test 3: Test equation solving
45
+ console.log("\n3. Testing equation solving: x^2-4=0");
46
+ try {
47
+ const equationResult = spawnSync(binaryPath, ["x^2-4=0"], {
48
+ encoding: "utf8",
49
+ });
50
+
51
+ if (equationResult.status === 0) {
52
+ console.log(`✅ Equation result: ${equationResult.stdout.trim()}`);
53
+ } else {
54
+ console.error(
55
+ `❌ Equation solving failed with status ${equationResult.status}`,
56
+ );
57
+ console.error(`Error output: ${equationResult.stderr}`);
58
+ process.exit(1);
59
+ }
60
+ } catch (error) {
61
+ console.error(`❌ Failed to solve equation: ${error.message}`);
62
+ process.exit(1);
63
+ }
64
+
65
+ // Test 4: Test complex numbers
66
+ console.log("\n4. Testing complex numbers: sqrt(-4)");
67
+ try {
68
+ const complexResult = spawnSync(binaryPath, ["sqrt(-4)"], {
69
+ encoding: "utf8",
70
+ });
71
+
72
+ if (complexResult.status === 0) {
73
+ console.log(`✅ Complex number result: ${complexResult.stdout.trim()}`);
74
+ } else {
75
+ console.error(
76
+ `❌ Complex number calculation failed with status ${complexResult.status}`,
77
+ );
78
+ console.error(`Error output: ${complexResult.stderr}`);
79
+ process.exit(1);
80
+ }
81
+ } catch (error) {
82
+ console.error(`❌ Failed to calculate complex number: ${error.message}`);
83
+ process.exit(1);
84
+ }
85
+
86
+ // Test 5: Test index.js entry point
87
+ console.log("\n5. Testing index.js entry point...");
88
+ try {
89
+ const indexResult = spawnSync(
90
+ "node",
91
+ [path.join(__dirname, "..", "index.js"), "--help"],
92
+ { encoding: "utf8" },
93
+ );
94
+
95
+ if (indexResult.status === 0) {
96
+ console.log("✅ index.js help command works");
97
+ } else {
98
+ console.log(
99
+ `ℹ️ index.js returned status ${indexResult.status} (this may be expected)`,
100
+ );
101
+ }
102
+ } catch (error) {
103
+ console.error(`❌ Failed to run index.js: ${error.message}`);
104
+ process.exit(1);
105
+ }
106
+
107
+ console.log("\n🎉 All tests passed! Calculator CLI is ready for distribution.");
@@ -1,482 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /*
4
- * Local build script for generating platform-specific binaries for npm distribution
5
- * This script is designed for local compilation across multiple platforms
6
- *
7
- * To build for all platforms locally, you'll need:
8
- * - Rust toolchains: x86_64-pc-windows-gnu, x86_64-apple-darwin, x86_64-unknown-linux-gnu
9
- * - Cross-compilation tools for Windows (mingw-w64) on Linux/macOS
10
- */
11
-
12
- const path = require("path");
13
- const { execSync } = require("child_process");
14
- const fs = require("fs");
15
-
16
- // Target platforms and their output files
17
- const platforms = [
18
- {
19
- target: "x86_64-unknown-linux-gnu",
20
- outputFile: "calculator-linux-x64",
21
- canBuildOn: ["linux"],
22
- },
23
- {
24
- target: "x86_64-pc-windows-gnu",
25
- outputFile: "calculator-win32-x64.exe",
26
- canBuildOn: ["linux", "macos", "windows"],
27
- requires: {
28
- linux: "x86_64-w64-mingw32-gcc",
29
- macos: "x86_64-w64-mingw32-gcc",
30
- },
31
- },
32
- {
33
- target: "x86_64-apple-darwin",
34
- outputFile: "calculator-darwin-x64",
35
- canBuildOn: ["macos"],
36
- },
37
- ];
38
-
39
- console.log("🔨 Building calculator-cli binaries for npm distribution...\n");
40
-
41
- // Check if Cargo.toml exists
42
- const projectRoot = path.join(__dirname, "..");
43
- if (!fs.existsSync(path.join(projectRoot, "Cargo.toml"))) {
44
- console.error("❌ Cargo.toml not found in project root");
45
- console.log("Make sure this script is run from the correct directory");
46
- process.exit(1);
47
- }
48
-
49
- // Detect current platform and WSL environment
50
- const detectCurrentPlatform = () => {
51
- const platform = process.platform;
52
- if (platform === "linux") return "linux";
53
- if (platform === "darwin") return "macos";
54
- if (platform === "win32") return "windows";
55
- return "unknown";
56
- };
57
-
58
- // Check if running in WSL
59
- const isWSL = () => {
60
- try {
61
- return (
62
- fs
63
- .readFileSync("/proc/version", "utf8")
64
- .toLowerCase()
65
- .includes("microsoft") ||
66
- process.env.WSL_DISTRO_NAME !== undefined
67
- );
68
- } catch (e) {
69
- return false;
70
- }
71
- };
72
-
73
- const currentPlatform = detectCurrentPlatform();
74
- const inWSL = currentPlatform === "linux" && isWSL();
75
- console.log(
76
- `📍 Detected current platform: ${currentPlatform}${inWSL ? " (in WSL)" : ""}\n`,
77
- );
78
-
79
- // Helper function to check if a command is available
80
- const commandExists = (command) => {
81
- try {
82
- execSync(`which ${command}`, { stdio: "ignore" });
83
- return true;
84
- } catch (e) {
85
- return false;
86
- }
87
- };
88
-
89
- // Helper function to check if a target is installed
90
- const isTargetInstalled = (target) => {
91
- try {
92
- const list = execSync("rustup target list --installed", {
93
- encoding: "utf8",
94
- });
95
- return list.includes(target);
96
- } catch (e) {
97
- return false;
98
- }
99
- };
100
-
101
- try {
102
- // Get version from Cargo.toml
103
- const cargoContent = fs.readFileSync(
104
- path.join(projectRoot, "Cargo.toml"),
105
- "utf8",
106
- );
107
- const versionMatch = cargoContent.match(/^version\s*=\s*"([^"]+)"/m);
108
- const version = versionMatch ? versionMatch[1] : "2.0.0";
109
- console.log(`Found version: ${version}\n`);
110
-
111
- // Create bin directory if it doesn't exist
112
- const binDir = path.join(projectRoot, "bin");
113
- if (!fs.existsSync(binDir)) {
114
- fs.mkdirSync(binDir, { recursive: true });
115
- console.log(`Created bin directory: ${binDir}\n`);
116
- }
117
-
118
- // Filter platforms that can be built on current platform
119
- const buildablePlatforms = platforms.filter((platform) =>
120
- platform.canBuildOn.includes(currentPlatform),
121
- );
122
-
123
- if (buildablePlatforms.length === 0) {
124
- console.log(`⚠️ No platforms can be built on ${currentPlatform}`);
125
- console.log("This script supports:");
126
-
127
- platforms.forEach((platform) => {
128
- console.log(
129
- `- ${platform.target}: ${platform.canBuildOn.join(", ")}`,
130
- );
131
- });
132
-
133
- console.log("\n💡 Consider using a different platform or a CI service");
134
- process.exit(1);
135
- }
136
-
137
- let successfulBuilds = 0;
138
-
139
- // Build for each buildable target platform
140
- for (const platform of buildablePlatforms) {
141
- console.log(`📦 Building for ${platform.target}...`);
142
-
143
- // Check if the target is installed
144
- if (!isTargetInstalled(platform.target)) {
145
- console.log(`❌ Rust target '${platform.target}' not installed`);
146
- console.log(`💡 Installing target now...`);
147
-
148
- try {
149
- execSync(`rustup target add ${platform.target}`, {
150
- stdio: "inherit",
151
- maxBuffer: 10 * 1024 * 1024,
152
- });
153
- console.log(
154
- `✅ Target '${platform.target}' installed successfully\n`,
155
- );
156
- } catch (error) {
157
- console.log(`❌ Failed to install target: ${error.message}`);
158
- console.log(
159
- `💡 Please install manually: rustup target add ${platform.target}\n`,
160
- );
161
- continue;
162
- }
163
- }
164
-
165
- // Check for required tools
166
- if (platform.requires && platform.requires[currentPlatform]) {
167
- const requiredTool = platform.requires[currentPlatform];
168
- if (!commandExists(requiredTool)) {
169
- console.log(`❌ Required tool '${requiredTool}' not found`);
170
-
171
- // Provide installation instructions
172
- if (
173
- currentPlatform === "linux" &&
174
- platform.target.includes("windows")
175
- ) {
176
- console.log("💡 To install on Linux/Ubuntu:");
177
- console.log(" sudo apt-get update");
178
- console.log(" sudo apt-get install mingw-w64");
179
- console.log(" # For Debian:");
180
- console.log(" sudo apt-get install gcc-mingw-w64-x86-64");
181
- } else if (
182
- currentPlatform === "macos" &&
183
- platform.target.includes("windows")
184
- ) {
185
- console.log("💡 To install on macOS:");
186
- console.log(" brew install mingw-w64");
187
- }
188
-
189
- console.log("");
190
- continue;
191
- }
192
- }
193
-
194
- try {
195
- // Set environment variables for cross-compilation if needed
196
- const env = { ...process.env };
197
-
198
- // Configure environment for cross-compilation
199
- const env = { ...process.env };
200
- if (
201
- platform.target === "x86_64-pc-windows-gnu" &&
202
- currentPlatform !== "windows"
203
- ) {
204
- // Set the linker for Windows cross-compilation
205
- env.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER =
206
- "x86_64-w64-mingw32-gcc";
207
- env.CC_x86_64_pc_windows_gnu = "x86_64-w64-mingw32-gcc";
208
- env.CXX_x86_64_pc_windows_gnu = "x86_64-w64-mingw32-g++";
209
-
210
- // WSL-specific settings
211
- if (inWSL) {
212
- console.log(
213
- " 🐧 Applying WSL-specific settings for Windows target",
214
- );
215
- // Additional linker flags for WSL
216
- env.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS =
217
- "-C link-arg=-Wl,--subsystem,console -C link-arg=-static";
218
-
219
- // Try alternative linking strategy for WSL
220
- if (process.env.USE_MSVC_TOOLCHAIN) {
221
- console.log(
222
- " Using MSVC toolchain for Windows target",
223
- );
224
- env.RUSTUP_TOOLCHAIN = "stable-x86_64-pc-windows-msvc";
225
- }
226
- }
227
- }
228
-
229
- // Build the binary
230
- const buildCmd = `cargo build --release --target ${platform.target}`;
231
- console.log(` Running: ${buildCmd}`);
232
-
233
- // Use inherit stdio and increased buffer to avoid ENOBUFS errors
234
- execSync(buildCmd, {
235
- stdio: "inherit",
236
- env,
237
- cwd: projectRoot,
238
- maxBuffer: 10 * 1024 * 1024, // 10MB buffer
239
- });
240
-
241
- // Copy the binary to the bin directory
242
- const sourcePath = path.join(
243
- projectRoot,
244
- "target",
245
- platform.target,
246
- "release",
247
- "calculator",
248
- );
249
-
250
- // For Windows, the binary has .exe extension
251
- const windowsSourcePath = path.join(
252
- projectRoot,
253
- "target",
254
- platform.target,
255
- "release",
256
- "calculator.exe",
257
- );
258
-
259
- const finalSourcePath = platform.target.includes("windows")
260
- ? windowsSourcePath
261
- : sourcePath;
262
- const destPath = path.join(binDir, platform.outputFile);
263
-
264
- // Verify source exists
265
- if (!fs.existsSync(finalSourcePath)) {
266
- throw new Error(
267
- `Binary not found at expected path: ${finalSourcePath}`,
268
- );
269
- }
270
-
271
- // Copy binary
272
- fs.copyFileSync(finalSourcePath, destPath);
273
-
274
- // On Unix-like systems, make sure the binary is executable
275
- if (!platform.target.includes("windows")) {
276
- try {
277
- fs.chmodSync(destPath, "755");
278
- } catch (error) {
279
- console.warn(
280
- `Warning: Could not set executable permissions: ${error.message}`,
281
- );
282
- }
283
- }
284
-
285
- console.log(`✅ Built and copied to: ${destPath}\n`);
286
- successfulBuilds++;
287
- } catch (error) {
288
- console.error(
289
- `❌ Failed to build for ${platform.target}: ${error.message}`,
290
- );
291
-
292
- // Provide specific help for common errors
293
- if (
294
- error.message.includes("E0425") ||
295
- error.message.includes("E0431") ||
296
- error.message.includes("linker") ||
297
- error.message.includes("undefined reference")
298
- ) {
299
- console.log("");
300
- console.log(
301
- "💡 This appears to be a linker error (E0425/E0431). Solutions:",
302
- );
303
-
304
- if (platform.target.includes("windows")) {
305
- console.log("1. For WSL MinGW issues, try these steps:");
306
- if (inWSL) {
307
- console.log(" 🐧 WSL-specific solutions:");
308
- console.log(" a) Install complete MinGW toolchain:");
309
- console.log(
310
- " sudo apt-get update && sudo apt-get install mingw-w64 gcc-mingw-w64-x86-64",
311
- );
312
- console.log("");
313
- console.log(" b) Set environment variables for WSL:");
314
- console.log(
315
- " export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc",
316
- );
317
- console.log(
318
- " export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc",
319
- );
320
- console.log(
321
- " export CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++",
322
- );
323
- console.log("");
324
- console.log(
325
- " c) Alternative: Use Windows native Rust:",
326
- );
327
- console.log(
328
- " rustup toolchain install stable-x86_64-pc-windows-msvc",
329
- );
330
- console.log(
331
- " rustup default stable-x86_64-pc-windows-msvc",
332
- );
333
- console.log(
334
- " rustup target add x86_64-pc-windows-msvc",
335
- );
336
- console.log("");
337
- console.log(
338
- " d) For persistent configuration, add to ~/.bashrc:",
339
- );
340
- console.log(" [target.x86_64-pc-windows-gnu]");
341
- console.log(" linker = 'x86_64-w64-mingw32-gcc'");
342
- console.log(" ");
343
- console.log(" [target.x86_64-pc-windows-msvc]");
344
- console.log(" linker = 'lld-link'");
345
- } else {
346
- console.log(
347
- " sudo apt-get update && sudo apt-get install mingw-w64",
348
- );
349
- }
350
-
351
- console.log("");
352
- console.log(
353
- "2. Try reinstalling and reconfiguring Rust targets:",
354
- );
355
- console.log(
356
- " rustup target remove --toolchain stable x86_64-pc-windows-gnu",
357
- );
358
- console.log(
359
- " rustup target add --toolchain stable x86_64-pc-windows-gnu",
360
- );
361
- console.log(" # Or try MSVC target:");
362
- console.log(" rustup target add x86_64-pc-windows-msvc");
363
-
364
- if (inWSL) {
365
- console.log("");
366
- console.log("🐧 WSL Specific Tips:");
367
- console.log(
368
- " - WSL MinGW builds can be tricky. Consider using:",
369
- );
370
- console.log(
371
- " * Windows Subsystem for Linux with Windows Rust installed in Windows",
372
- );
373
- console.log(
374
- " * The MSVC target which might be more stable in WSL",
375
- );
376
- console.log(
377
- " * Running the build directly in Windows instead of WSL",
378
- );
379
- }
380
-
381
- console.log("");
382
- console.log("3. Alternative approaches:");
383
- console.log(" - Build in native Windows environment");
384
- console.log(
385
- " - Use GitHub Actions or another CI service",
386
- );
387
- console.log(
388
- " - Focus on platforms that build successfully",
389
- );
390
- }
391
- } else if (error.message.includes("could not find")) {
392
- console.log("");
393
- console.log(`💡 Rust target not found. To install:`);
394
- console.log(` rustup target add ${platform.target}`);
395
- console.log("");
396
- console.log("To see all installed targets:");
397
- console.log(" rustup target list --installed");
398
- }
399
-
400
- console.log("");
401
- }
402
- }
403
-
404
- // Build summary
405
- console.log("📋 Build Summary:");
406
- platforms.forEach((platform) => {
407
- const destPath = path.join(binDir, platform.outputFile);
408
- if (fs.existsSync(destPath)) {
409
- console.log(`✅ ${platform.outputFile}`);
410
- } else {
411
- const canBuild = platform.canBuildOn.includes(currentPlatform)
412
- ? "buildable"
413
- : "requires different platform";
414
- console.log(`❌ ${platform.outputFile} (${canBuild})`);
415
- }
416
- });
417
-
418
- console.log(
419
- `\nSuccessfully built ${successfulBuilds} out of ${buildablePlatforms.length} platforms`,
420
- );
421
-
422
- if (successfulBuilds === 0) {
423
- console.log("\n❌ No binaries were built successfully");
424
- console.log("\n💡 Troubleshooting:");
425
- console.log("1. Install missing Rust targets:");
426
- buildablePlatforms.forEach((platform) => {
427
- console.log(` rustup target add ${platform.target}`);
428
- });
429
- console.log("\n2. Install cross-compilation tools:");
430
- if (currentPlatform === "linux") {
431
- console.log(
432
- " sudo apt-get update && sudo apt-get install mingw-w64",
433
- );
434
- } else if (currentPlatform === "macos") {
435
- console.log(" brew install mingw-w64");
436
- }
437
- console.log("\n3. See LOCAL_BUILD_GUIDE.md for detailed instructions");
438
- console.log("\n4. Consider building only for your current platform");
439
- } else {
440
- console.log("\n✅ Build completed successfully!");
441
- }
442
-
443
- console.log("\n📦 Next steps:");
444
- if (successfulBuilds > 0) {
445
- console.log("1. Test the package: node test-package.js");
446
- console.log("2. Create package: npm run prepare-package");
447
- console.log("3. Test locally: npm run local-test");
448
- console.log("4. Publish to npm: npm publish");
449
- console.log(
450
- "\n💡 Remember to update the version number in Cargo.toml before publishing!",
451
- );
452
-
453
- if (inWSL) {
454
- console.log("\n🐧 WSL-Specific Tips:");
455
- console.log("- Windows binaries are accessible from Windows at:");
456
- console.log(
457
- ` \\\\wsl$\\$(hostname)\\${path
458
- .resolve(projectRoot)
459
- .replace(/^\/mnt\//, "")
460
- .replace(/\//g, "\\")}\\bin`,
461
- );
462
- console.log(
463
- "- Test Windows binaries directly in Windows Command Prompt or PowerShell",
464
- );
465
- }
466
- } else {
467
- console.log("1. Fix the build issues shown above");
468
- console.log("2. Try building for fewer platforms");
469
- console.log("3. Consider building only for your current platform");
470
-
471
- if (inWSL) {
472
- console.log("\n🐧 WSL-Specific Tips:");
473
- console.log("- Ensure you have the latest mingw-w64 packages");
474
- console.log(
475
- "- Try running the build script from /mnt/c/ to avoid WSL path limitations",
476
- );
477
- }
478
- }
479
- } catch (error) {
480
- console.error(`❌ Build process failed: ${error.message}`);
481
- process.exit(1);
482
- }
@@ -1,148 +0,0 @@
1
- #!/bin/bash
2
-
3
- # WSL Windows Build Fix Script
4
- # This script helps resolve E4025 and E4031 linker errors when building Windows binaries in WSL
5
-
6
- echo "🐧 WSL Windows Build Fix Script"
7
- echo "================================"
8
- echo ""
9
-
10
- # Check if we're in WSL
11
- if ! grep -qi microsoft /proc/version; then
12
- echo "⚠️ This script is optimized for WSL but can run on other Linux systems"
13
- fi
14
-
15
- # Install complete MinGW toolchain
16
- echo "🔧 Installing complete MinGW toolchain..."
17
- sudo apt-get update
18
- sudo apt-get install -y \
19
- mingw-w64 \
20
- gcc-mingw-w64-x86-64 \
21
- gcc-mingw-w64-i686 \
22
- binutils-mingw-w64-x86-64 \
23
- binutils-mingw-w64-i686 \
24
- mingw-w64-tools \
25
- mingw-w64-x86-64-dev \
26
- g++-mingw-w64-x86-64
27
-
28
- # Create Cargo config directory if it doesn't exist
29
- echo ""
30
- echo "📝 Configuring Cargo for cross-compilation..."
31
- mkdir -p ~/.cargo
32
-
33
- # Create or update Cargo config.toml
34
- cat > ~/.cargo/config.toml << 'EOF'
35
- [target.x86_64-pc-windows-gnu]
36
- linker = "x86_64-w64-mingw32-gcc"
37
- ar = "x86_64-w64-mingw32-ar"
38
-
39
- [target.x86_64-pc-windows-gnu.env]
40
- CC_x86_64_pc_windows_gnu = "x86_64-w64-mingw32-gcc"
41
- CXX_x86_64_pc_windows_gnu = "x86_64-w64-mingw32-g++"
42
- AR_x86_64_pc_windows_gnu = "x86_64-w64-mingw32-ar"
43
-
44
- [target.i686-pc-windows-gnu]
45
- linker = "i686-w64-mingw32-gcc"
46
- ar = "i686-w64-mingw32-ar"
47
-
48
- [target.i686-pc-windows-gnu.env]
49
- CC_i686_pc_windows_gnu = "i686-w64-mingw32-gcc"
50
- CXX_i686_pc_windows_gnu = "i686-w64-mingw32-g++"
51
- AR_i686_pc_windows_gnu = "i686-w64-mingw32-ar"
52
- EOF
53
-
54
- # Set environment variables for current session
55
- echo ""
56
- echo "🔧 Setting environment variables..."
57
- export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
58
- export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
59
- export CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++
60
- export AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar
61
-
62
- # Add to ~/.bashrc for persistence
63
- echo ""
64
- echo "💾 Adding environment variables to ~/.bashrc..."
65
- cat >> ~/.bashrc << 'EOF'
66
-
67
- # Rust cross-compilation for Windows in WSL
68
- export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
69
- export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
70
- export CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++
71
- export AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar
72
- EOF
73
-
74
- # Add to ~/.zshrc if zsh is used
75
- if [ -f ~/.zshrc ]; then
76
- echo ""
77
- echo "💾 Adding environment variables to ~/.zshrc..."
78
- cat >> ~/.zshrc << 'EOF'
79
-
80
- # Rust cross-compilation for Windows in WSL
81
- export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
82
- export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
83
- export CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++
84
- export AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar
85
- EOF
86
- fi
87
-
88
- # Verify installation
89
- echo ""
90
- echo "🔍 Verifying installation..."
91
- if command -v x86_64-w64-mingw32-gcc &> /dev/null; then
92
- echo "✅ MinGW GCC found"
93
- echo " Version: $(x86_64-w64-mingw32-gcc --version | head -1)"
94
- else
95
- echo "❌ MinGW GCC not found"
96
- fi
97
-
98
- if command -v x86_64-w64-mingw32-ar &> /dev/null; then
99
- echo "✅ MinGW AR found"
100
- else
101
- echo "❌ MinGW AR not found"
102
- fi
103
-
104
- # Install or update Rust targets
105
- echo ""
106
- echo "🔧 Installing Rust targets..."
107
- rustup target add x86_64-pc-windows-gnu
108
- rustup target add i686-pc-windows-gnu
109
-
110
- # Test compilation with a simple C program
111
- echo ""
112
- echo "🧪 Testing MinGW with a simple program..."
113
- cat > test_minGW.c << 'EOF'
114
- #include <stdio.h>
115
-
116
- int main() {
117
- printf("Hello from Windows binary built in WSL!\n");
118
- return 0;
119
- }
120
- EOF
121
-
122
- # Compile with MinGW
123
- if x86_64-w64-mingw32-gcc -o test_minGW.exe test_minGW.c 2>/dev/null; then
124
- echo "✅ MinGW test compilation successful"
125
- echo " Output: $(./test_minGW.exe 2>/dev/null || echo 'Binary created, needs Windows to run')"
126
- rm -f test_minGW.exe test_minGW.c
127
- else
128
- echo "❌ MinGW test compilation failed"
129
- echo " You may need to restart your terminal or source your shell configuration"
130
- fi
131
-
132
- # Clean up
133
- rm -f test_minGW.c
134
-
135
- echo ""
136
- echo "🎉 WSL Windows build fix completed!"
137
- echo ""
138
- echo "📋 Next steps:"
139
- echo "1. Restart your terminal or run: source ~/.bashrc"
140
- echo "2. Try building Windows binary: npm run build-windows"
141
- echo "3. If you still have issues, try: npm run build-windows-static"
142
- echo ""
143
- echo "🔧 Additional options if problems persist:"
144
- echo "- Use MSVC toolchain: rustup toolchain install stable-x86_64-pc-windows-msvc"
145
- echo "- Build in native Windows environment"
146
- echo "- Use GitHub Actions for automated builds"
147
- echo ""
148
- echo "💡 For more help, see: WSL_BUILD_GUIDE.md"