Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
20 changes: 16 additions & 4 deletions .ado/build-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ extends:
${{ if eq(parameters.MustPublish, false) }}:
skipBuildTagsForGitHubPullRequests: true
pool:
name: Azure-Pipelines-1ESPT-ExDShared
image: windows-latest
os: windows
name: fabric-internal-pool-large
sdl:
binskim:
analyzeTarget: |
Expand Down Expand Up @@ -186,7 +184,7 @@ extends:
$(fakeBuildArg)
displayName: Run unit tests

# Run JS regression tests after the build is finished.
# Run Lit tests which are mostly JS tests.
- script: >
node .ado\scripts\build.js
--no-build
Expand All @@ -200,6 +198,20 @@ extends:
$(fakeBuildArg)
displayName: Run JS regression tests

# Run Test262 Intl tests.
- script: >
node .ado\scripts\build.js
--no-build
--test262-intl
--output-path $(Build.StagingDirectory)\out
--platform ${{ MatrixEntry.TargetCPU }}
--configuration release
${{ MatrixEntry.BuildUWP }}
--semantic-version "$(semanticVersion)"
--file-version "$(fileVersion)"
$(fakeBuildArg)
displayName: Run Test262 Intl tests

# Sign and publish symbols only for the CI builds and real builds.
- ${{ if and(eq(parameters.MustPublish, true), eq(parameters.FakeBuild, false)) }}:
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5
Expand Down
8 changes: 8 additions & 0 deletions .ado/nuget/Microsoft.JavaScript.Hermes.targets
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,13 @@
<ItemGroup Condition="'$(HermesNoDLLCopy)' == ''">
<ReferenceCopyLocalPaths Include="$(PackageRoot)build\native\$(HermesAppPlatform)\$(HermesPlatform)\hermes.dll" />
<None Include="$(PackageRoot)build\native\$(HermesAppPlatform)\$(HermesPlatform)\hermes.dll" CopyToOutputDirectory="PreserveNewest" />
<!-- Bundled ICU library (optional - may not exist if built without bundled ICU) -->
<ReferenceCopyLocalPaths
Include="$(PackageRoot)build\native\$(HermesAppPlatform)\$(HermesPlatform)\hermes-icu.dll"
Condition="Exists('$(PackageRoot)build\native\$(HermesAppPlatform)\$(HermesPlatform)\hermes-icu.dll')" />
<None
Include="$(PackageRoot)build\native\$(HermesAppPlatform)\$(HermesPlatform)\hermes-icu.dll"
CopyToOutputDirectory="PreserveNewest"
Condition="Exists('$(PackageRoot)build\native\$(HermesAppPlatform)\$(HermesPlatform)\hermes-icu.dll')" />
</ItemGroup>
</Project>
35 changes: 35 additions & 0 deletions .ado/nuget/NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,38 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

----------------------------------------------------------------

ICU - International Components for Unicode

UNICODE LICENSE V3

COPYRIGHT AND PERMISSION NOTICE

Copyright (c) 2016-2025 Unicode, Inc.

Permission is hereby granted, free of charge, to any person obtaining a
copy of data files and any associated documentation (the "Data Files") or
software and any associated documentation (the "Software") to deal in the
Data Files or Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, and/or sell
copies of the Data Files or Software, and to permit persons to whom the
Data Files or Software are furnished to do so, provided that either (a)
this copyright and permission notice appear with all copies of the Data
Files or Software, or (b) this copyright and permission notice appear in
associated Documentation.

THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
THIRD PARTY RIGHTS.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
FILES OR SOFTWARE.

SPDX-License-Identifier: Unicode-3.0
173 changes: 173 additions & 0 deletions .ado/scripts/build-hermesc-windows.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#!/usr/bin/env node
const path = require('path');
const fs = require('fs');
const https = require('https');
const {spawnSync} = require('child_process');

const log = (msg) => process.stdout.write(`${msg}\n`);

const REPO_ROOT = path.resolve(__dirname, '..', '..');
const BASE_DIR = process.env.HERMES_WS_DIR || path.join(REPO_ROOT, 'build', 'win_hermesc');
const ICU_URL = process.env.ICU_URL || 'https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip';
const ICU_DIR = path.join(BASE_DIR, 'icu');
const DEPS_DIR = path.join(BASE_DIR, 'deps');
const WIN64_BIN_DIR = path.join(BASE_DIR, 'win64-bin');
const CMAKE_BUILD_DIR = path.join(BASE_DIR, 'build_release');

