Changeset View
Changeset View
Standalone View
Standalone View
arcanist/workflow/ArcanistBuildWorkflow.php
- This file was added.
<?php | |||||
/** | |||||
* Build the project | |||||
*/ | |||||
final class ArcanistBuildWorkflow extends ArcanistWorkflow { | |||||
const DEFAULT_BUILD_DIR = 'buildcmake'; | |||||
const RESULT_OKAY = 0; | |||||
const RESULT_WARNINGS = 1; | |||||
const RESULT_ERRORS = 2; | |||||
const RESULT_SKIP = 3; | |||||
public function getWorkflowName() { | |||||
return 'build'; | |||||
} | |||||
public function getCommandSynopses() { | |||||
return phutil_console_format(<<<EOTEXT | |||||
**build** [__options__] [__targets__] | |||||
EOTEXT | |||||
); | |||||
} | |||||
public function getCommandHelp() { | |||||
return phutil_console_format(<<<EOTEXT | |||||
Build the bitcoin-abc project using CMake and Ninja. | |||||
You can specify the Ninja targets by passing them to __targets__. | |||||
Requires: cmake, ninja | |||||
EOTEXT | |||||
); | |||||
} | |||||
public function getArguments() { | |||||
return array( | |||||
'clear-cache' => array( | |||||
'help' => pht('Clear the CMake cache before running the build.'), | |||||
), | |||||
'dir' => array( | |||||
'param' => 'build directory', | |||||
'help' => pht('Set the build directory. It will be created if it does '. | |||||
'not exist. Default: '.self::DEFAULT_BUILD_DIR), | |||||
), | |||||
'post-clean' => array( | |||||
'help' => pht('Delete all files and the build directory if the build '. | |||||
'is successful.'), | |||||
), | |||||
'*' => 'targets', | |||||
); | |||||
} | |||||
public function requiresWorkingCopy() { | |||||
return true; | |||||
} | |||||
private function setSuccess($duration) { | |||||
$out = phutil_console_format( | |||||
"**<bg:green> %s </bg>** %s (%.3f s)\n", | |||||
pht('OKAY'), | |||||
pht('Build is successful'), | |||||
$duration); | |||||
PhutilConsole::getConsole()->writeOut($out); | |||||
return self::RESULT_OKAY; | |||||
} | |||||
private function setFailure($failureReason) { | |||||
$out = phutil_console_format( | |||||
"**<bg:red> %s </bg>** %s\n", | |||||
pht('FAILED'), | |||||
pht($failureReason)); | |||||
PhutilConsole::getConsole()->writeOut($out); | |||||
return self::RESULT_ERRORS; | |||||
} | |||||
public function run() { | |||||
$root = $this->getWorkingCopy()->getProjectRoot(); | |||||
/* Create the build directory if it doesn't exist */ | |||||
$buildDir = $this->getArgument('dir', self::DEFAULT_BUILD_DIR); | |||||
$buildDir = Filesystem::resolvePath($buildDir, $root); | |||||
try { | |||||
$buildDir = Filesystem::createDirectory($buildDir); | |||||
} catch (FilesystemException $e) { | |||||
return $this->setFailure( | |||||
'Unable to create the build directory: '.$buildDir.'. '. | |||||
'Check the permissions and run `arc build` again.'); | |||||
} | |||||
/* Clear the CMake cache if requested */ | |||||
if ($this->getArgument('clear-cache')) { | |||||
/* Delete the CMakeCache.txt file */ | |||||
$cacheFile = Filesystem::resolvePath('CMakeCache.txt', $buildDir); | |||||
if (file_exists($cacheFile)) { | |||||
try { | |||||
Filesystem::remove($cacheFile); | |||||
} catch (FilesystemException $e) { | |||||
return $this->setFailure( | |||||
'Unable to remove the '.$buildDir.'/CMakeCache.txt file. '. | |||||
'Check the permissions and run `arc build` again.'); | |||||
} | |||||
} | |||||
} | |||||
$timeStart = microtime(true); | |||||
/* Run CMake from the build repository */ | |||||
$future = new ExecFuture('cmake -GNinja ..'); | |||||
$future->setCWD($buildDir); | |||||
list($ret) = $future->resolve(); | |||||
if ($ret != 0) { | |||||
return $this->setFailure( | |||||
'CMake failed with error '.strval($ret)); | |||||
} | |||||
/* | |||||
* Run Ninja from the build directory. | |||||
* If "targets" arguments are specified, pass them to Ninja, otherwise do | |||||
* not speficy any target and let Ninja build the default. | |||||
*/ | |||||
$targets = $this->getArgument('targets'); | |||||
$cmd = 'ninja'; | |||||
foreach ($targets as $_) { | |||||
$cmd .= ' %s'; | |||||
} | |||||
$future = new ExecFuture($cmd, ...$targets); | |||||
$future->setCWD($buildDir); | |||||
list($ret) = $future->resolve(); | |||||
$timeEnd = microtime(true); | |||||
if ($ret != 0) { | |||||
return $this->setFailure( | |||||
'Ninja failed with error '.strval($ret)); | |||||
} | |||||
/* Remove the build directory if requested. */ | |||||
if ($this->getArgument('post-clean')) { | |||||
try { | |||||
Filesystem::remove($buildDir); | |||||
} catch (FilesystemException $e) { | |||||
return $this->setFailure( | |||||
'Unable to delete the build directory: '.$buildDir.'. '. | |||||
'Check the permissions and run `arc build --clean` again.'); | |||||
} | |||||
} | |||||
return $this->setSuccess($timeEnd - $timeStart); | |||||
} | |||||
} |