✨ Support packaging of multiple systems including Linux/Windows
This commit is contained in:
29
bin/README.md
vendored
29
bin/README.md
vendored
@@ -19,6 +19,8 @@ npm install pake-cli -g
|
||||
4. Microsoft Visual C++ 2013 Redistributable (x86) (optional)
|
||||
5. Microsoft Visual C++ 2008 Redistributable (x86) (optional)
|
||||
|
||||
**For Windows on ARM (ARM64) support**: Install the C++ ARM64 build tools in Visual Studio Installer under "Individual Components" → "MSVC v143 - VS 2022 C++ ARM64 build tools". The system will automatically detect ARM64 architecture and build native ARM64 binaries.
|
||||
|
||||
- For Ubuntu users, execute the following commands to install the required libraries before compiling:
|
||||
|
||||
```bash
|
||||
@@ -188,12 +190,35 @@ Package the application to support both Intel and M1 chips, exclusively for macO
|
||||
|
||||
#### [targets]
|
||||
|
||||
Choose the output package format, supporting `deb`, `appimage`, `rpm`. This option is only applicable to Linux and defaults to `deb`.
|
||||
Specify the build target architecture or format:
|
||||
|
||||
- **Linux**: `deb`, `appimage`, `deb-arm64`, `appimage-arm64` (default: `deb`)
|
||||
- **Windows**: `x64`, `arm64` (auto-detects if not specified)
|
||||
- **macOS**: `intel`, `apple`, `universal` (auto-detects if not specified)
|
||||
|
||||
```shell
|
||||
--targets <format>
|
||||
--targets <target>
|
||||
|
||||
# Examples:
|
||||
--targets arm64 # Windows ARM64
|
||||
--targets x64 # Windows x64
|
||||
--targets universal # macOS Universal (Intel + Apple Silicon)
|
||||
--targets apple # macOS Apple Silicon only
|
||||
--targets intel # macOS Intel only
|
||||
--targets deb # Linux DEB package (x64)
|
||||
--targets rpm # Linux RPM package (x64)
|
||||
--targets appimage # Linux AppImage (x64)
|
||||
--targets deb-arm64 # Linux DEB package (ARM64)
|
||||
--targets rpm-arm64 # Linux RPM package (ARM64)
|
||||
--targets appimage-arm64 # Linux AppImage (ARM64)
|
||||
```
|
||||
|
||||
**Note for Linux ARM64**:
|
||||
|
||||
- Cross-compilation requires additional setup. Install `gcc-aarch64-linux-gnu` and configure environment variables for cross-compilation.
|
||||
- ARM64 support enables Pake apps to run on ARM-based Linux devices, including Linux phones (postmarketOS, Ubuntu Touch), Raspberry Pi, and other ARM64 Linux systems.
|
||||
- Use `--target appimage-arm64` for portable ARM64 applications that work across different ARM64 Linux distributions.
|
||||
|
||||
#### [user-agent]
|
||||
|
||||
Customize the browser user agent. Default is empty.
|
||||
|
||||
29
bin/README_CN.md
vendored
29
bin/README_CN.md
vendored
@@ -19,6 +19,8 @@ npm install pake-cli -g
|
||||
4. Microsoft Visual C++ 2013 Redistributable (x86)(可选)
|
||||
5. Microsoft Visual C++ 2008 Redistributable (x86)(可选)
|
||||
|
||||
**Windows ARM(ARM64)支持**:在 Visual Studio Installer 中的"单个组件"下安装"MSVC v143 - VS 2022 C++ ARM64 构建工具"。系统会自动检测 ARM64 架构并构建原生 ARM64 二进制文件。
|
||||
|
||||
- 对于 Ubuntu 用户,在开始之前,建议运行以下命令以安装所需的依赖项:
|
||||
|
||||
```bash
|
||||
@@ -188,12 +190,35 @@ pake [url] [options]
|
||||
|
||||
#### [targets]
|
||||
|
||||
选择输出的包格式,支持 `deb`、`appimage`、`rpm`,此选项仅适用于 Linux,默认为 `deb`。
|
||||
指定构建目标架构或格式:
|
||||
|
||||
- **Linux**: `deb`, `appimage`, `deb-arm64`, `appimage-arm64`(默认:`deb`)
|
||||
- **Windows**: `x64`, `arm64`(未指定时自动检测)
|
||||
- **macOS**: `intel`, `apple`, `universal`(未指定时自动检测)
|
||||
|
||||
```shell
|
||||
--targets <string>
|
||||
--targets <target>
|
||||
|
||||
# 示例:
|
||||
--targets arm64 # Windows ARM64
|
||||
--targets x64 # Windows x64
|
||||
--targets universal # macOS 通用版本(Intel + Apple Silicon)
|
||||
--targets apple # 仅 macOS Apple Silicon
|
||||
--targets intel # 仅 macOS Intel
|
||||
--targets deb # Linux DEB 包(x64)
|
||||
--targets rpm # Linux RPM 包(x64)
|
||||
--targets appimage # Linux AppImage(x64)
|
||||
--targets deb-arm64 # Linux DEB 包(ARM64)
|
||||
--targets rpm-arm64 # Linux RPM 包(ARM64)
|
||||
--targets appimage-arm64 # Linux AppImage(ARM64)
|
||||
```
|
||||
|
||||
**Linux ARM64 注意事项**:
|
||||
|
||||
- 交叉编译需要额外设置。需要安装 `gcc-aarch64-linux-gnu` 并配置交叉编译环境变量。
|
||||
- ARM64 支持让 Pake 应用可以在基于 ARM 的 Linux 设备上运行,包括 Linux 手机(postmarketOS、Ubuntu Touch)、树莓派和其他 ARM64 Linux 系统。
|
||||
- 使用 `--target appimage-arm64` 可以创建便携式 ARM64 应用,在不同的 ARM64 Linux 发行版上运行。
|
||||
|
||||
#### [user-agent]
|
||||
|
||||
自定义浏览器的用户代理请求头,默认为空。
|
||||
|
||||
63
bin/builders/LinuxBuilder.ts
vendored
63
bin/builders/LinuxBuilder.ts
vendored
@@ -1,19 +1,43 @@
|
||||
import path from 'path';
|
||||
import BaseBuilder from './BaseBuilder';
|
||||
import { PakeAppOptions } from '@/types';
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
|
||||
export default class LinuxBuilder extends BaseBuilder {
|
||||
private buildFormat: string;
|
||||
private buildArch: string;
|
||||
|
||||
constructor(options: PakeAppOptions) {
|
||||
super(options);
|
||||
|
||||
// Parse target format and architecture
|
||||
const target = options.targets || 'deb';
|
||||
if (target.includes('-arm64')) {
|
||||
this.buildFormat = target.replace('-arm64', '');
|
||||
this.buildArch = 'arm64';
|
||||
} else {
|
||||
this.buildFormat = target;
|
||||
this.buildArch = 'auto';
|
||||
}
|
||||
|
||||
// Set targets to format for Tauri
|
||||
this.options.targets = this.buildFormat;
|
||||
}
|
||||
|
||||
getFileName() {
|
||||
const { name, targets } = this.options;
|
||||
const version = tauriConfig.version;
|
||||
|
||||
let arch = process.arch === 'x64' ? 'amd64' : process.arch;
|
||||
if (arch === 'arm64' && (targets === 'rpm' || targets === 'appimage')) {
|
||||
arch = 'aarch64';
|
||||
// Determine architecture based on explicit target or auto-detect
|
||||
let arch: string;
|
||||
if (this.buildArch === 'arm64') {
|
||||
arch = targets === 'rpm' || targets === 'appimage' ? 'aarch64' : 'arm64';
|
||||
} else {
|
||||
// Auto-detect or default to current architecture
|
||||
arch = process.arch === 'x64' ? 'amd64' : process.arch;
|
||||
if (arch === 'arm64' && (targets === 'rpm' || targets === 'appimage')) {
|
||||
arch = 'aarch64';
|
||||
}
|
||||
}
|
||||
|
||||
// The RPM format uses different separators and version number formats
|
||||
@@ -34,6 +58,39 @@ export default class LinuxBuilder extends BaseBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
protected getBuildCommand(): string {
|
||||
const baseCommand = this.options.debug
|
||||
? 'npm run build:debug'
|
||||
: 'npm run build';
|
||||
|
||||
// Use temporary config directory to avoid modifying source files
|
||||
const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
|
||||
let fullCommand = `${baseCommand} -- -c "${configPath}"`;
|
||||
|
||||
// Add ARM64 target if explicitly specified
|
||||
if (this.buildArch === 'arm64') {
|
||||
fullCommand += ' --target aarch64-unknown-linux-gnu';
|
||||
}
|
||||
|
||||
// Add features
|
||||
const features = ['cli-build'];
|
||||
if (features.length > 0) {
|
||||
fullCommand += ` --features ${features.join(',')}`;
|
||||
}
|
||||
|
||||
return fullCommand;
|
||||
}
|
||||
|
||||
protected getBasePath(): string {
|
||||
const basePath = this.options.debug ? 'debug' : 'release';
|
||||
|
||||
if (this.buildArch === 'arm64') {
|
||||
return `src-tauri/target/aarch64-unknown-linux-gnu/${basePath}/bundle/`;
|
||||
}
|
||||
|
||||
return super.getBasePath();
|
||||
}
|
||||
|
||||
protected getFileType(target: string): string {
|
||||
if (target === 'appimage') {
|
||||
return 'AppImage';
|
||||
|
||||
84
bin/builders/MacBuilder.ts
vendored
84
bin/builders/MacBuilder.ts
vendored
@@ -4,37 +4,56 @@ import { PakeAppOptions } from '@/types';
|
||||
import BaseBuilder from './BaseBuilder';
|
||||
|
||||
export default class MacBuilder extends BaseBuilder {
|
||||
private buildFormat: string;
|
||||
private buildArch: string;
|
||||
|
||||
constructor(options: PakeAppOptions) {
|
||||
super(options);
|
||||
|
||||
// Store the original targets value for architecture selection
|
||||
this.buildArch = options.targets || 'auto';
|
||||
|
||||
// Use DMG by default for distribution
|
||||
// Only create app bundles for testing to avoid user interaction
|
||||
if (process.env.PAKE_CREATE_APP === '1') {
|
||||
this.options.targets = 'app';
|
||||
this.buildFormat = 'app';
|
||||
} else {
|
||||
this.options.targets = 'dmg';
|
||||
this.buildFormat = 'dmg';
|
||||
}
|
||||
|
||||
// Set targets to format for Tauri
|
||||
this.options.targets = this.buildFormat;
|
||||
}
|
||||
|
||||
getFileName(): string {
|
||||
const { name } = this.options;
|
||||
|
||||
// For app bundles, use simple name without version/arch
|
||||
if (this.options.targets === 'app') {
|
||||
if (this.buildFormat === 'app') {
|
||||
return name;
|
||||
}
|
||||
|
||||
// For DMG files, use versioned filename
|
||||
let arch: string;
|
||||
if (this.options.multiArch) {
|
||||
if (this.buildArch === 'universal' || this.options.multiArch) {
|
||||
arch = 'universal';
|
||||
} else if (this.buildArch === 'apple') {
|
||||
arch = 'aarch64';
|
||||
} else if (this.buildArch === 'intel') {
|
||||
arch = 'x64';
|
||||
} else {
|
||||
// Auto-detect based on current architecture
|
||||
arch = process.arch === 'arm64' ? 'aarch64' : process.arch;
|
||||
}
|
||||
return `${name}_${tauriConfig.version}_${arch}`;
|
||||
}
|
||||
|
||||
protected getBuildCommand(): string {
|
||||
if (this.options.multiArch) {
|
||||
// Determine if we need universal build
|
||||
const needsUniversal =
|
||||
this.buildArch === 'universal' || this.options.multiArch;
|
||||
|
||||
if (needsUniversal) {
|
||||
const baseCommand = this.options.debug
|
||||
? 'npm run tauri build -- --debug'
|
||||
: 'npm run tauri build --';
|
||||
@@ -56,14 +75,63 @@ export default class MacBuilder extends BaseBuilder {
|
||||
fullCommand += ` --features ${features.join(',')}`;
|
||||
}
|
||||
|
||||
return fullCommand;
|
||||
} else if (this.buildArch === 'apple') {
|
||||
// Build for Apple Silicon only
|
||||
const baseCommand = this.options.debug
|
||||
? 'npm run tauri build -- --debug'
|
||||
: 'npm run tauri build --';
|
||||
const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
|
||||
let fullCommand = `${baseCommand} --target aarch64-apple-darwin -c "${configPath}"`;
|
||||
|
||||
// Add features
|
||||
const features = ['cli-build'];
|
||||
const macOSVersion = this.getMacOSMajorVersion();
|
||||
if (macOSVersion >= 23) {
|
||||
features.push('macos-proxy');
|
||||
}
|
||||
if (features.length > 0) {
|
||||
fullCommand += ` --features ${features.join(',')}`;
|
||||
}
|
||||
|
||||
return fullCommand;
|
||||
} else if (this.buildArch === 'intel') {
|
||||
// Build for Intel only
|
||||
const baseCommand = this.options.debug
|
||||
? 'npm run tauri build -- --debug'
|
||||
: 'npm run tauri build --';
|
||||
const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
|
||||
let fullCommand = `${baseCommand} --target x86_64-apple-darwin -c "${configPath}"`;
|
||||
|
||||
// Add features
|
||||
const features = ['cli-build'];
|
||||
const macOSVersion = this.getMacOSMajorVersion();
|
||||
if (macOSVersion >= 23) {
|
||||
features.push('macos-proxy');
|
||||
}
|
||||
if (features.length > 0) {
|
||||
fullCommand += ` --features ${features.join(',')}`;
|
||||
}
|
||||
|
||||
return fullCommand;
|
||||
}
|
||||
|
||||
return super.getBuildCommand();
|
||||
}
|
||||
|
||||
protected getBasePath(): string {
|
||||
return this.options.multiArch
|
||||
? 'src-tauri/target/universal-apple-darwin/release/bundle'
|
||||
: super.getBasePath();
|
||||
const needsUniversal =
|
||||
this.buildArch === 'universal' || this.options.multiArch;
|
||||
const basePath = this.options.debug ? 'debug' : 'release';
|
||||
|
||||
if (needsUniversal) {
|
||||
return `src-tauri/target/universal-apple-darwin/${basePath}/bundle`;
|
||||
} else if (this.buildArch === 'apple') {
|
||||
return `src-tauri/target/aarch64-apple-darwin/${basePath}/bundle`;
|
||||
} else if (this.buildArch === 'intel') {
|
||||
return `src-tauri/target/x86_64-apple-darwin/${basePath}/bundle`;
|
||||
}
|
||||
|
||||
return super.getBasePath();
|
||||
}
|
||||
}
|
||||
|
||||
82
bin/builders/WinBuilder.ts
vendored
82
bin/builders/WinBuilder.ts
vendored
@@ -1,17 +1,93 @@
|
||||
import path from 'path';
|
||||
import BaseBuilder from './BaseBuilder';
|
||||
import { PakeAppOptions } from '@/types';
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
|
||||
export default class WinBuilder extends BaseBuilder {
|
||||
private buildFormat: string = 'msi';
|
||||
private buildArch: string;
|
||||
|
||||
constructor(options: PakeAppOptions) {
|
||||
super(options);
|
||||
this.options.targets = 'msi';
|
||||
// Store the original targets value for architecture selection
|
||||
this.buildArch = options.targets || 'auto';
|
||||
// Set targets to msi format for Tauri
|
||||
this.options.targets = this.buildFormat;
|
||||
}
|
||||
|
||||
getFileName(): string {
|
||||
const { name } = this.options;
|
||||
const { arch } = process;
|
||||
const language = tauriConfig.bundle.windows.wix.language[0];
|
||||
return `${name}_${tauriConfig.version}_${arch}_${language}`;
|
||||
|
||||
// Determine architecture name based on explicit targets option or auto-detect
|
||||
let targetArch: string;
|
||||
if (this.buildArch === 'arm64') {
|
||||
targetArch = 'aarch64';
|
||||
} else if (this.buildArch === 'x64') {
|
||||
targetArch = 'x64';
|
||||
} else {
|
||||
// Auto-detect based on current architecture if no explicit target
|
||||
const archMap: { [key: string]: string } = {
|
||||
x64: 'x64',
|
||||
arm64: 'aarch64',
|
||||
};
|
||||
targetArch = archMap[process.arch] || process.arch;
|
||||
}
|
||||
|
||||
return `${name}_${tauriConfig.version}_${targetArch}_${language}`;
|
||||
}
|
||||
|
||||
protected getBuildCommand(): string {
|
||||
const baseCommand = this.options.debug
|
||||
? 'npm run build:debug'
|
||||
: 'npm run build';
|
||||
|
||||
// Use temporary config directory to avoid modifying source files
|
||||
const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
|
||||
let fullCommand = `${baseCommand} -- -c "${configPath}"`;
|
||||
|
||||
// Determine build target based on explicit targets option or auto-detect
|
||||
let buildTarget: string;
|
||||
if (this.buildArch === 'arm64') {
|
||||
buildTarget = 'aarch64-pc-windows-msvc';
|
||||
} else if (this.buildArch === 'x64') {
|
||||
buildTarget = 'x86_64-pc-windows-msvc';
|
||||
} else {
|
||||
// Auto-detect based on current architecture if no explicit target
|
||||
buildTarget =
|
||||
process.arch === 'arm64'
|
||||
? 'aarch64-pc-windows-msvc'
|
||||
: 'x86_64-pc-windows-msvc';
|
||||
}
|
||||
|
||||
fullCommand += ` --target ${buildTarget}`;
|
||||
|
||||
// Add features
|
||||
const features = ['cli-build'];
|
||||
if (features.length > 0) {
|
||||
fullCommand += ` --features ${features.join(',')}`;
|
||||
}
|
||||
|
||||
return fullCommand;
|
||||
}
|
||||
|
||||
protected getBasePath(): string {
|
||||
const basePath = this.options.debug ? 'debug' : 'release';
|
||||
|
||||
// Determine target based on explicit targets option or auto-detect
|
||||
let target: string;
|
||||
if (this.buildArch === 'arm64') {
|
||||
target = 'aarch64-pc-windows-msvc';
|
||||
} else if (this.buildArch === 'x64') {
|
||||
target = 'x86_64-pc-windows-msvc';
|
||||
} else {
|
||||
// Auto-detect based on current architecture if no explicit target
|
||||
target =
|
||||
process.arch === 'arm64'
|
||||
? 'aarch64-pc-windows-msvc'
|
||||
: 'x86_64-pc-windows-msvc';
|
||||
}
|
||||
|
||||
return `src-tauri/target/${target}/${basePath}/bundle/`;
|
||||
}
|
||||
}
|
||||
|
||||
7
bin/cli.ts
vendored
7
bin/cli.ts
vendored
@@ -81,9 +81,10 @@ program
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--targets <string>', 'For Linux, option "deb" or "appimage"')
|
||||
.default(DEFAULT.targets)
|
||||
.hideHelp(),
|
||||
new Option(
|
||||
'--targets <string>',
|
||||
'Build target: Linux: "deb", "rpm", "appimage", "deb-arm64", "rpm-arm64", "appimage-arm64"; Windows: "x64", "arm64"; macOS: "intel", "apple", "universal"',
|
||||
).default(DEFAULT.targets),
|
||||
)
|
||||
.addOption(
|
||||
new Option(
|
||||
|
||||
15
bin/helpers/merge.ts
vendored
15
bin/helpers/merge.ts
vendored
@@ -172,9 +172,20 @@ StartupNotify=true
|
||||
[`/usr/share/applications/${desktopFileName}`]: `assets/${desktopFileName}`,
|
||||
};
|
||||
|
||||
const validTargets = ['deb', 'appimage', 'rpm'];
|
||||
const validTargets = [
|
||||
'deb',
|
||||
'appimage',
|
||||
'rpm',
|
||||
'deb-arm64',
|
||||
'appimage-arm64',
|
||||
'rpm-arm64',
|
||||
];
|
||||
const baseTarget = options.targets.includes('-arm64')
|
||||
? options.targets.replace('-arm64', '')
|
||||
: options.targets;
|
||||
|
||||
if (validTargets.includes(options.targets)) {
|
||||
tauriConf.bundle.targets = [options.targets];
|
||||
tauriConf.bundle.targets = [baseTarget];
|
||||
} else {
|
||||
logger.warn(
|
||||
`✼ The target must be one of ${validTargets.join(', ')}, the default 'deb' will be used.`,
|
||||
|
||||
3
bin/types.ts
vendored
3
bin/types.ts
vendored
@@ -57,7 +57,8 @@ export interface PakeCliOptions {
|
||||
// Multi arch, supports both Intel and M1 chips, only for Mac
|
||||
multiArch: boolean;
|
||||
|
||||
// Package output, valid for Linux users, default is deb, optional appimage, or all (i.e., output both deb and all);
|
||||
// Build target architecture/format:
|
||||
// Linux: "deb", "appimage", "deb-arm64", "appimage-arm64"; Windows: "x64", "arm64"; macOS: "intel", "apple", "universal"
|
||||
targets: string;
|
||||
|
||||
// Debug mode, outputs more logs
|
||||
|
||||
Reference in New Issue
Block a user