Skip to content

Commit 38b7065

Browse files
hramosfacebook-github-bot
authored andcommitted
Hermes: Use pre-built artifacts in hermes-engine
Summary: Update `hermes-engine.podspec` to use pre-built Hermes artifacts from the corresponding React Native GitHub Release when targeting a specific React Native release. Otherwise, fallback to building Hermes from source. Changelog: [Internal] Reviewed By: cortinico, cipolleschi Differential Revision: D36609257 fbshipit-source-id: 6179c9e255558c7eaf1417ff46a2e7db120295f0
1 parent a709688 commit 38b7065

File tree

5 files changed

+98
-102
lines changed

5 files changed

+98
-102
lines changed

scripts/__tests__/hermes-utils-test.js

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as path from 'path';
1111

1212
const {
1313
copyBuildScripts,
14+
copyPodSpec,
1415
downloadHermesTarball,
1516
expandHermesTarball,
1617
getHermesTagSHA,
@@ -193,45 +194,42 @@ describe('hermes-utils', () => {
193194
it('should fail if Hermes tarball does not exist', () => {
194195
expect(() => {
195196
expandHermesTarball();
196-
}).toThrow('[Hermes] Failed to expand Hermes tarball.');
197+
}).toThrow('[Hermes] Could not locate Hermes tarball.');
197198
expect(execCalls.tar).toBeUndefined();
198199
});
199200
});
200201
describe('copyBuildScripts', () => {
201202
it('should copy React Native Hermes build scripts to Hermes source directory', () => {
202-
fs.mkdirSync(path.join(SDKS_DIR, 'hermes', 'utils'), {
203-
recursive: true,
204-
});
205203
copyBuildScripts();
206-
expect(
207-
fs.readFileSync(
208-
path.join(
209-
ROOT_DIR,
210-
'sdks',
211-
'hermes',
212-
'utils',
213-
'build-mac-framework.sh',
204+
205+
[
206+
'build-apple-framework.sh',
207+
'build-ios-framework.sh',
208+
'build-mac-framework.sh',
209+
].forEach(buildScript => {
210+
expect(
211+
fs.readFileSync(
212+
path.join(ROOT_DIR, 'sdks', 'hermes', 'utils', buildScript),
213+
{
214+
encoding: 'utf8',
215+
flag: 'r',
216+
},
214217
),
215-
{
216-
encoding: 'utf8',
217-
flag: 'r',
218-
},
219-
),
220-
).toEqual(
221-
fs.readFileSync(
222-
path.join(
223-
ROOT_DIR,
224-
'sdks',
225-
'hermes-engine',
226-
'utils',
227-
'build-mac-framework.sh',
218+
).toEqual(
219+
fs.readFileSync(
220+
path.join(ROOT_DIR, 'sdks', 'hermes-engine', 'utils', buildScript),
221+
{
222+
encoding: 'utf8',
223+
flag: 'r',
224+
},
228225
),
229-
{
230-
encoding: 'utf8',
231-
flag: 'r',
232-
},
233-
),
234-
);
226+
);
227+
});
228+
});
229+
});
230+
describe('copyPodSpec', () => {
231+
it('should copy React Native Hermes Podspec to Hermes source directory', () => {
232+
copyPodSpec();
235233
expect(
236234
fs.readFileSync(
237235
path.join(SDKS_DIR, 'hermes', 'hermes-engine.podspec'),

scripts/hermes/hermes-utils.js

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const {execSync} = require('child_process');
1515

1616
const SDKS_DIR = path.normalize(path.join(__dirname, '..', '..', 'sdks'));
1717
const HERMES_DIR = path.join(SDKS_DIR, 'hermes');
18+
const DEFAULT_HERMES_TAG = 'main';
1819
const HERMES_TAG_FILE_PATH = path.join(SDKS_DIR, '.hermesversion');
1920
const HERMES_TARBALL_BASE_URL = 'https://github.com/facebook/hermes/tarball/';
2021
const HERMES_TARBALL_DOWNLOAD_DIR = path.join(SDKS_DIR, 'download');
@@ -25,20 +26,6 @@ const MACOS_IMPORT_HERMESC_PATH = path.join(
2526
'ImportHermesc.cmake',
2627
);
2728

28-
function prepareFileSystem() {
29-
if (!fs.existsSync(SDKS_DIR)) {
30-
fs.mkdirSync(SDKS_DIR, {recursive: true});
31-
}
32-
33-
if (!fs.existsSync(HERMES_DIR)) {
34-
fs.mkdirSync(HERMES_DIR, {recursive: true});
35-
}
36-
37-
if (!fs.existsSync(HERMES_TARBALL_DOWNLOAD_DIR)) {
38-
fs.mkdirSync(HERMES_TARBALL_DOWNLOAD_DIR, {recursive: true});
39-
}
40-
}
41-
4229
function readHermesTag() {
4330
if (fs.existsSync(HERMES_TAG_FILE_PATH)) {
4431
const data = fs
@@ -64,8 +51,9 @@ function setHermesTag(hermesTag) {
6451
return;
6552
}
6653

67-
prepareFileSystem();
68-
54+
if (!fs.existsSync(SDKS_DIR)) {
55+
fs.mkdirSync(SDKS_DIR, {recursive: true});
56+
}
6957
fs.writeFileSync(HERMES_TAG_FILE_PATH, hermesTag.trim());
7058
console.log('Hermes tag has been updated. Please commit your changes.');
7159
}
@@ -89,12 +77,14 @@ function downloadHermesTarball() {
8977
const hermesTarballDownloadPath = getHermesTarballDownloadPath(hermesTag);
9078
let hermesTarballUrl = HERMES_TARBALL_BASE_URL + hermesTag;
9179

92-
prepareFileSystem();
93-
9480
if (fs.existsSync(hermesTarballDownloadPath)) {
9581
return;
9682
}
9783

84+
if (!fs.existsSync(HERMES_TARBALL_DOWNLOAD_DIR)) {
85+
fs.mkdirSync(HERMES_TARBALL_DOWNLOAD_DIR, {recursive: true});
86+
}
87+
9888
console.info(
9989
`[Hermes] Downloading Hermes source code for commit ${hermesTagSHA}`,
10090
);
@@ -110,12 +100,13 @@ function expandHermesTarball() {
110100
const hermesTagSHA = getHermesTagSHA(hermesTag);
111101
const hermesTarballDownloadPath = getHermesTarballDownloadPath(hermesTag);
112102

113-
prepareFileSystem();
114-
115103
if (!fs.existsSync(hermesTarballDownloadPath)) {
116-
throw new Error(`[Hermes] Failed to expand Hermes tarball.`);
104+
throw new Error('[Hermes] Could not locate Hermes tarball.');
117105
}
118106

107+
if (!fs.existsSync(HERMES_DIR)) {
108+
fs.mkdirSync(HERMES_DIR, {recursive: true});
109+
}
119110
console.info(`[Hermes] Expanding Hermes tarball for commit ${hermesTagSHA}`);
120111
try {
121112
execSync(
@@ -127,16 +118,16 @@ function expandHermesTarball() {
127118
}
128119

129120
function copyBuildScripts() {
130-
if (!fs.existsSync(HERMES_DIR)) {
121+
if (!fs.existsSync(SDKS_DIR)) {
131122
throw new Error(
132-
'[Hermes] Failed to copy Hermes build scripts, no Hermes source directory found.',
123+
'[Hermes] Failed to copy Hermes build scripts, no SDKs directory found.',
133124
);
134125
}
135126

136-
fs.copyFileSync(
137-
path.join(SDKS_DIR, 'hermes-engine', 'hermes-engine.podspec'),
138-
path.join(HERMES_DIR, 'hermes-engine.podspec'),
139-
);
127+
if (!fs.existsSync(HERMES_DIR)) {
128+
fs.mkdirSync(path.join(HERMES_DIR, 'utils'), {recursive: true});
129+
}
130+
140131
fs.copyFileSync(
141132
path.join(SDKS_DIR, 'hermes-engine', 'utils', 'build-apple-framework.sh'),
142133
path.join(HERMES_DIR, 'utils', 'build-apple-framework.sh'),
@@ -151,6 +142,27 @@ function copyBuildScripts() {
151142
);
152143
}
153144

145+
function copyPodSpec() {
146+
if (!fs.existsSync(SDKS_DIR)) {
147+
throw new Error(
148+
'[Hermes] Failed to copy Hermes Podspec, no SDKs directory found.',
149+
);
150+
}
151+
152+
if (!fs.existsSync(HERMES_DIR)) {
153+
fs.mkdirSync(HERMES_DIR, {recursive: true});
154+
}
155+
fs.copyFileSync(
156+
path.join(SDKS_DIR, 'hermes-engine', 'hermes-engine.podspec'),
157+
path.join(HERMES_DIR, 'hermes-engine.podspec'),
158+
);
159+
}
160+
161+
function shouldBuildHermesFromSource() {
162+
const hermesTag = readHermesTag();
163+
return hermesTag === DEFAULT_HERMES_TAG;
164+
}
165+
154166
function shouldUsePrebuiltHermesC(os) {
155167
if (os === 'macos') {
156168
return fs.existsSync(MACOS_HERMESC_PATH);
@@ -178,10 +190,12 @@ set_target_properties(native-hermesc PROPERTIES
178190
module.exports = {
179191
configureMakeForPrebuiltHermesC,
180192
copyBuildScripts,
193+
copyPodSpec,
181194
downloadHermesTarball,
182195
expandHermesTarball,
183196
getHermesTagSHA,
184197
readHermesTag,
185198
setHermesTag,
199+
shouldBuildHermesFromSource,
186200
shouldUsePrebuiltHermesC,
187201
};

scripts/hermes/prepare-hermes-for-build.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,30 @@
1616
const {
1717
configureMakeForPrebuiltHermesC,
1818
copyBuildScripts,
19+
copyPodSpec,
1920
downloadHermesTarball,
2021
expandHermesTarball,
2122
shouldUsePrebuiltHermesC,
23+
shouldBuildHermesFromSource,
2224
} = require('./hermes-utils');
2325

24-
downloadHermesTarball();
25-
expandHermesTarball();
26-
copyBuildScripts();
26+
async function main() {
27+
if (!shouldBuildHermesFromSource()) {
28+
copyPodSpec();
29+
return;
30+
}
2731

28-
if (shouldUsePrebuiltHermesC('macos')) {
29-
console.log('[Hermes] Using pre-built HermesC');
30-
configureMakeForPrebuiltHermesC();
32+
downloadHermesTarball();
33+
expandHermesTarball();
34+
copyPodSpec();
35+
copyBuildScripts();
36+
37+
if (shouldUsePrebuiltHermesC('macos')) {
38+
console.log('[Hermes] Using pre-built HermesC');
39+
configureMakeForPrebuiltHermesC();
40+
}
3141
}
42+
43+
main().then(() => {
44+
process.exit(0);
45+
});

scripts/react_native_pods.rb

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,8 @@ def use_react_native! (options={})
107107
if hermes_enabled
108108
pod 'React-hermes', :path => "#{prefix}/ReactCommon/hermes"
109109
pod 'libevent', '~> 2.1.12'
110-
111-
sdks_dir = Pod::Config.instance.installation_root.join(prefix, "sdks")
112-
hermes_tag_file = sdks_dir.join(".hermesversion")
113-
114-
if (File.exist?(hermes_tag_file))
115-
# Use published pod with pre-builts.
116-
Pod::UI.puts "[Hermes] Tag file exists at path: #{hermes_tag_file}"
117-
package = JSON.parse(File.read(File.join(__dir__, "..", "package.json")))
118-
hermes_version = package['version']
119-
Pod::UI.puts "[Hermes] Loading version: #{hermes_version}"
120-
pod 'hermes-engine', hermes_version
121-
else
122-
# Use local podspec and build from source.
123-
path_to_hermes = "#{prefix}/sdks/hermes/hermes-engine.podspec"
124-
Pod::UI.puts "[Hermes] Use local version from #{path_to_hermes}"
125-
system("(cd #{prefix} && node scripts/hermes/prepare-hermes-for-build)")
126-
pod 'hermes-engine', :path => path_to_hermes
127-
end
128-
110+
system("(cd #{prefix} && node scripts/hermes/prepare-hermes-for-build)")
111+
pod 'hermes-engine', :path => "#{prefix}/sdks/hermes/hermes-engine.podspec"
129112
end
130113

131114
if flipper_configuration.flipper_enabled && !production

sdks/hermes-engine/hermes-engine.podspec

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
require "json"
77

8-
# sdks/.hermesversion
9-
hermes_tag_file = File.join(__dir__, "..", ".hermesversion")
10-
118
# sdks/hermesc/osx-bin/ImportHermesc.cmake
129
import_hermesc_file=File.join(__dir__, "..", "hermesc", "osx-bin", "ImportHermesc.cmake")
1310

@@ -18,37 +15,27 @@ version = package['version']
1815

1916
source = {}
2017
git = "https://github.com/facebook/hermes.git"
21-
building_from_source = false
2218

23-
if ENV['hermes-artifact-url'] then
24-
source[:http] = ENV['hermes-artifact-url']
25-
elsif File.exist?(hermes_tag_file) then
26-
building_from_source = true
19+
if version == '1000.0.0'
20+
Pod::UI.puts '[Hermes] Hermes needs to be compiled, installing hermes-engine may take a while...'.yellow if Object.const_defined?("Pod::UI")
2721
source[:git] = git
28-
source[:tag] = File.read(hermes_tag_file)
22+
source[:commit] = `git ls-remote https://github.com/facebook/hermes main | cut -f 1`.strip
2923
else
30-
building_from_source = true
31-
source[:git] = git
32-
hermes_commit_sha = `git ls-remote https://github.com/facebook/hermes main | cut -f 1`.strip
33-
source[:commit] = hermes_commit_sha
24+
source[:http] = `https://github.com/facebook/react-native/releases/download/v#{version}/hermes-runtime-darwin-v#{version}.tar.gz`
3425
end
3526

3627
module HermesHelper
3728
# BUILD_TYPE = :debug
3829
BUILD_TYPE = :release
3930
end
4031

41-
if building_from_source
42-
Pod::UI.puts '[Hermes] Hermes needs to be compiled, installing hermes-engine may take a while...'.yellow if Object.const_defined?("Pod::UI")
43-
end
44-
4532
Pod::Spec.new do |spec|
4633
spec.name = "hermes-engine"
4734
spec.version = version
4835
spec.summary = "Hermes is a small and lightweight JavaScript engine optimized for running React Native."
4936
spec.description = "Hermes is a JavaScript engine optimized for fast start-up of React Native apps. It features ahead-of-time static optimization and compact bytecode."
5037
spec.homepage = "https://hermesengine.dev"
51-
spec.license = { type: "MIT", file: "LICENSE" }
38+
spec.license = package["license"]
5239
spec.author = "Facebook"
5340
spec.source = source
5441
spec.platforms = { :osx => "10.13", :ios => "11.0" }
@@ -62,7 +49,7 @@ Pod::Spec.new do |spec|
6249

6350
spec.xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", "CLANG_CXX_LIBRARY" => "compiler-default", "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" }
6451

65-
unless ENV['hermes-artifact-url']
52+
if source[:git] then
6653
spec.prepare_command = <<-EOS
6754
# When true, debug build will be used.
6855
# See `build-apple-framework.sh` for details

0 commit comments

Comments
 (0)