const PATH_KEY = Object.keys(process.env).find((key) => key.toLowerCase() === 'path') || 'PATH';
const extraPath = [process.env.CMAKE_DIR, process.env.MSBUILD_DIR].filter(Boolean);
if (extraPath.length) {
const currentPath = process.env[PATH_KEY] || '';
const additions = extraPath.join(path.delimiter);
process.env[PATH_KEY] = additions + (currentPath ? `${path.delimiter}${currentPath}` : '');
log(`Extended PATH with: ${additions}`);
}

function ensureDir(dir) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, {recursive: true});
}
}

function ensureWorkspace() {
[BASE_DIR, path.join(BASE_DIR, 'osx-bin'), ICU_DIR, DEPS_DIR, WIN64_BIN_DIR].forEach(ensureDir);
}

function downloadFile(url, dest) {
return new Promise((resolve, reject) => {
if (fs.existsSync(dest)) {
fs.unlinkSync(dest);
}
const file = fs.createWriteStream(dest);
https.get(url, (response) => {
if (response.statusCode && response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
downloadFile(response.headers.location, dest).then(resolve).catch(reject);
return;
}
if (response.statusCode !== 200) {
reject(new Error(`Download failed with status ${response.statusCode}`));
return;
}
response.pipe(file);
file.on('finish', () => {
file.close(resolve);
});
}).on('error', (err) => {
fs.unlink(dest, () => reject(err));
});
});
}

function run(command, args, options = {}) {
log(`> ${command} ${(args || []).join(' ')}`);
const result = spawnSync(command, args, {
stdio: 'inherit',
shell: false,
...options,
});
if (result.error) {
if (result.error.code === 'ENOENT') {
throw new Error(`Command not found: ${command}. Update PATH or set CMAKE_DIR/MSBUILD_DIR.`);
}
throw new Error(`Failed to launch ${command}: ${result.error.message}`);
}
if (result.status !== 0) {
throw new Error(`${command} exited with code ${result.status}`);
}
}

function expandZip(zipPath, destination) {
run('powershell.exe', [
'-NoLogo',
'-NoProfile',
'-Command',
`Expand-Archive -Path '${zipPath}' -DestinationPath '${destination}' -Force`,
]);
}

function copyFile(source, destination) {
ensureDir(path.dirname(destination));
fs.copyFileSync(source, destination);
}

function copyPattern(sourceDir, pattern, destinationDir) {
const regex = new RegExp(pattern.replace(/\*/g, '.*'));
for (const entry of fs.readdirSync(sourceDir)) {
if (regex.test(entry)) {
copyFile(path.join(sourceDir, entry), path.join(destinationDir, entry));
}
}
}

async function fetchIcu() {
log('Downloading ICU');
const zipPath = path.join(ICU_DIR, 'icu.zip');
await downloadFile(ICU_URL, zipPath);
log('Expanding ICU');
expandZip(zipPath, ICU_DIR);
}

function copyRuntimeDependencies() {
copyPattern(path.join(ICU_DIR, 'bin64'), '^icu.*\.dll$', DEPS_DIR);
const system32 = path.join(process.env.windir || 'C:/Windows', 'System32');
['msvcp140.dll', 'vcruntime140.dll', 'vcruntime140_1.dll'].forEach((dll) => {
const source = path.join(system32, dll);
if (!fs.existsSync(source)) {
throw new Error(`Missing runtime dependency: ${source}`);
}
copyFile(source, path.join(DEPS_DIR, dll));
});
}

function ensureCMakeBuild() {
const configureArgs = [
'-S',
'.',
'-B',
CMAKE_BUILD_DIR,
'-G',
'Visual Studio 17 2022',
'-Ax64',
'-DCMAKE_BUILD_TYPE=Release',
'-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True',
];
run('cmake', configureArgs, {
env: {
...process.env,
ICU_ROOT: ICU_DIR,
},
});
run('cmake', ['--build', CMAKE_BUILD_DIR, '--target', 'hermesc', '--config', 'Release'], {
env: {
...process.env,
BOOST_CONTEXT_MASM: 'OFF',
},
});
}

function stageArtifacts() {
const hermescSource = path.join(CMAKE_BUILD_DIR, 'bin', 'Release', 'hermesc.exe');
if (!fs.existsSync(hermescSource)) {
throw new Error(`Build output missing: ${hermescSource}`);
}
copyFile(hermescSource, path.join(WIN64_BIN_DIR, 'hermesc.exe'));
for (const entry of fs.readdirSync(DEPS_DIR)) {
copyFile(path.join(DEPS_DIR, entry), path.join(WIN64_BIN_DIR, entry));
}
}

async function main() {
try {
ensureWorkspace();
await fetchIcu();
copyRuntimeDependencies();
ensureCMakeBuild();
stageArtifacts();
log('HermesC build artifacts staged to win64-bin');
} catch (error) {
log(`Build failed: ${error.message}`);
process.exitCode = 1;
}
}

main();
Loading