bare-build 0.0.0 → 0.0.2
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/CMakeLists.txt +23 -1
- package/README.md +91 -0
- package/bin.js +40 -2
- package/index.js +9 -2
- package/lib/appimagetool.js +17 -0
- package/lib/fs.js +17 -0
- package/lib/platform/apple.js +52 -16
- package/lib/platform/linux.js +37 -18
- package/lib/platform/windows.js +72 -68
- package/lib/runtime.c +2 -0
- package/lib/runtime.manifest +15 -0
- package/package.json +13 -2
- package/prebuilds/darwin-arm64/bare +0 -0
- package/prebuilds/darwin-x64/bare +0 -0
- package/prebuilds/ios-arm64/bare +0 -0
- package/prebuilds/ios-arm64-simulator/bare +0 -0
- package/prebuilds/ios-x64-simulator/bare +0 -0
- package/prebuilds/linux-arm64/appimagetool.AppImage +0 -0
- package/prebuilds/linux-arm64/bare +0 -0
- package/prebuilds/linux-x64/appimagetool.AppImage +0 -0
- package/prebuilds/linux-x64/bare +0 -0
- package/prebuilds/win32-arm64/bare.exe +0 -0
- package/prebuilds/win32-arm64/bare.lib +0 -0
- package/prebuilds/win32-x64/bare.exe +0 -0
- package/prebuilds/win32-x64/bare.lib +0 -0
package/CMakeLists.txt
CHANGED
|
@@ -5,7 +5,9 @@ find_package(cmake-fetch REQUIRED PATHS node_modules/cmake-fetch)
|
|
|
5
5
|
|
|
6
6
|
project(bare_build C)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
set(bare_version "1.24.3")
|
|
9
|
+
|
|
10
|
+
fetch_package("github:holepunchto/bare@${bare_version}")
|
|
9
11
|
fetch_package("github:holepunchto/libpath")
|
|
10
12
|
|
|
11
13
|
add_executable(bare_build)
|
|
@@ -46,6 +48,26 @@ target_link_libraries(
|
|
|
46
48
|
path_static
|
|
47
49
|
)
|
|
48
50
|
|
|
51
|
+
if(WIN32)
|
|
52
|
+
file(READ "lib/runtime.manifest" manifest)
|
|
53
|
+
|
|
54
|
+
string(CONFIGURE "${manifest}" manifest)
|
|
55
|
+
|
|
56
|
+
file(GENERATE OUTPUT "runtime.manifest" CONTENT "${manifest}" NEWLINE_STYLE WIN32)
|
|
57
|
+
|
|
58
|
+
target_sources(
|
|
59
|
+
bare_build
|
|
60
|
+
PRIVATE
|
|
61
|
+
"${CMAKE_CURRENT_BINARY_DIR}/runtime.manifest"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
target_link_options(
|
|
65
|
+
bare_build
|
|
66
|
+
PRIVATE
|
|
67
|
+
$<$<CONFIG:Release>:/subsystem:windows /entry:mainCRTStartup>
|
|
68
|
+
)
|
|
69
|
+
endif()
|
|
70
|
+
|
|
49
71
|
bare_target(target)
|
|
50
72
|
|
|
51
73
|
install(TARGETS bare_build DESTINATION ${target})
|
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# bare-build
|
|
2
|
+
|
|
3
|
+
Application builder for Bare.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
npm i [-g] bare-build
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
const build = require('bare-build')
|
|
13
|
+
|
|
14
|
+
await build('/path/to/app.js', {
|
|
15
|
+
target: ['darwin-arm64', 'darwinx64'],
|
|
16
|
+
icon: 'icon.icns',
|
|
17
|
+
identifier: 'com.example.App'
|
|
18
|
+
})
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```console
|
|
22
|
+
bare-build \
|
|
23
|
+
--target darwin-arm64 --target darwin-x64 \
|
|
24
|
+
--icon icon.icns \
|
|
25
|
+
--identifier com.example.App \
|
|
26
|
+
app.js
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
#### `await build(entry[, options])`
|
|
32
|
+
|
|
33
|
+
Options include:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
options = {
|
|
37
|
+
name: pkg.name,
|
|
38
|
+
version: pkg.version,
|
|
39
|
+
author: pkg.author,
|
|
40
|
+
description: pkg.description,
|
|
41
|
+
icon,
|
|
42
|
+
identifier,
|
|
43
|
+
target: [],
|
|
44
|
+
out: '.',
|
|
45
|
+
sign: false,
|
|
46
|
+
|
|
47
|
+
// Apple signing options
|
|
48
|
+
identity: 'Apple Development',
|
|
49
|
+
keychain,
|
|
50
|
+
entitlements,
|
|
51
|
+
hardenedRuntime: false,
|
|
52
|
+
|
|
53
|
+
// Windows signing options
|
|
54
|
+
subject,
|
|
55
|
+
subjectName,
|
|
56
|
+
thumbprint,
|
|
57
|
+
|
|
58
|
+
// Linux signing options
|
|
59
|
+
key
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## CLI
|
|
64
|
+
|
|
65
|
+
#### `bare-build [flags] <entry>`
|
|
66
|
+
|
|
67
|
+
Flags include:
|
|
68
|
+
|
|
69
|
+
```console
|
|
70
|
+
--name|-n <name>
|
|
71
|
+
--author <name>
|
|
72
|
+
--description <text>
|
|
73
|
+
--icon|-i <path>
|
|
74
|
+
--identifier <id>
|
|
75
|
+
--target|-t <host>
|
|
76
|
+
--out|-o <dir>
|
|
77
|
+
--sign
|
|
78
|
+
--identity <id>
|
|
79
|
+
--keychain <name>
|
|
80
|
+
--entitlements <path>
|
|
81
|
+
--hardened-runtime
|
|
82
|
+
--subject <id>
|
|
83
|
+
--subject-name <name>
|
|
84
|
+
--thumbprint <sha1>
|
|
85
|
+
--key <hash>
|
|
86
|
+
--help|-h
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
Apache-2.0
|
package/bin.js
CHANGED
|
@@ -13,11 +13,39 @@ const cmd = command(
|
|
|
13
13
|
flag('--author <name>', 'The name of the application author'),
|
|
14
14
|
flag('--description <text>', 'The description of the application'),
|
|
15
15
|
flag('--icon|-i <path>', 'The application icon'),
|
|
16
|
+
flag('--identifier <id>', 'The unique application identifier'),
|
|
16
17
|
flag('--target|-t <host>', 'The host to target').multiple(),
|
|
17
18
|
flag('--out|-o <dir>', 'The output directory'),
|
|
19
|
+
flag('--sign', 'Sign the application'),
|
|
20
|
+
flag('--identity <id>', 'The macOS signing identity'),
|
|
21
|
+
flag('--keychain <name>', 'The macOS signing keychain'),
|
|
22
|
+
flag('--entitlements <path>', 'The macOS signing entitlements'),
|
|
23
|
+
flag('--hardened-runtime', 'Enable the macOS hardened runtime'),
|
|
24
|
+
flag('--subject <id>', 'The Windows signing subject'),
|
|
25
|
+
flag('--subject-name <name>', 'The Windows signing subject friendly name'),
|
|
26
|
+
flag('--thumbprint <sha1>', 'The Windows signing subject thumbprint'),
|
|
27
|
+
flag('--key <hash>', 'The GPG signing key'),
|
|
18
28
|
async (cmd) => {
|
|
19
29
|
const { entry } = cmd.args
|
|
20
|
-
const {
|
|
30
|
+
const {
|
|
31
|
+
version,
|
|
32
|
+
name,
|
|
33
|
+
author,
|
|
34
|
+
description,
|
|
35
|
+
icon,
|
|
36
|
+
identifier,
|
|
37
|
+
target,
|
|
38
|
+
out,
|
|
39
|
+
sign,
|
|
40
|
+
identity,
|
|
41
|
+
keychain,
|
|
42
|
+
entitlements,
|
|
43
|
+
hardenedRuntime,
|
|
44
|
+
subject,
|
|
45
|
+
subjectName,
|
|
46
|
+
thumbprint,
|
|
47
|
+
key
|
|
48
|
+
} = cmd.flags
|
|
21
49
|
|
|
22
50
|
if (version) return console.log(`v${pkg.version}`)
|
|
23
51
|
|
|
@@ -27,8 +55,18 @@ const cmd = command(
|
|
|
27
55
|
author,
|
|
28
56
|
description,
|
|
29
57
|
icon,
|
|
58
|
+
identifier,
|
|
30
59
|
target,
|
|
31
|
-
out
|
|
60
|
+
out,
|
|
61
|
+
sign,
|
|
62
|
+
identity,
|
|
63
|
+
keychain,
|
|
64
|
+
entitlements,
|
|
65
|
+
hardenedRuntime,
|
|
66
|
+
subject,
|
|
67
|
+
subjectName,
|
|
68
|
+
thumbprint,
|
|
69
|
+
key
|
|
32
70
|
})
|
|
33
71
|
} catch (err) {
|
|
34
72
|
if (err) console.error(err)
|
package/index.js
CHANGED
|
@@ -10,7 +10,14 @@ const linux = require('./lib/platform/linux')
|
|
|
10
10
|
const windows = require('./lib/platform/windows')
|
|
11
11
|
|
|
12
12
|
module.exports = async function build(entry, opts = {}) {
|
|
13
|
-
const { base =
|
|
13
|
+
const { base = '.', target = [], hosts = target } = opts
|
|
14
|
+
|
|
15
|
+
let pkg
|
|
16
|
+
try {
|
|
17
|
+
pkg = require(path.resolve(base, 'package.json'))
|
|
18
|
+
} catch {
|
|
19
|
+
pkg = {}
|
|
20
|
+
}
|
|
14
21
|
|
|
15
22
|
let bundle = await pack(
|
|
16
23
|
pathToFileURL(entry),
|
|
@@ -63,6 +70,6 @@ module.exports = async function build(entry, opts = {}) {
|
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
for (const [platform, hosts] of groups) {
|
|
66
|
-
await platform(base, bundle, { ...opts, hosts })
|
|
73
|
+
await platform(base, pkg, bundle, { ...opts, hosts })
|
|
67
74
|
}
|
|
68
75
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
|
|
3
|
+
require.asset = require('require-asset')
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const appimagetool = require.asset('#appimagetool', __filename)
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
fs.accessSync(appimagetool, fs.constants.X_OK)
|
|
10
|
+
} catch {
|
|
11
|
+
fs.chmodSync(appimagetool, 0o755)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = appimagetool
|
|
15
|
+
} catch {
|
|
16
|
+
module.exports = null
|
|
17
|
+
}
|
package/lib/fs.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const fs = require('fs')
|
|
3
|
+
const os = require('os')
|
|
3
4
|
|
|
4
5
|
exports.rm = async function rm(name) {
|
|
5
6
|
return new Promise((resolve, reject) => {
|
|
@@ -61,3 +62,19 @@ exports.makeDir = async function makeDir(name) {
|
|
|
61
62
|
})
|
|
62
63
|
})
|
|
63
64
|
}
|
|
65
|
+
|
|
66
|
+
exports.tempDir = async function tempDir() {
|
|
67
|
+
const name = Math.random().toString(16).slice(2)
|
|
68
|
+
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
fs.realpath(os.tmpdir(), (err, dir) => {
|
|
71
|
+
if (err) return reject(err)
|
|
72
|
+
|
|
73
|
+
dir = path.join(dir, `bare-build-${name}`)
|
|
74
|
+
|
|
75
|
+
fs.mkdir(dir, { recursive: true }, (err) => {
|
|
76
|
+
err ? reject(err) : resolve(dir)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
}
|
package/lib/platform/apple.js
CHANGED
|
@@ -5,8 +5,8 @@ const fs = require('../fs')
|
|
|
5
5
|
const run = require('../run')
|
|
6
6
|
const prebuilds = require('../prebuilds')
|
|
7
7
|
|
|
8
|
-
module.exports = async function build(base, bundle, opts = {}) {
|
|
9
|
-
const { hosts = [], out =
|
|
8
|
+
module.exports = async function build(base, pkg, bundle, opts = {}) {
|
|
9
|
+
const { hosts = [], out = '.' } = opts
|
|
10
10
|
|
|
11
11
|
const archs = new Map([
|
|
12
12
|
['macos', []],
|
|
@@ -44,9 +44,9 @@ module.exports = async function build(base, bundle, opts = {}) {
|
|
|
44
44
|
|
|
45
45
|
for (const [os, hosts] of archs) {
|
|
46
46
|
apps.push(
|
|
47
|
-
await app(
|
|
47
|
+
await app(base, pkg, bundle, hosts, {
|
|
48
48
|
...opts,
|
|
49
|
-
out: archs.size === 1 ? out : path.
|
|
49
|
+
out: archs.size === 1 ? path.resolve(out) : path.resolve(out, os)
|
|
50
50
|
})
|
|
51
51
|
)
|
|
52
52
|
}
|
|
@@ -55,12 +55,12 @@ module.exports = async function build(base, bundle, opts = {}) {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
// https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle
|
|
58
|
-
async function app(
|
|
59
|
-
const
|
|
58
|
+
async function app(base, pkg, bundle, hosts, opts = {}) {
|
|
59
|
+
const { name = pkg.name, version = pkg.version, icon, out = '.' } = opts
|
|
60
60
|
|
|
61
|
-
const
|
|
61
|
+
const isMac = hosts.some((host) => host.startsWith('darwin'))
|
|
62
62
|
|
|
63
|
-
const app = path.
|
|
63
|
+
const app = path.resolve(out, `${name}.app`)
|
|
64
64
|
await fs.makeDir(app)
|
|
65
65
|
|
|
66
66
|
const main = isMac ? path.join(app, 'Contents') : app
|
|
@@ -71,7 +71,9 @@ async function app(os, base, bundle, hosts, opts = {}) {
|
|
|
71
71
|
|
|
72
72
|
const frameworks = path.join(main, 'Frameworks')
|
|
73
73
|
|
|
74
|
-
await link(base, { hosts, out: frameworks })
|
|
74
|
+
for await (const resource of link(base, { hosts, out: frameworks })) {
|
|
75
|
+
await sign(resource, opts)
|
|
76
|
+
}
|
|
75
77
|
|
|
76
78
|
const executable = isMac ? path.join(main, 'MacOS', name) : path.join(main, name)
|
|
77
79
|
|
|
@@ -85,7 +87,9 @@ async function app(os, base, bundle, hosts, opts = {}) {
|
|
|
85
87
|
|
|
86
88
|
await run('lipo', ['-create', '-output', executable, ...inputs])
|
|
87
89
|
|
|
88
|
-
await
|
|
90
|
+
await sign(executable, opts)
|
|
91
|
+
|
|
92
|
+
await fs.writeFile(path.join(main, 'Info.plist'), plist(isMac, name, version, opts))
|
|
89
93
|
|
|
90
94
|
await fs.writeFile(path.join(main, 'PkgInfo'), 'APPL????')
|
|
91
95
|
|
|
@@ -95,21 +99,46 @@ async function app(os, base, bundle, hosts, opts = {}) {
|
|
|
95
99
|
await fs.makeDir(path.dirname(target))
|
|
96
100
|
await fs.writeFile(target, bundle.read(key))
|
|
97
101
|
|
|
102
|
+
await sign(target, opts)
|
|
103
|
+
|
|
98
104
|
return '/../app' + key
|
|
99
105
|
})
|
|
100
106
|
|
|
101
107
|
await fs.writeFile(path.join(resources, 'app.bundle'), bundle.toBuffer())
|
|
102
108
|
|
|
103
|
-
|
|
109
|
+
await sign(path.join(resources, 'app.bundle'), opts)
|
|
110
|
+
|
|
111
|
+
await fs.cp(path.resolve(icon), path.join(resources, 'app' + path.extname(icon)))
|
|
112
|
+
|
|
113
|
+
await sign(path.join(resources, 'app' + path.extname(icon)), opts)
|
|
104
114
|
|
|
105
115
|
return app
|
|
106
116
|
}
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
const
|
|
118
|
+
async function sign(resource, opts = {}) {
|
|
119
|
+
const {
|
|
120
|
+
sign = false,
|
|
121
|
+
identity = 'Apple Development',
|
|
122
|
+
keychain,
|
|
123
|
+
entitlements,
|
|
124
|
+
hardenedRuntime = false
|
|
125
|
+
} = opts
|
|
126
|
+
|
|
127
|
+
if (sign) {
|
|
128
|
+
const args = ['--timestamp', '--force', '--sign', identity]
|
|
129
|
+
|
|
130
|
+
if (keychain) args.push('--keychain', keychain)
|
|
131
|
+
if (entitlements) args.push('--entitlements', path.resolve(entitlements))
|
|
132
|
+
if (hardenedRuntime) args.push('--options', 'runtime')
|
|
110
133
|
|
|
111
|
-
|
|
112
|
-
|
|
134
|
+
args.push(resource)
|
|
135
|
+
|
|
136
|
+
await run('codesign', args)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function plist(isMac, name, version, opts = {}) {
|
|
141
|
+
const { identifier = toIdentifier(name) } = opts
|
|
113
142
|
|
|
114
143
|
version = version.match(/^\d+(\.\d+){0,2}/).at(0)
|
|
115
144
|
|
|
@@ -119,7 +148,7 @@ function plist(os, name, version) {
|
|
|
119
148
|
<plist version="1.0">
|
|
120
149
|
<dict>
|
|
121
150
|
<key>CFBundleIdentifier</key>
|
|
122
|
-
<string>${
|
|
151
|
+
<string>${identifier}</string>
|
|
123
152
|
<key>CFBundleVersion</key>
|
|
124
153
|
<string>${version}</string>
|
|
125
154
|
<key>CFBundleShortVersionString</key>
|
|
@@ -138,3 +167,10 @@ function plist(os, name, version) {
|
|
|
138
167
|
</plist>
|
|
139
168
|
`
|
|
140
169
|
}
|
|
170
|
+
|
|
171
|
+
// https://developer.apple.com/documentation/bundleresources/information-property-list/cfbundleidentifier
|
|
172
|
+
const invalidBundleIdentifierCharacter = /[^A-Za-z0-9.-]/g
|
|
173
|
+
|
|
174
|
+
function toIdentifier(input) {
|
|
175
|
+
return input.replace(invalidBundleIdentifierCharacter, '')
|
|
176
|
+
}
|
package/lib/platform/linux.js
CHANGED
|
@@ -2,10 +2,12 @@ const path = require('path')
|
|
|
2
2
|
const link = require('bare-link')
|
|
3
3
|
const unpack = require('bare-unpack')
|
|
4
4
|
const fs = require('../fs')
|
|
5
|
+
const run = require('../run')
|
|
5
6
|
const prebuilds = require('../prebuilds')
|
|
7
|
+
const appimagetool = require('../appimagetool')
|
|
6
8
|
|
|
7
|
-
module.exports = async function build(base, bundle, opts = {}) {
|
|
8
|
-
const { hosts = [], out =
|
|
9
|
+
module.exports = async function build(base, pkg, bundle, opts = {}) {
|
|
10
|
+
const { hosts = [], out = '.' } = opts
|
|
9
11
|
|
|
10
12
|
const archs = new Map()
|
|
11
13
|
|
|
@@ -30,9 +32,9 @@ module.exports = async function build(base, bundle, opts = {}) {
|
|
|
30
32
|
|
|
31
33
|
for (const [arch, host] of archs) {
|
|
32
34
|
result.push(
|
|
33
|
-
await appDir(base, bundle, host, {
|
|
35
|
+
await appImage(pkg, await appDir(base, pkg, bundle, host, opts), {
|
|
34
36
|
...opts,
|
|
35
|
-
out: archs.size === 1 ? out : path.
|
|
37
|
+
out: archs.size === 1 ? path.resolve(out) : path.resolve(out, arch)
|
|
36
38
|
})
|
|
37
39
|
)
|
|
38
40
|
}
|
|
@@ -41,10 +43,12 @@ module.exports = async function build(base, bundle, opts = {}) {
|
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
// https://docs.appimage.org/reference/appdir.html
|
|
44
|
-
async function appDir(base, bundle, host, opts = {}) {
|
|
45
|
-
const { name =
|
|
46
|
+
async function appDir(base, pkg, bundle, host, opts = {}) {
|
|
47
|
+
const { name = pkg.name, icon } = opts
|
|
46
48
|
|
|
47
|
-
const
|
|
49
|
+
const out = await fs.tempDir()
|
|
50
|
+
|
|
51
|
+
const app = path.resolve(out, name + '.AppDir')
|
|
48
52
|
|
|
49
53
|
const usr = path.join(app, 'usr')
|
|
50
54
|
|
|
@@ -67,7 +71,8 @@ async function appDir(base, bundle, host, opts = {}) {
|
|
|
67
71
|
|
|
68
72
|
const assets = path.join(data, 'app')
|
|
69
73
|
|
|
70
|
-
await link(base, { hosts: [host], out: usr })
|
|
74
|
+
for await (const resource of link(base, { hosts: [host], out: usr })) {
|
|
75
|
+
}
|
|
71
76
|
|
|
72
77
|
await fs.writeFile(path.join(applications, name + '.desktop'), desktop(name))
|
|
73
78
|
|
|
@@ -87,23 +92,37 @@ async function appDir(base, bundle, host, opts = {}) {
|
|
|
87
92
|
|
|
88
93
|
await fs.writeFile(path.join(data, 'app.bundle'), bundle.toBuffer())
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
await fs.makeDir(icons)
|
|
95
|
+
const icons = path.join(share, 'icons')
|
|
96
|
+
await fs.makeDir(icons)
|
|
93
97
|
|
|
94
|
-
|
|
98
|
+
await fs.cp(path.resolve(icon), path.join(icons, name + path.extname(icon)))
|
|
95
99
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
await fs.symlink(
|
|
101
|
+
path.join('usr', 'share', 'icons', name + path.extname(icon)),
|
|
102
|
+
path.join(app, name + path.extname(icon))
|
|
103
|
+
)
|
|
100
104
|
|
|
101
|
-
|
|
102
|
-
}
|
|
105
|
+
await fs.symlink(name + path.extname(icon), path.join(app, '.DirIcon'))
|
|
103
106
|
|
|
104
107
|
return app
|
|
105
108
|
}
|
|
106
109
|
|
|
110
|
+
async function appImage(pkg, appDir, opts = {}) {
|
|
111
|
+
const { name = pkg.name, out = '.', sign = false, key } = opts
|
|
112
|
+
|
|
113
|
+
const appImage = path.resolve(out, name + '.AppImage')
|
|
114
|
+
|
|
115
|
+
const args = [appDir]
|
|
116
|
+
|
|
117
|
+
if (sign) args.push('--sign', '--sign-key', key)
|
|
118
|
+
|
|
119
|
+
args.push(appImage)
|
|
120
|
+
|
|
121
|
+
await run(appimagetool, args)
|
|
122
|
+
|
|
123
|
+
return appImage
|
|
124
|
+
}
|
|
125
|
+
|
|
107
126
|
function desktop(name) {
|
|
108
127
|
return `\
|
|
109
128
|
[Desktop Entry]
|
package/lib/platform/windows.js
CHANGED
|
@@ -2,10 +2,11 @@ const path = require('path')
|
|
|
2
2
|
const link = require('bare-link')
|
|
3
3
|
const unpack = require('bare-unpack')
|
|
4
4
|
const fs = require('../fs')
|
|
5
|
+
const run = require('../run')
|
|
5
6
|
const prebuilds = require('../prebuilds')
|
|
6
7
|
|
|
7
|
-
module.exports = async function build(base, bundle, opts = {}) {
|
|
8
|
-
const { hosts = [], out =
|
|
8
|
+
module.exports = async function build(base, pkg, bundle, opts = {}) {
|
|
9
|
+
const { hosts = [], out = '.' } = opts
|
|
9
10
|
|
|
10
11
|
const archs = new Map()
|
|
11
12
|
|
|
@@ -30,9 +31,10 @@ module.exports = async function build(base, bundle, opts = {}) {
|
|
|
30
31
|
|
|
31
32
|
for (const [arch, host] of archs) {
|
|
32
33
|
result.push(
|
|
33
|
-
await appx(base,
|
|
34
|
+
await appx(base, pkg, bundle, {
|
|
34
35
|
...opts,
|
|
35
|
-
|
|
36
|
+
host,
|
|
37
|
+
out: archs.size === 1 ? path.resolve(out) : path.resolve(out, arch)
|
|
36
38
|
})
|
|
37
39
|
)
|
|
38
40
|
}
|
|
@@ -40,10 +42,12 @@ module.exports = async function build(base, bundle, opts = {}) {
|
|
|
40
42
|
return result
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
async function appx(base,
|
|
44
|
-
const { name =
|
|
45
|
+
async function appx(base, pkg, bundle, opts = {}) {
|
|
46
|
+
const { name = pkg.name, icon, host, out = '.' } = opts
|
|
45
47
|
|
|
46
|
-
const
|
|
48
|
+
const tmp = await fs.tempDir()
|
|
49
|
+
|
|
50
|
+
const app = path.join(tmp, name)
|
|
47
51
|
|
|
48
52
|
const bin = path.join(app, 'App')
|
|
49
53
|
await fs.makeDir(bin)
|
|
@@ -52,12 +56,16 @@ async function appx(base, bundle, host, opts = {}) {
|
|
|
52
56
|
|
|
53
57
|
await fs.copyFile(prebuilds[host](), executable)
|
|
54
58
|
|
|
59
|
+
await sign(executable, opts)
|
|
60
|
+
|
|
55
61
|
const resources = path.join(app, 'Resources')
|
|
56
62
|
await fs.makeDir(resources)
|
|
57
63
|
|
|
58
64
|
const assets = path.join(resources, 'app')
|
|
59
65
|
|
|
60
|
-
await link(base, { hosts: [host], out: bin })
|
|
66
|
+
for await (const resource of link(base, { hosts: [host], out: bin })) {
|
|
67
|
+
await sign(resource, opts)
|
|
68
|
+
}
|
|
61
69
|
|
|
62
70
|
bundle = await unpack(bundle, { files: false, assets: true }, async (key) => {
|
|
63
71
|
const target = path.join(assets, key)
|
|
@@ -70,19 +78,54 @@ async function appx(base, bundle, host, opts = {}) {
|
|
|
70
78
|
|
|
71
79
|
await fs.writeFile(path.join(resources, 'app.bundle'), bundle.toBuffer())
|
|
72
80
|
|
|
73
|
-
await fs.writeFile(path.join(app, 'AppxManifest.xml'), appxManifest(host, opts))
|
|
81
|
+
await fs.writeFile(path.join(app, 'AppxManifest.xml'), appxManifest(pkg, host, opts))
|
|
74
82
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
await fs.makeDir(icons)
|
|
83
|
+
const icons = path.join(app, 'Assets')
|
|
84
|
+
await fs.makeDir(icons)
|
|
78
85
|
|
|
79
|
-
|
|
80
|
-
|
|
86
|
+
await fs.cp(path.resolve(icon), path.join(icons, name + path.extname(icon)))
|
|
87
|
+
|
|
88
|
+
const appx = path.resolve(out, name + '.msix')
|
|
89
|
+
|
|
90
|
+
await fs.rm(appx)
|
|
91
|
+
|
|
92
|
+
await run('makeappx', ['pack', '/d', app, '/p', appx])
|
|
93
|
+
|
|
94
|
+
await sign(appx, opts)
|
|
95
|
+
|
|
96
|
+
return appx
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function sign(resource, opts = {}) {
|
|
100
|
+
const { sign = false, subjectName, thumbprint } = opts
|
|
101
|
+
|
|
102
|
+
if (sign) {
|
|
103
|
+
const args = ['sign', '/a', '/fd', 'SHA256', '/t', 'http://timestamp.digicert.com']
|
|
104
|
+
|
|
105
|
+
if (subjectName) args.push('/n', subjectName)
|
|
106
|
+
if (thumbprint) args.push('/sha1', thumbprint)
|
|
107
|
+
|
|
108
|
+
args.push(resource)
|
|
81
109
|
|
|
82
|
-
|
|
110
|
+
await run('signtool', args)
|
|
111
|
+
}
|
|
83
112
|
}
|
|
84
113
|
|
|
85
|
-
|
|
114
|
+
// https://learn.microsoft.com/en-us/windows/msix/package/unsigned-package
|
|
115
|
+
const unsignedSubject = 'CN=AppModelSamples, OID.2.25.311729368913984317654407730594956997722=1'
|
|
116
|
+
|
|
117
|
+
function appxManifest(pkg, host, opts = {}) {
|
|
118
|
+
let {
|
|
119
|
+
name = pkg.name,
|
|
120
|
+
identifier = toIdentifier(name),
|
|
121
|
+
version = pkg.version,
|
|
122
|
+
description = pkg.description,
|
|
123
|
+
author = pkg.author,
|
|
124
|
+
language = 'en-US',
|
|
125
|
+
icon,
|
|
126
|
+
subject = unsignedSubject
|
|
127
|
+
} = opts
|
|
128
|
+
|
|
86
129
|
let arch
|
|
87
130
|
|
|
88
131
|
switch (host) {
|
|
@@ -94,89 +137,50 @@ function appxManifest(host, opts = {}) {
|
|
|
94
137
|
break
|
|
95
138
|
}
|
|
96
139
|
|
|
97
|
-
|
|
98
|
-
name = 'App',
|
|
99
|
-
identifier = name.replace(/[^a-z0-9.-]+/gi, ''),
|
|
100
|
-
version = '1.0.0',
|
|
101
|
-
description = '',
|
|
102
|
-
author = '',
|
|
103
|
-
language = 'en-US',
|
|
140
|
+
version = version.match(/^\d+(\.\d+){0,2}/).at(0)
|
|
104
141
|
|
|
105
|
-
|
|
106
|
-
publisher = 'CN=AppModelSamples, OID.2.25.311729368913984317654407730594956997722=1'
|
|
107
|
-
} = opts
|
|
142
|
+
const logo = `Assets\\${name}${path.extname(icon)}`
|
|
108
143
|
|
|
109
144
|
return `\
|
|
110
145
|
<?xml version="1.0" encoding="utf-8"?>
|
|
111
146
|
<Package
|
|
112
147
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
|
113
148
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
|
114
|
-
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
|
|
115
149
|
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
|
116
150
|
xmlns:virtualization="http://schemas.microsoft.com/appx/manifest/virtualization/windows10"
|
|
117
151
|
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
|
|
118
152
|
IgnorableNamespaces="rescap desktop6 virtualization"
|
|
119
153
|
>
|
|
120
|
-
<Identity
|
|
121
|
-
Name="${identifier}"
|
|
122
|
-
Version="${version}.0"
|
|
123
|
-
Publisher="${publisher}"
|
|
124
|
-
ProcessorArchitecture="${arch}"
|
|
125
|
-
/>
|
|
154
|
+
<Identity Name="${identifier}" Version="${version}.0" Publisher="${subject}" ProcessorArchitecture="${arch}" />
|
|
126
155
|
<Properties>
|
|
127
156
|
<DisplayName>${name}</DisplayName>
|
|
128
157
|
<PublisherDisplayName>${author}</PublisherDisplayName>
|
|
129
158
|
<Description>${description}</Description>
|
|
130
|
-
<Logo
|
|
131
|
-
|
|
159
|
+
<Logo>${logo}</Logo>
|
|
132
160
|
<desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>
|
|
133
161
|
<desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>
|
|
134
162
|
</Properties>
|
|
135
|
-
|
|
136
163
|
<Resources>
|
|
137
164
|
<Resource Language="${language}" />
|
|
138
165
|
</Resources>
|
|
139
|
-
|
|
140
166
|
<Dependencies>
|
|
141
|
-
<TargetDeviceFamily
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
MaxVersionTested="10.0.22621.0"
|
|
145
|
-
/>
|
|
146
|
-
<PackageDependency
|
|
147
|
-
Name="Microsoft.WindowsAppRuntime.1.4"
|
|
148
|
-
MinVersion="4000.1049.117.0"
|
|
149
|
-
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
|
150
|
-
/>
|
|
151
|
-
<PackageDependency
|
|
152
|
-
Name="Microsoft.VCLibs.140.00"
|
|
153
|
-
MinVersion="14.0.30704.0"
|
|
154
|
-
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
|
155
|
-
/>
|
|
167
|
+
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19045.0" MaxVersionTested="10.0.22621.0" />
|
|
168
|
+
<PackageDependency Name="Microsoft.WindowsAppRuntime.1.4" MinVersion="4000.1049.117.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
|
169
|
+
<PackageDependency Name="Microsoft.VCLibs.140.00" MinVersion="14.0.30704.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
|
156
170
|
</Dependencies>
|
|
157
|
-
|
|
158
171
|
<Capabilities>
|
|
159
172
|
<rescap:Capability Name="runFullTrust" />
|
|
160
173
|
<rescap:Capability Name="unvirtualizedResources" />
|
|
161
174
|
</Capabilities>
|
|
162
|
-
|
|
163
175
|
<Applications>
|
|
164
|
-
<Application
|
|
165
|
-
|
|
166
|
-
Executable="App\\${name}.exe"
|
|
167
|
-
EntryPoint="Windows.FullTrustApplication"
|
|
168
|
-
uap10:RuntimeBehavior="packagedClassicApp"
|
|
169
|
-
uap10:TrustLevel="mediumIL"
|
|
170
|
-
>
|
|
171
|
-
<uap:VisualElements
|
|
172
|
-
DisplayName="${name}"
|
|
173
|
-
Description="${description}"
|
|
174
|
-
Square150x150Logo="Assets\\${name}.png"
|
|
175
|
-
Square44x44Logo="Assets\\${name}.png"
|
|
176
|
-
BackgroundColor="transparent"
|
|
177
|
-
/>
|
|
176
|
+
<Application Id="App" Executable="App\\${name}.exe" EntryPoint="Windows.FullTrustApplication">
|
|
177
|
+
<uap:VisualElements DisplayName="${name}" Description="${description}" Square150x150Logo="${logo}" Square44x44Logo="${logo}" BackgroundColor="transparent" />
|
|
178
178
|
</Application>
|
|
179
179
|
</Applications>
|
|
180
180
|
</Package>
|
|
181
181
|
`
|
|
182
182
|
}
|
|
183
|
+
|
|
184
|
+
function toIdentifier(input) {
|
|
185
|
+
return input.replace(/[^a-z0-9.-]+/gi, '')
|
|
186
|
+
}
|
package/lib/runtime.c
CHANGED
|
@@ -81,6 +81,8 @@ main(int argc, char *argv[]) {
|
|
|
81
81
|
err = path_join(
|
|
82
82
|
#if defined(BARE_PLATFORM_DARWIN) || defined(BARE_PLATFORM_WIN32)
|
|
83
83
|
(const char *[]) {bin, "..", "..", "Resources", "app.bundle", NULL},
|
|
84
|
+
#elif defined(BARE_PLATFORM_IOS)
|
|
85
|
+
(const char *[]) {bin, "..", "app.bundle", NULL},
|
|
84
86
|
#elif defined(BARE_PLATFORM_LINUX)
|
|
85
87
|
(const char *[]) {bin, "..", "..", "share", &bin[dir], "app.bundle", NULL},
|
|
86
88
|
#endif
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
|
3
|
+
<assemblyIdentity type="win32" name="to.holepunch.bare" version="${bare_version}.0" />
|
|
4
|
+
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
5
|
+
<windowsSettings>
|
|
6
|
+
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
|
7
|
+
</windowsSettings>
|
|
8
|
+
</application>
|
|
9
|
+
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
|
10
|
+
<application>
|
|
11
|
+
<maxversiontested Id="10.0.19045.0" />
|
|
12
|
+
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
|
13
|
+
</application>
|
|
14
|
+
</compatibility>
|
|
15
|
+
</assembly>
|
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bare-build",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Application builder for Bare",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./package": "./package.json",
|
|
7
7
|
".": "./index.js"
|
|
8
8
|
},
|
|
9
9
|
"imports": {
|
|
10
|
+
"#appimagetool": {
|
|
11
|
+
"linux": {
|
|
12
|
+
"arm64": "./prebuilds/linux-arm64/appimagetool.AppImage",
|
|
13
|
+
"x64": "./prebuilds/linux-x64/appimagetool.AppImage"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
10
16
|
"child_process": {
|
|
11
17
|
"bare": "bare-subprocess",
|
|
12
18
|
"default": "child_process"
|
|
@@ -15,6 +21,10 @@
|
|
|
15
21
|
"bare": "bare-fs",
|
|
16
22
|
"default": "fs"
|
|
17
23
|
},
|
|
24
|
+
"os": {
|
|
25
|
+
"bare": "bare-os",
|
|
26
|
+
"default": "os"
|
|
27
|
+
},
|
|
18
28
|
"path": {
|
|
19
29
|
"bare": "bare-path",
|
|
20
30
|
"default": "path"
|
|
@@ -50,8 +60,9 @@
|
|
|
50
60
|
"dependencies": {
|
|
51
61
|
"bare-bundle-id": "^1.0.2",
|
|
52
62
|
"bare-fs": "^4.5.1",
|
|
53
|
-
"bare-link": "^
|
|
63
|
+
"bare-link": "^2.0.0",
|
|
54
64
|
"bare-module-traverse": "^1.8.1",
|
|
65
|
+
"bare-os": "^3.6.2",
|
|
55
66
|
"bare-pack": "^1.5.1",
|
|
56
67
|
"bare-path": "^3.0.0",
|
|
57
68
|
"bare-subprocess": "^5.1.5",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|