Skip to content

Commit bbf0c4e

Browse files
committed
feat(build): add automated build tools installation
- Add installBuildTools() function for ninja and mold installation - Support Homebrew (macOS), apt-get/yum (Linux), choco/winget (Windows) - Auto-detect missing tools and install after platform setup - Add mold linker check to build tools verification
1 parent c57faba commit bbf0c4e

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

scripts/setup-build-toolchain.mjs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,7 @@ function checkBuildTools() {
762762
const tools = {
763763
cmake: 'CMake',
764764
ninja: 'Ninja',
765+
mold: 'Mold Linker',
765766
make: 'Make',
766767
git: 'Git',
767768
}
@@ -781,6 +782,117 @@ function checkBuildTools() {
781782
return results
782783
}
783784

785+
/**
786+
* Install build tools (ninja and mold).
787+
*/
788+
async function installBuildTools() {
789+
if (CHECK_ONLY) {
790+
logInfo('Skipping build tools installation (check-only mode)')
791+
return false
792+
}
793+
794+
logInfo('Installing build tools (ninja, mold)...')
795+
796+
try {
797+
if (PLATFORM === 'darwin') {
798+
if (!commandExists('brew')) {
799+
logError('Homebrew not found. Install from: https://brew.sh/')
800+
return false
801+
}
802+
803+
// Install ninja.
804+
if (!commandExists('ninja')) {
805+
logInfo('Installing ninja...')
806+
if (!exec('brew install ninja')) {
807+
logWarn('Failed to install ninja via brew')
808+
}
809+
}
810+
811+
// Install mold (not available on macOS via brew, use lld instead).
812+
if (!commandExists('mold') && !commandExists('ld64.lld')) {
813+
logInfo('Installing llvm (includes lld linker)...')
814+
if (!exec('brew install llvm')) {
815+
logWarn('Failed to install llvm via brew')
816+
}
817+
}
818+
819+
return true
820+
}
821+
822+
if (PLATFORM === 'linux') {
823+
// Try apt-get first.
824+
if (commandExists('apt-get')) {
825+
const packages = []
826+
if (!commandExists('ninja')) {
827+
packages.push('ninja-build')
828+
}
829+
if (!commandExists('mold')) {
830+
packages.push('mold')
831+
}
832+
833+
if (packages.length) {
834+
logInfo(`Installing ${packages.join(', ')}...`)
835+
return (
836+
exec('sudo apt-get update') &&
837+
exec(`sudo apt-get install -y ${packages.join(' ')}`)
838+
)
839+
}
840+
return true
841+
}
842+
843+
// Try yum.
844+
if (commandExists('yum')) {
845+
const packages = []
846+
if (!commandExists('ninja')) {
847+
packages.push('ninja-build')
848+
}
849+
// mold not available in default yum repos, user needs to build from source.
850+
851+
if (packages.length) {
852+
logInfo(`Installing ${packages.join(', ')}...`)
853+
return exec(`sudo yum install -y ${packages.join(' ')}`)
854+
}
855+
return true
856+
}
857+
858+
logError('No supported package manager found')
859+
return false
860+
}
861+
862+
if (PLATFORM === 'win32') {
863+
if (commandExists('choco')) {
864+
if (!commandExists('ninja')) {
865+
logInfo('Installing ninja...')
866+
if (!exec('choco install -y ninja')) {
867+
logWarn('Failed to install ninja via choco')
868+
}
869+
}
870+
// mold not available on Windows, will use MSVC linker.
871+
return true
872+
}
873+
874+
if (commandExists('winget')) {
875+
if (!commandExists('ninja')) {
876+
logInfo('Installing ninja...')
877+
if (!exec('winget install Ninja-build.ninja')) {
878+
logWarn('Failed to install ninja via winget')
879+
}
880+
}
881+
return true
882+
}
883+
884+
logError('No supported package manager found')
885+
return false
886+
}
887+
888+
logError(`Unsupported platform: ${PLATFORM}`)
889+
return false
890+
} catch (error) {
891+
logError(`Failed to install build tools: ${error.message}`)
892+
return false
893+
}
894+
}
895+
784896
/**
785897
* Create environment activation script.
786898
*/
@@ -923,6 +1035,13 @@ async function main() {
9231035
log('')
9241036
}
9251037

1038+
// Install build tools (ninja, mold) after platform installers are ready.
1039+
const buildToolsCheck = checkBuildTools()
1040+
if (!buildToolsCheck.ninja || !buildToolsCheck.mold) {
1041+
await installBuildTools()
1042+
log('')
1043+
}
1044+
9261045
// Create activation script.
9271046
await createActivationScript()
9281047

0 commit comments

Comments
 (0)